From 72077d64a2815a1fd9f0db6785a4e0a168027c4c Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Tue, 7 May 2024 22:37:16 +1000 Subject: [PATCH 1/2] refactor: reconfigure cobbler to module style - split params into class - split class into individual functions --- hieradata/roles/infra/cobbler/server.eyaml | 2 +- hieradata/roles/infra/cobbler/server.yaml | 2 +- site/profiles/manifests/cobbler/config.pp | 75 ++++++++++++ site/profiles/manifests/cobbler/init.pp | 17 +++ site/profiles/manifests/cobbler/install.pp | 9 ++ site/profiles/manifests/cobbler/ipxebins.pp | 2 + site/profiles/manifests/cobbler/params.pp | 24 ++++ site/profiles/manifests/cobbler/selinux.pp | 37 ++++++ site/profiles/manifests/cobbler/server.pp | 119 ------------------- site/profiles/manifests/cobbler/service.pp | 17 +++ site/roles/manifests/infra/cobbler/server.pp | 2 +- 11 files changed, 184 insertions(+), 122 deletions(-) create mode 100644 site/profiles/manifests/cobbler/config.pp create mode 100644 site/profiles/manifests/cobbler/init.pp create mode 100644 site/profiles/manifests/cobbler/install.pp create mode 100644 site/profiles/manifests/cobbler/params.pp create mode 100644 site/profiles/manifests/cobbler/selinux.pp delete mode 100644 site/profiles/manifests/cobbler/server.pp create mode 100644 site/profiles/manifests/cobbler/service.pp diff --git a/hieradata/roles/infra/cobbler/server.eyaml b/hieradata/roles/infra/cobbler/server.eyaml index 9f6f432..6ccffe3 100644 --- a/hieradata/roles/infra/cobbler/server.eyaml +++ b/hieradata/roles/infra/cobbler/server.eyaml @@ -1,2 +1,2 @@ --- -profiles::cobbler::server::default_password_crypted: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAJidO18dSzKXgDEvFhigrDmiMTW+D7obTCZVAvl0JzQ6nqRdnh6Xa+j+yc7YzYtCg9VH60vfcutHFGhJptlMbTQq3vSUoF9ylgTutaW/to4T8jb8gBqK1n7b+devEQh4soJtOdAPSidCX4aqsP9dK3I8IijNWMABz59usGbY6oWedmC4865PBcxyIu3phWynNULTXPBEAqdXAutkh4N3P1ydFk3eARCVS3uWo7zaXVsu4vIkjYRDCUyFXBWb12L/NmQ2EhGwckPwgX/rcKRL9r49GxQTLBHJ5MoHQanwoiRw+5Tz3qLW69z+hk91VpnpkZgANc081rmhdyp6qmuIAVDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBiDUwXVJ6mmwzt4YAxg3+qgDDWm5mlWEgsZqCHwG0n94v7oqCBqY2WQdTJAM3TtKlX2nOPlLEmfLrwqtsS2r3QzLo=] +profiles::cobbler::params::default_password_crypted: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAJidO18dSzKXgDEvFhigrDmiMTW+D7obTCZVAvl0JzQ6nqRdnh6Xa+j+yc7YzYtCg9VH60vfcutHFGhJptlMbTQq3vSUoF9ylgTutaW/to4T8jb8gBqK1n7b+devEQh4soJtOdAPSidCX4aqsP9dK3I8IijNWMABz59usGbY6oWedmC4865PBcxyIu3phWynNULTXPBEAqdXAutkh4N3P1ydFk3eARCVS3uWo7zaXVsu4vIkjYRDCUyFXBWb12L/NmQ2EhGwckPwgX/rcKRL9r49GxQTLBHJ5MoHQanwoiRw+5Tz3qLW69z+hk91VpnpkZgANc081rmhdyp6qmuIAVDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBiDUwXVJ6mmwzt4YAxg3+qgDDWm5mlWEgsZqCHwG0n94v7oqCBqY2WQdTJAM3TtKlX2nOPlLEmfLrwqtsS2r3QzLo=] diff --git a/hieradata/roles/infra/cobbler/server.yaml b/hieradata/roles/infra/cobbler/server.yaml index 4aaea83..9fac228 100644 --- a/hieradata/roles/infra/cobbler/server.yaml +++ b/hieradata/roles/infra/cobbler/server.yaml @@ -14,4 +14,4 @@ profiles::packages::install: profiles::pki::vault::alt_names: - cobbler.main.unkin.net -profiles::cobbler::server::service_cname: 'cobbler.main.unkin.net' +profiles::cobbler::params::service_cname: 'cobbler.main.unkin.net' diff --git a/site/profiles/manifests/cobbler/config.pp b/site/profiles/manifests/cobbler/config.pp new file mode 100644 index 0000000..9b5c2af --- /dev/null +++ b/site/profiles/manifests/cobbler/config.pp @@ -0,0 +1,75 @@ +# profiles::cobbler::config +class profiles::cobbler::config { + + include profiles::cobbler::params + + $default_password_crypted = $profiles::cobbler::params::default_password_crypted + $httpd_ssl_certificate = $profiles::cobbler::params::httpd_ssl_certificate + $httpd_ssl_privatekey = $profiles::cobbler::params::httpd_ssl_privatekey + $pxe_just_once = $profiles::cobbler::params::pxe_just_once + $service_cname = $profiles::cobbler::params::service_cname + $next_server = $profiles::cobbler::params::next_server + $server = $profiles::cobbler::params::server + + # manage the cobbler settings file + file { '/etc/cobbler/settings.yaml': + ensure => 'file', + content => template('profiles/cobbler/settings.yaml.erb'), + group => 'apache', + owner => 'root', + mode => '0640', + require => Package['cobbler'], + notify => Service['cobblerd'], + } + + # manage the debmirror config to meet cobbler requirements + file { '/etc/debmirror.conf': + ensure => 'file', + content => template('profiles/cobbler/debmirror.conf.erb'), + group => 'root', + owner => 'root', + mode => '0644', + require => Package['debmirror'], + } + + # manage the httpd ssl configuration + file { '/etc/httpd/conf.d/ssl.conf': + ensure => 'file', + content => template('profiles/cobbler/httpd_ssl.conf.erb'), + group => 'root', + owner => 'root', + mode => '0644', + require => Package['httpd'], + notify => Service['httpd'], + } + + # fix permissions in /var/lib/cobbler/web.ss + file {'/var/lib/cobbler/web.ss': + ensure => 'file', + group => 'root', + owner => 'apache', + mode => '0660', + require => Package['cobbler'], + notify => Service['cobblerd'], + } + + # manage the main ipxe menu script + file { '/var/lib/tftpboot/main.ipxe': + ensure => 'file', + content => template('profiles/cobbler/main.ipxe.erb'), + owner => 'root', + group => 'root', + mode => '0644', + require => Package['cobbler'], + } + + # export cnames for cobbler + #profiles::dns::record { "${::facts['networking']['fqdn']}_${service_cname}_CNAME": + # value => $::facts['networking']['hostname'], + # type => 'CNAME', + # record => "${service_cname}.", + # zone => $::facts['networking']['domain'], + # order => 10, + #} + +} diff --git a/site/profiles/manifests/cobbler/init.pp b/site/profiles/manifests/cobbler/init.pp new file mode 100644 index 0000000..24b1555 --- /dev/null +++ b/site/profiles/manifests/cobbler/init.pp @@ -0,0 +1,17 @@ +# profiles::cobbler::init +class profiles::cobbler::init ( +) { + # wait for enc_role to be populated, needed for hieradata to match + if $facts['enc_role'] == 'roles::infra::cobbler::server' { + include profiles::cobbler::config + include profiles::cobbler::install + include profiles::cobbler::ipxebins + include profiles::cobbler::selinux + include profiles::cobbler::service + + Class['profiles::cobbler::install'] + -> Class['profiles::cobbler::config'] + -> Class['profiles::cobbler::ipxebins'] + -> Class['profiles::cobbler::selinux'] + } +} diff --git a/site/profiles/manifests/cobbler/install.pp b/site/profiles/manifests/cobbler/install.pp new file mode 100644 index 0000000..df41ed6 --- /dev/null +++ b/site/profiles/manifests/cobbler/install.pp @@ -0,0 +1,9 @@ +# profiles::cobbler::install +class profiles::cobbler::install { + + include profiles::cobbler::params + + $packages = $profiles::cobbler::params::packages + + ensure_packages($packages, { ensure => 'present' }) +} diff --git a/site/profiles/manifests/cobbler/ipxebins.pp b/site/profiles/manifests/cobbler/ipxebins.pp index 125c353..1fc0bf9 100644 --- a/site/profiles/manifests/cobbler/ipxebins.pp +++ b/site/profiles/manifests/cobbler/ipxebins.pp @@ -1,6 +1,8 @@ # profiles::cobbler::ipxebins class profiles::cobbler::ipxebins { + include profiles::cobbler::params + # download the custom undionly.kpxe file # https://gist.github.com/rikka0w0/50895b82cbec8a3a1e8c7707479824c1 exec { 'download_undionly_kpxe': diff --git a/site/profiles/manifests/cobbler/params.pp b/site/profiles/manifests/cobbler/params.pp new file mode 100644 index 0000000..ca5ddfd --- /dev/null +++ b/site/profiles/manifests/cobbler/params.pp @@ -0,0 +1,24 @@ +# profiles::cobbler::params +class profiles::cobbler::params ( + Stdlib::Absolutepath $httpd_ssl_certificate = '/etc/pki/tls/vault/certificate.crt', + Stdlib::Absolutepath $httpd_ssl_privatekey = '/etc/pki/tls/vault/private.key', + Stdlib::Absolutepath $tftpboot_path = '/var/lib/tftpboot/boot', + Stdlib::Fqdn $service_cname = $facts['networking']['fqdn'], + String $default_password_crypted = 'changeme', + String $server = $::facts['networking']['ip'], + String $next_server = $::facts['networking']['ip'], + Boolean $pxe_just_once = true, + Array $packages = [ + 'cobbler', + 'cobbler3.2-web', + 'httpd', + 'syslinux', + 'dnf-plugins-core', + 'debmirror', + 'pykickstart', + 'fence-agents', + 'selinux-policy-devel', + 'ipxe-bootimgs', + ] +){ +} diff --git a/site/profiles/manifests/cobbler/selinux.pp b/site/profiles/manifests/cobbler/selinux.pp new file mode 100644 index 0000000..a8b0d61 --- /dev/null +++ b/site/profiles/manifests/cobbler/selinux.pp @@ -0,0 +1,37 @@ +# profiles::cobbler::selinux +class profiles::cobbler::selinux inherits profiles::cobbler::params { + + include profiles::cobbler::params + + $tftpboot_path = $profiles::cobbler::params::tftpboot_path + + # manage selinux requirements for cobbler + if $::facts['os']['selinux']['config_mode'] == 'enforcing' { + + $enable_sebooleans = [ + 'httpd_can_network_connect_cobbler', + 'httpd_serve_cobbler_files', + 'cobbler_can_network_connect' + ] + + $enable_sebooleans.each |$bool| { + selboolean { $bool: + value => on, + persistent => true, + } + } + + selinux::fcontext { $tftpboot_path: + ensure => 'present', + seltype => 'cobbler_var_lib_t', + pathspec => "${tftpboot_path}(/.*)?", + } + + exec { "restorecon_${tftpboot_path}": + path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'], + command => "restorecon -Rv ${tftpboot_path}", + refreshonly => true, + subscribe => Selinux::Fcontext[$tftpboot_path], + } + } +} diff --git a/site/profiles/manifests/cobbler/server.pp b/site/profiles/manifests/cobbler/server.pp deleted file mode 100644 index 3dba1dc..0000000 --- a/site/profiles/manifests/cobbler/server.pp +++ /dev/null @@ -1,119 +0,0 @@ -# profiles::cobbler::server -class profiles::cobbler::server ( - Stdlib::Fqdn $service_cname, - String $default_password_crypted, - Stdlib::Absolutepath $httpd_ssl_certificate = '/etc/pki/tls/vault/certificate.crt', - Stdlib::Absolutepath $httpd_ssl_privatekey = '/etc/pki/tls/vault/private.key', - Stdlib::Absolutepath $tftpboot_path = '/var/lib/tftpboot/boot', - String $server = $::facts['networking']['ip'], - String $next_server = $::facts['networking']['ip'], - Boolean $pxe_just_once = true, -) { - - include profiles::cobbler::ipxebins - - # manage the cobbler settings file - file { '/etc/cobbler/settings.yaml': - ensure => 'file', - content => template('profiles/cobbler/settings.yaml.erb'), - group => 'apache', - owner => 'root', - mode => '0640', - require => Package['cobbler'], - notify => Service['cobblerd'], - } - - # fix permissions in /var/lib/cobbler/web.ss - file {'/var/lib/cobbler/web.ss': - ensure => 'file', - group => 'root', - owner => 'apache', - mode => '0660', - require => Package['cobbler'], - notify => Service['cobblerd'], - } - - # manage the debmirror config to meet cobbler requirements - file { '/etc/debmirror.conf': - ensure => 'file', - content => template('profiles/cobbler/debmirror.conf.erb'), - group => 'root', - owner => 'root', - mode => '0644', - require => Package['debmirror'], - } - - # manage the httpd ssl configuration - file { '/etc/httpd/conf.d/ssl.conf': - ensure => 'file', - content => template('profiles/cobbler/httpd_ssl.conf.erb'), - group => 'root', - owner => 'root', - mode => '0644', - require => Package['httpd'], - notify => Service['httpd'], - } - - # manage the main ipxe menu script - file { '/var/lib/tftpboot/main.ipxe': - ensure => 'file', - content => template('profiles/cobbler/main.ipxe.erb'), - owner => 'root', - group => 'root', - mode => '0644', - require => Package['cobbler'], - } - - # ensure cobblerd is running - service {'cobblerd': - ensure => 'running', - enable => true, - require => File['/etc/cobbler/settings.yaml'], - } - - # ensure httpd is running - service {'httpd': - ensure => 'running', - enable => true, - require => File['/etc/httpd/conf.d/ssl.conf'], - } - - # export cnames for cobbler - profiles::dns::record { "${::facts['networking']['fqdn']}_${service_cname}_CNAME": - value => $::facts['networking']['hostname'], - type => 'CNAME', - record => "${service_cname}.", - zone => $::facts['networking']['domain'], - order => 10, - } - - # manage selinux requirements for cobbler - if $::facts['os']['selinux']['config_mode'] == 'enforcing' { - - $enable_sebooleans = [ - 'httpd_can_network_connect_cobbler', - 'httpd_serve_cobbler_files', - 'cobbler_can_network_connect' - ] - - $enable_sebooleans.each |$bool| { - selboolean { $bool: - value => on, - persistent => true, - } - } - - selinux::fcontext { $tftpboot_path: - ensure => 'present', - seltype => 'cobbler_var_lib_t', - pathspec => "${tftpboot_path}(/.*)?", - } - - exec { "restorecon_${tftpboot_path}": - path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'], - command => "restorecon -Rv ${tftpboot_path}", - refreshonly => true, - subscribe => Selinux::Fcontext[$tftpboot_path], - } - } -} diff --git a/site/profiles/manifests/cobbler/service.pp b/site/profiles/manifests/cobbler/service.pp new file mode 100644 index 0000000..63b2645 --- /dev/null +++ b/site/profiles/manifests/cobbler/service.pp @@ -0,0 +1,17 @@ +# profiles::cobbler::service +class profiles::cobbler::service inherits profiles::cobbler::params { + + # ensure cobblerd is running + service {'cobblerd': + ensure => 'running', + enable => true, + require => File['/etc/cobbler/settings.yaml'], + } + + # ensure httpd is running + service {'httpd': + ensure => 'running', + enable => true, + require => File['/etc/httpd/conf.d/ssl.conf'], + } +} diff --git a/site/roles/manifests/infra/cobbler/server.pp b/site/roles/manifests/infra/cobbler/server.pp index 65d8541..0c515d3 100644 --- a/site/roles/manifests/infra/cobbler/server.pp +++ b/site/roles/manifests/infra/cobbler/server.pp @@ -3,5 +3,5 @@ class roles::infra::cobbler::server { include profiles::defaults include profiles::base include profiles::base::datavol - include profiles::cobbler::server + include profiles::cobbler::init } From fee0bde60401bd670f6eb274cb9f553f79a8e971 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Thu, 9 May 2024 19:47:01 +1000 Subject: [PATCH 2/2] feat: complete cobbler automation - add facts to manage the /var/www/cobbler and /data/cobbler directories - move /var/www/cobbler -> /data/cobbler - create symlink from /var/www/cobbler -> /data/cobbler - ensure that cobbler nodes are set to permissive selinux mode --- hieradata/common.yaml | 1 + hieradata/roles/infra/cobbler/server.yaml | 1 + .../lib/facter/cobbler_data_dir_exists.rb | 8 ++++++ .../libs/lib/facter/cobbler_var_www_exists.rb | 8 ++++++ .../libs/lib/facter/cobbler_var_www_islink.rb | 8 ++++++ site/profiles/manifests/cobbler/install.pp | 25 +++++++++++++++++++ site/profiles/manifests/cobbler/selinux.pp | 11 ++++++++ 7 files changed, 62 insertions(+) create mode 100644 modules/libs/lib/facter/cobbler_data_dir_exists.rb create mode 100644 modules/libs/lib/facter/cobbler_var_www_exists.rb create mode 100644 modules/libs/lib/facter/cobbler_var_www_islink.rb diff --git a/hieradata/common.yaml b/hieradata/common.yaml index cc16e0e..80e79a1 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -98,6 +98,7 @@ facts_path: '/opt/puppetlabs/facter/facts.d' hiera_classes: - timezone + - profiles::selinux::setenforce profiles::ntp::client::ntp_role: 'roles::infra::ntp::server' profiles::ntp::client::use_ntp: 'region' diff --git a/hieradata/roles/infra/cobbler/server.yaml b/hieradata/roles/infra/cobbler/server.yaml index 9fac228..98511cb 100644 --- a/hieradata/roles/infra/cobbler/server.yaml +++ b/hieradata/roles/infra/cobbler/server.yaml @@ -15,3 +15,4 @@ profiles::pki::vault::alt_names: - cobbler.main.unkin.net profiles::cobbler::params::service_cname: 'cobbler.main.unkin.net' +profiles::selinux::setenforce::mode: permissive diff --git a/modules/libs/lib/facter/cobbler_data_dir_exists.rb b/modules/libs/lib/facter/cobbler_data_dir_exists.rb new file mode 100644 index 0000000..d716b35 --- /dev/null +++ b/modules/libs/lib/facter/cobbler_data_dir_exists.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +Facter.add('cobbler_data_dir_exists') do + confine enc_role: 'roles::infra::cobbler::server' + setcode do + File.exist?('/data/cobbler') + end +end diff --git a/modules/libs/lib/facter/cobbler_var_www_exists.rb b/modules/libs/lib/facter/cobbler_var_www_exists.rb new file mode 100644 index 0000000..aa445b8 --- /dev/null +++ b/modules/libs/lib/facter/cobbler_var_www_exists.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +Facter.add('cobbler_var_www_exists') do + confine enc_role: 'roles::infra::cobbler::server' + setcode do + File.exist?('/var/www/cobbler') + end +end diff --git a/modules/libs/lib/facter/cobbler_var_www_islink.rb b/modules/libs/lib/facter/cobbler_var_www_islink.rb new file mode 100644 index 0000000..13d9c6e --- /dev/null +++ b/modules/libs/lib/facter/cobbler_var_www_islink.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +Facter.add('cobbler_var_www_islink') do + confine enc_role: 'roles::infra::cobbler::server' + setcode do + File.exist?('/var/www/cobbler') and File.symlink?('/var/www/cobbler') + end +end diff --git a/site/profiles/manifests/cobbler/install.pp b/site/profiles/manifests/cobbler/install.pp index df41ed6..f6bb8d6 100644 --- a/site/profiles/manifests/cobbler/install.pp +++ b/site/profiles/manifests/cobbler/install.pp @@ -6,4 +6,29 @@ class profiles::cobbler::install { $packages = $profiles::cobbler::params::packages ensure_packages($packages, { ensure => 'present' }) + + # move the /var/www/cobbler directory to /data/cobbler + if ! $facts['cobbler_var_www_islink'] and ! $facts['cobbler_data_exists'] { + exec {'move_cobbler_data': + command => 'mv /var/www/cobbler /data/cobbler', + onlyif => 'test -d /var/www/cobbler', + path => ['/bin', '/usr/bin'], + before => Service['cobblerd'], + } + file { '/var/www/cobbler': + ensure => 'link', + target => '/data/cobbler', + require => Exec['move_cobbler_data'], + before => Service['httpd'], + notify => Service['httpd'], + } + } + if ! $facts['cobbler_var_www_exists'] and $facts['cobbler_data_exists'] { + file { '/var/www/cobbler': + ensure => 'link', + target => '/data/cobbler', + before => Service['httpd'], + notify => Service['httpd'], + } + } } diff --git a/site/profiles/manifests/cobbler/selinux.pp b/site/profiles/manifests/cobbler/selinux.pp index a8b0d61..df8dab5 100644 --- a/site/profiles/manifests/cobbler/selinux.pp +++ b/site/profiles/manifests/cobbler/selinux.pp @@ -26,6 +26,11 @@ class profiles::cobbler::selinux inherits profiles::cobbler::params { seltype => 'cobbler_var_lib_t', pathspec => "${tftpboot_path}(/.*)?", } + selinux::fcontext { '/data/cobbler': + ensure => 'present', + seltype => 'cobbler_var_lib_t', + pathspec => '/data/cobbler(/.*)?', + } exec { "restorecon_${tftpboot_path}": path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'], @@ -33,5 +38,11 @@ class profiles::cobbler::selinux inherits profiles::cobbler::params { refreshonly => true, subscribe => Selinux::Fcontext[$tftpboot_path], } + exec { 'restorecon_/data/cobbler': + path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'], + command => 'restorecon -Rv /data/cobbler', + refreshonly => true, + subscribe => Selinux::Fcontext['/data/cobbler'], + } } }