diff --git a/Puppetfile b/Puppetfile index 5ad891a..1da664c 100644 --- a/Puppetfile +++ b/Puppetfile @@ -8,6 +8,7 @@ mod 'puppetlabs-concat', '9.0.0' mod 'puppetlabs-vcsrepo', '6.1.0' mod 'puppetlabs-yumrepo_core', '2.0.0' mod 'puppetlabs-apt', '9.1.0' +mod 'puppetlabs-lvm', '2.0.3' mod 'puppetlabs-puppetdb', '7.13.0' mod 'puppetlabs-postgresql', '9.1.0' mod 'puppetlabs-firewall', '6.0.0' @@ -20,6 +21,8 @@ mod 'puppet-yum', '7.0.0' mod 'puppet-archive', '7.0.0' mod 'puppet-chrony', '2.6.0' mod 'puppet-puppetboard', '9.0.0' +mod 'puppet-nginx', '5.0.0' +mod 'puppet-selinux', '4.1.0' # other mod 'ghoneycutt-puppet', '3.3.0' diff --git a/hiera.yaml b/hiera.yaml index c601683..d117ebd 100644 --- a/hiera.yaml +++ b/hiera.yaml @@ -5,10 +5,14 @@ defaults: data_hash: "yaml_data" hierarchy: - name: Node-specific data - path: "nodes/%{trusted.certname}.yaml" - - name: "Per-OS & Release Specific Data" - path: "os/%{facts.os.name}/%{facts.os.name}%{facts.os.release.major}.yaml" - - name: "Per-OS Specific Data" - path: "os/%{facts.os.name}/all_releases.yaml" + paths: + - "nodes/%{trusted.certname}.yaml" + - name: Role-specific data + paths: + - "%{facts.enc_role_path}.yaml" + - name: "OS Related" + paths: + - "os/%{facts.os.name}/%{facts.os.name}%{facts.os.release.major}.yaml" + - "os/%{facts.os.name}/all_releases.yaml" - name: Common data shared across nodes path: "common.yaml" diff --git a/hieradata/common.yaml b/hieradata/common.yaml index 1520bd2..b8a2f9d 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -1,9 +1,13 @@ --- -profiles::base::ntp_servers: - - 0.au.pool.ntp.org - - 1.au.pool.ntp.org +profiles::ntp::client::peers: + - ntp01.main.unkin.net + - ntp02.main.unkin.net -profiles::base::packages::common: +profiles::base::puppet_servers: + - 'prodinf01n01.main.unkin.net' + +profiles::packages::base: + - bash-completion - ccze - curl - dstat @@ -11,6 +15,7 @@ profiles::base::packages::common: - mtr - ncdu - neovim + - rsync - screen - strace - tmux @@ -31,19 +36,64 @@ profiles::puppet::autosign::domains: # profiles::puppet::autosign::nodes: # - 'somenode.main.unkin.net' -profiles::puppet::enc::enc_repo: https://git.unkin.net/unkinben/puppet-enc.git +profiles::puppet::client::environment: 'develop' +profiles::puppet::client::runinterval: 1800 +profiles::puppet::client::runtimeout: 3600 +profiles::puppet::client::show_diff: true +profiles::puppet::client::usecacheonfailure: false + +profiles::puppet::enc::repo: https://git.unkin.net/unkinben/puppet-enc.git +profiles::puppet::enc::release: '0.4' +profiles::puppet::enc::force: true profiles::puppet::r10k::r10k_repo: https://git.unkin.net/unkinben/puppet-r10k.git profiles::puppet::g10k::bin_path: '/opt/puppetlabs/bin/g10k' profiles::puppet::g10k::cfg_path: '/etc/puppetlabs/r10k/r10k.yaml' profiles::puppet::g10k::environments_path: '/etc/puppetlabs/code/environments' profiles::puppet::g10k::default_environment: 'develop' profiles::puppet::puppetdb::puppetdb_host: prodinf01n04.main.unkin.net +profiles::puppet::puppetdb::postgres_host: prodinf01n05.main.unkin.net puppetdb::master::config::create_puppet_service_resource: false -puppetdb::master::config::puppetdb_host: "%{lookup('profiles::puppet::puppetdb::puppetdb_host')}" +#puppetdb::master::config::puppetdb_host: "%{lookup('profiles::puppet::puppetdb::puppetdb_host')}" profiles::accounts::sysadmin::sshkeys: - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZ8SRLlPiDylBpdWR9LpvPg4fDVD+DZst4yRPFwMMhta4mnB1H9XuvZkptDhXywWQ7QIcqa2WbhCen0OQJCtwn3s7EYtacmF5MxmwBYocPoK2AArGuh6NA9rwTdLrPdzhZ+gwe88PAzRLNzjm0ZBR+mA9saMbPJdqpKp0AWeAM8QofRQAWuCzQg9i0Pn1KDMvVDRHCZof4pVlHSTyHNektq4ifovn0zhKC8jD/cYu95mc5ftBbORexpGiQWwQ3HZw1IBe0ZETB1qPIPwsoJpt3suvMrL6T2//fcIIUE3TcyJKb/yhztja4TZs5jT8370G/vhlT70He0YPxqHub8ZfBv0khlkY93VBWYpNGJwM1fVqlw7XbfBNdOuJivJac8eW317ZdiDnKkBTxapThpPG3et9ib1HoPGKRsd/fICzNz16h2R3tddSdihTFL+bmTCa6Lo+5t5uRuFjQvhSLSgO2/gRAprc3scYOB4pY/lxOFfq3pU2VvSJtRgLNEYMUYKk= ben@unkin.net +profiles::reposync::repos_list: + almalinux_8_8_baseos: + repository: 'BaseOS' + description: 'AlmaLinux 8.8 - BaseOS' + osname: 'almalinux' + release: '8.8' + baseurl: 'http://mirror.aarnet.edu.au/pub/almalinux/8.8/BaseOS/x86_64/os/' + gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux' + almalinux_8_8_appstream: + repository: 'AppStream' + description: 'AlmaLinux 8.8 - AppStream' + osname: 'almalinux' + release: '8.8' + baseurl: 'http://mirror.aarnet.edu.au/pub/almalinux/8.8/AppStream/x86_64/os/' + gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux' + almalinux_8_8_highavailability: + repository: 'HighAvailability' + description: 'AlmaLinux 8.8 - HighAvailability' + osname: 'almalinux' + release: '8.8' + baseurl: 'http://mirror.aarnet.edu.au/pub/almalinux/8.8/HighAvailability/x86_64/os/' + gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux' + epel_8_everything: + repository: 'Everything' + description: 'EPEL 8 Everything' + osname: 'epel' + release: '8' + baseurl: 'https://dl.fedoraproject.org/pub/epel/8/Everything/x86_64/' + gpgkey: 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-8' + epel_8_modular: + repository: 'Modular' + description: 'EPEL 8 Modular' + osname: 'epel' + release: '8' + baseurl: 'https://dl.fedoraproject.org/pub/epel/8/Modular/x86_64/' + gpgkey: 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-8' profiles::base::hosts::additional_hosts: - ip: 198.18.17.3 @@ -58,3 +108,26 @@ profiles::base::hosts::additional_hosts: aliases: - prodinf01n04 - puppetdb + - ip: 198.18.17.5 + hostname: prodinf01n05.main.unkin.net + aliases: + - prodinf01n05 + - ip: 198.18.17.6 + hostname: prodinf01n06.main.unkin.net + aliases: + - prodinf01n06 + - ip: 198.18.17.9 + hostname: prodinf01n09.main.unkin.net + aliases: + - prodinf01n09 + - ntp01.main.unkin.net + - ip: 198.18.17.10 + hostname: prodinf01n10.main.unkin.net + aliases: + - prodinf01n10 + - ntp02.main.unkin.net + - ip: 198.18.17.22 + hostname: prodinf01n22.main.unkin.net + aliases: + - prodinf01n22 + - repo.main.unkin.net diff --git a/hieradata/os/AlmaLinux/all_releases.yaml b/hieradata/os/AlmaLinux/all_releases.yaml index beee352..bdb6ccb 100644 --- a/hieradata/os/AlmaLinux/all_releases.yaml +++ b/hieradata/os/AlmaLinux/all_releases.yaml @@ -1,4 +1,9 @@ # hieradata/os/almalinux/all_releases.yaml --- profiles::yum::base::baseurl: http://almalinux.mirror.digitalpacific.com.au -profiles::yum::epel::baseurl: http://epel.mirror.digitalpacific.com.au +profiles::yum::epel::baseurl: http://mirror.aarnet.edu.au/pub/epel +profiles::firewall::firewalld::ensure_package: 'absent' +profiles::firewall::firewalld::ensure_service: 'stopped' +profiles::firewall::firewalld::enable_service: false + +profiles::puppet::client::puppet_version: '7.26.0' diff --git a/hieradata/os/Debian/Debian11.yaml b/hieradata/os/Debian/Debian11.yaml index 8ed26ec..41e6201 100644 --- a/hieradata/os/Debian/Debian11.yaml +++ b/hieradata/os/Debian/Debian11.yaml @@ -10,3 +10,5 @@ profiles::apt::components: - contrib - main - non-free + +profiles::puppet::client::puppet_version: '7.25.0-1bullseye' diff --git a/hieradata/os/Debian/Debian12.yaml b/hieradata/os/Debian/Debian12.yaml index 7063126..fab31d1 100644 --- a/hieradata/os/Debian/Debian12.yaml +++ b/hieradata/os/Debian/Debian12.yaml @@ -11,3 +11,5 @@ profiles::apt::components: - main - non-free - non-free-firmware + +profiles::puppet::client::puppet_version: 'latest' diff --git a/hieradata/roles/infra/ntpserver.yaml b/hieradata/roles/infra/ntpserver.yaml new file mode 100644 index 0000000..e618573 --- /dev/null +++ b/hieradata/roles/infra/ntpserver.yaml @@ -0,0 +1,10 @@ +--- +profiles::ntp::client::client_only: false +profiles::ntp::server::allowquery: + - '198.18.17.0/24' + +profiles::ntp::server::peers: + - '0.au.pool.ntp.org' + - '1.au.pool.ntp.org' + - '2.au.pool.ntp.org' + - '3.au.pool.ntp.org' diff --git a/site/profiles/files/reposync/favicon.ico b/site/profiles/files/reposync/favicon.ico new file mode 100644 index 0000000..6c351da Binary files /dev/null and b/site/profiles/files/reposync/favicon.ico differ diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp index e5831df..d601bf8 100644 --- a/site/profiles/manifests/base.pp +++ b/site/profiles/manifests/base.pp @@ -1,13 +1,12 @@ # this is the base class, which will be used by all servers class profiles::base ( - Array $ntp_servers, + Array $puppet_servers, ) { - class { 'chrony': - servers => $ntp_servers, - } + case $facts['os']['family'] { 'RedHat': { include profiles::yum::global + include profiles::firewall::firewalld } 'Debian': { include profiles::apt::global @@ -17,17 +16,19 @@ class profiles::base ( } } - # include the base packages profile - class { 'profiles::base::packages': - packages => hiera('profiles::base::packages::common'), - ensure => 'installed', + # manage puppet clients + if ! member($puppet_servers, $trusted['certname']) { + include profiles::puppet::client } - # include admin scripts + # include the base profiles + include profiles::packages::base + include profiles::base::facts + include profiles::base::motd include profiles::base::scripts - - # include admin scripts include profiles::base::hosts + include profiles::accounts::sysadmin + include profiles::ntp::client # include the python class class { 'python': @@ -42,7 +43,4 @@ class profiles::base ( secure_path => '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/opt/puppetlabs/bin' } - # default users - include profiles::accounts::sysadmin - } diff --git a/site/profiles/manifests/base/datavol.pp b/site/profiles/manifests/base/datavol.pp new file mode 100644 index 0000000..167f60a --- /dev/null +++ b/site/profiles/manifests/base/datavol.pp @@ -0,0 +1,62 @@ +# profiles::base::datavol +# +# This class manages the creation of a logical volume using the `lvm::volume` definition. +# +# Parameters: +# $ensure - Ensure whether the logical volume is present or not. Defaults to 'present'. +# $vg - Volume group name. No default. +# $pv - Physical volume, typically the disk or partition device path. No default. +# $fstype - Filesystem type for the logical volume. Defaults to 'ext3'. +# $size - Size of the logical volume. undef = 100%FREE. Changing $size to cause a resize. +# +class profiles::base::datavol ( + Enum['present', 'absent'] $ensure = 'present', + Enum['ext2', 'ext3', 'ext4', 'xfs', 'btrfs'] $fstype = 'xfs', + String $vg = 'datavg', + String $pv = '/dev/vdb', + String $lv = 'data', + Stdlib::Absolutepath $mount = '/data', + Optional[Variant[Pattern[/^\d+(M|G|T|P)$/], Integer]] $size = undef, + Array $mount_options = ['noatime', 'nodiratime'], +) { + + # Ensure the physical volume exists + physical_volume { $pv: + ensure => $ensure, + before => Volume_group[$vg], + } + + # Ensure the volume group exists + volume_group { $vg: + ensure => $ensure, + physical_volumes => [$pv], + before => Logical_volume[$lv], + } + + # Ensure the logical volume exists + logical_volume { $lv: + ensure => $ensure, + volume_group => $vg, + size => $size, + before => Filesystem["/dev/${vg}/${lv}"], + } + + # Ensure the filesystem is created on the logical volume + filesystem { "/dev/${vg}/${lv}": + ensure => $ensure, + fs_type => $fstype, + require => Logical_volume[$lv], + before => Mount[$mount], + } + + # Ensure the logical volume is mounted at the desired location + mount { $mount: + ensure => $ensure, + device => "/dev/${vg}/${lv}", + fstype => $fstype, + options => 'defaults', + dump => 0, + pass => 2, + require => Filesystem["/dev/${vg}/${lv}"], + } +} diff --git a/site/profiles/manifests/base/facts.pp b/site/profiles/manifests/base/facts.pp new file mode 100644 index 0000000..e234625 --- /dev/null +++ b/site/profiles/manifests/base/facts.pp @@ -0,0 +1,29 @@ +# a class to define some global facts +class profiles::base::facts { + + # The path where external facts are stored + $facts_d_path = '/opt/puppetlabs/facter/facts.d' + + # Ensure the directory exists + file { $facts_d_path: + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', + } + + # facts to create + $fact_list = [ 'enc_role', 'enc_env' ] + + # Manage the external fact file with content from the template + $fact_list.each | String $item | { + file { "${facts_d_path}/${item}.txt": + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + content => template("profiles/base/facts/${item}.erb"), + require => File[$facts_d_path], + } + } +} diff --git a/site/profiles/manifests/base/motd.pp b/site/profiles/manifests/base/motd.pp new file mode 100644 index 0000000..e1dd5ca --- /dev/null +++ b/site/profiles/manifests/base/motd.pp @@ -0,0 +1,20 @@ +# set the motd +class profiles::base::motd ( + String $enc_role = pick($facts['enc_role'], 'undefined'), + String $enc_env = pick($facts['enc_env'], 'undefined'), + String $fqdn = $facts['networking']['fqdn'], + String $addr = $facts['networking']['ip'], + String $nic = $facts['networking']['primary'], + String $os_name = $facts['os']['name'], + String $os_release = $facts['os']['release']['full'], +) { + + # Use the regsubst function to remove the 'roles::' prefix from the role name + $clean_role = regsubst($enc_role, '^roles::', '') + + # Manage the content of the /etc/motd file + file { '/etc/motd': + ensure => file, + content => template('profiles/base/motd/motd.erb'), + } +} diff --git a/site/profiles/manifests/base/packages.pp b/site/profiles/manifests/base/packages.pp deleted file mode 100644 index 6c15811..0000000 --- a/site/profiles/manifests/base/packages.pp +++ /dev/null @@ -1,27 +0,0 @@ -# This class manages the installation of packages for the base profile -# -# Parameters: -# - $packages: An array of package names to be installed (optional) -# -# Description: -# This class installs a list of packages specified in the $packages parameter -# using the `package` resource from Puppet. Each package in the array is installed -# with the `ensure => installed` attribute, ensuring that the package is present -# on the target system. By default, the class retrieves the package list from Hiera -# using the key 'profiles::base::packages::common'. -# -# Example usage: -# class { 'profiles::base::packages': -# packages => ['package1', 'package2', 'package3'], -# -class profiles::base::packages ( - Array $packages, - Enum[ - 'present', - 'absent', - 'latest', - 'installed' - ] $ensure = 'installed', -){ - ensure_packages($packages, {'ensure' => $ensure}) -} diff --git a/site/profiles/manifests/firewall/firewalld.pp b/site/profiles/manifests/firewall/firewalld.pp new file mode 100644 index 0000000..eaafda7 --- /dev/null +++ b/site/profiles/manifests/firewall/firewalld.pp @@ -0,0 +1,32 @@ +# Manages the firewalld package and service on RedHat-like distributions. +# +# @param ensure_package Determines the state of the firewalld package. +# Can be set to 'absent' to remove the package or 'installed' to ensure it's present. +# +# @param ensure_service Determines the state of the firewalld service. +# Can be set to 'stopped' to stop the service or 'running' to ensure it's active. +# +# @param enable_service A boolean that specifies whether to enable or disable the firewalld service on boot. +# +class profiles::firewall::firewalld ( + Enum['absent', 'installed'] $ensure_package = 'installed', + Enum['stopped', 'running'] $ensure_service = 'running', + Boolean $enable_service = true, +) { + # Ensure it only runs on RedHat like distributions + if $facts['os']['family'] == 'RedHat' { + + # Manage the firewalld package + package { 'firewalld': + ensure => $ensure_package, + } + + # Manage the firewalld service + service { 'firewalld': + ensure => $ensure_service, + enable => $enable_service, + hasrestart => true, + require => Package['firewalld'], + } + } +} diff --git a/site/profiles/manifests/git/git.pp b/site/profiles/manifests/git/git.pp deleted file mode 100644 index ca3b4e7..0000000 --- a/site/profiles/manifests/git/git.pp +++ /dev/null @@ -1,24 +0,0 @@ -# Class: profiles::git::git -# -# This class ensures that the Git package is installed. -# -# It uses the 'package' resource to manage the Git package, -# and will ensure that it is installed. This class does not -# manage any configurations related to Git, it only ensures -# that the package is installed. -# -# The class does not take any parameters. -# -# Example usage: -# -------------- -# To use this class, you simply need to declare it in your manifest: -# -# include profiles::git::git -# -# You do not need to pass any parameters. -# -class profiles::git::git { - package { 'git': - ensure => installed, - } -} diff --git a/site/profiles/manifests/ntp/client.pp b/site/profiles/manifests/ntp/client.pp new file mode 100644 index 0000000..0429266 --- /dev/null +++ b/site/profiles/manifests/ntp/client.pp @@ -0,0 +1,30 @@ +# setup an ntp client using chrony +# use exported resources from profiles::ntp::server if they are available +class profiles::ntp::client ( + Array $peers, + Boolean $wait_enable = true, + Enum[ + 'running', + 'stopped' + ] $wait_ensure = 'running', + Boolean $client_only = true, +) { + + # If $client_only, setup a client. Servers are set to false so that they are configured + # through the profiles::ntp::server class. + if $client_only { + + # Define the client configuration based on OS family + if $facts['os']['family'] == 'RedHat' { + class { 'chrony': + servers => $peers, + wait_enable => $wait_enable, + wait_ensure => $wait_ensure, + } + } else { + class { 'chrony': + servers => $peers, + } + } + } +} diff --git a/site/profiles/manifests/ntp/server.pp b/site/profiles/manifests/ntp/server.pp new file mode 100644 index 0000000..c2f9b83 --- /dev/null +++ b/site/profiles/manifests/ntp/server.pp @@ -0,0 +1,39 @@ +# chronyd server class with exported resources +class profiles::ntp::server ( + Array[Variant[ + Stdlib::IP::Address::V4, + Stdlib::IP::Address::V4::CIDR + ]] $allowquery = ['127.0.0.1'], + Array[Stdlib::Host] $peers = [ + '0.pool.ntp.org', + '1.pool.ntp.org', + '2.pool.ntp.org', + '3.pool.ntp.org' + ], + Boolean $wait_enable = true, + Enum[ + 'running', + 'stopped' + ] $wait_ensure = 'running', +){ + + # check the enc_role has been set, it can take two puppet runs to do this + # TODO: change away from external fact + if $facts['enc_role'] == 'roles::infra::ntpserver' { + + # define the server + if $facts['os']['family'] == 'RedHat' { + class { 'chrony': + servers => $peers, + queryhosts => $allowquery, + wait_enable => $wait_enable, + wait_ensure => $wait_ensure, + } + } else { + class { 'chrony': + servers => $peers, + queryhosts => $allowquery, + } + } + } +} diff --git a/site/profiles/manifests/packages/base.pp b/site/profiles/manifests/packages/base.pp new file mode 100644 index 0000000..807c8a8 --- /dev/null +++ b/site/profiles/manifests/packages/base.pp @@ -0,0 +1,21 @@ +# This class manages the installation of packages for the base profile +# +# Parameters: +# - $packages: An array of package names to be installed (optional) +# - $ensure: Enum of present, absent, latest or installed (optional) +# +# Example usage: +# class { 'profiles::base::packages': +# packages => ['package1', 'package2', 'package3'], +# +class profiles::packages::base ( + Array $packages = lookup('profiles::packages::base', Array, 'first', []), + Enum[ + 'present', + 'absent', + 'latest', + 'installed' + ] $ensure = 'installed', +){ + ensure_packages($packages, {'ensure' => $ensure}) +} diff --git a/site/profiles/manifests/packages/git.pp b/site/profiles/manifests/packages/git.pp new file mode 100644 index 0000000..578aca7 --- /dev/null +++ b/site/profiles/manifests/packages/git.pp @@ -0,0 +1,11 @@ +# installs git related packages +# +class profiles::packages::git ( + Array[String] $packages = lookup('profiles::packages::git', Array, 'first', ['git']), +) { + $packages.each |String $package| { + package { $package: + ensure => installed, + } + } +} diff --git a/site/profiles/manifests/packages/reposync.pp b/site/profiles/manifests/packages/reposync.pp new file mode 100644 index 0000000..f6525a5 --- /dev/null +++ b/site/profiles/manifests/packages/reposync.pp @@ -0,0 +1,11 @@ +# installs reposync related packages +# +class profiles::packages::reposync ( + Array[String] $packages = lookup('profiles::packages::reposync', Array, 'first', ['createrepo']), +) { + $packages.each |String $package| { + package { $package: + ensure => installed, + } + } +} diff --git a/site/profiles/manifests/packages/selinux.pp b/site/profiles/manifests/packages/selinux.pp new file mode 100644 index 0000000..1bbd457 --- /dev/null +++ b/site/profiles/manifests/packages/selinux.pp @@ -0,0 +1,11 @@ +# installs selinux related packages +# +class profiles::packages::selinux ( + Array[String] $packages = lookup('profiles::packages::selinux', Array, 'first', ['policycoreutils']), +) { + $packages.each |String $package| { + package { $package: + ensure => installed, + } + } +} diff --git a/site/profiles/manifests/puppet/client.pp b/site/profiles/manifests/puppet/client.pp new file mode 100644 index 0000000..360e296 --- /dev/null +++ b/site/profiles/manifests/puppet/client.pp @@ -0,0 +1,50 @@ +# Class: profiles::puppet::client +# +# This class manages Puppet client configuration and service. +# +# Parameters: +# vardir - Directory path for variable data. +# logdir - Directory path for logs. +# rundir - Directory path for run-time data. +# pidfile - File path for the PID file. +# codedir - Directory path for code data. +# dns_alt_names - Array of alternate DNS names for the server. +# server - Server's name. +# +# site/profile/manifests/puppet/client.pp +class profiles::puppet::client ( + String $dns_alt_names = $trusted['certname'], + String $server = 'puppetmaster', + String $ca_server = 'puppetca', + String $environment = 'develop', + Integer $runinterval = 1800, + Integer $runtimeout = 3600, + Boolean $show_diff = true, + Boolean $usecacheonfailure = false, + String $puppet_version = 'latest', +) { + + # Ensure the puppet-agent package is installed and locked to a specific version + package { 'puppet-agent': + ensure => $puppet_version, + } + + # Ensure the puppet service is running + service { 'puppet': + ensure => 'running', + enable => true, + hasrestart => true, + require => Package['puppet-agent'], + } + + # Assuming you want to manage puppet.conf with this profile + file { '/etc/puppetlabs/puppet/puppet.conf': + ensure => 'present', + content => template('profiles/puppet/client/puppet.conf.erb'), + owner => 'root', + group => 'root', + mode => '0644', + notify => Service['puppet'], + } +} + diff --git a/site/profiles/manifests/puppet/enc.pp b/site/profiles/manifests/puppet/enc.pp index 6745587..dad9d11 100644 --- a/site/profiles/manifests/puppet/enc.pp +++ b/site/profiles/manifests/puppet/enc.pp @@ -34,15 +34,19 @@ # This is designed to work on Unix-like systems only. # class profiles::puppet::enc ( - String $enc_repo, + String $repo, + String $release = 'master', + Boolean $force = false, ) { - include profiles::git::git + include profiles::packages::git vcsrepo { '/opt/puppetlabs/enc': ensure => latest, provider => git, - source => $enc_repo, + source => $repo, + revision => $release, + force => $force, require => Package['git'], } diff --git a/site/profiles/manifests/puppet/puppetboard.pp b/site/profiles/manifests/puppet/puppetboard.pp index 85d2d4e..0085eb5 100644 --- a/site/profiles/manifests/puppet/puppetboard.pp +++ b/site/profiles/manifests/puppet/puppetboard.pp @@ -1,43 +1,123 @@ # Class: profiles::puppet::puppetboard # -# This class manages the configuration of Puppetboard, a web frontend for PuppetDB. -# -# Parameters: -# - `python_version`: Specifies the Python version used for the virtualenv where Puppetboard runs. -# - `manage_virtualenv`: Determines if this class should handle the creation of the virtual environment for Puppetboard. -# - `reports_count`: Defines the number of reports to show per node in Puppetboard. -# - `offline_mode`: Determines if Puppetboard should work in offline mode or not. -# - `default_environment`: Sets the default Puppet environment to filter results in Puppetboard. -# -# Usage: -# This class can be called directly in your manifests or through Hiera. -# -# Example: -# To use the default parameters (as shown below), you can declare the class: -# -# include profiles::puppet::puppetboard -# -# Alternatively, you can customize the parameters: -# -# class { 'profiles::puppet::puppetboard': -# python_version => '3.8', -# reports_count => 50, -# offline_mode => false, -# } +# This class manages the Puppetboard, a web interface to PuppetDB. # class profiles::puppet::puppetboard ( - String $python_version = '3.6', - Boolean $manage_virtualenv = false, - Integer $reports_count = 40, - Boolean $offline_mode = true, - String $default_environment = '*', + String $python_version = '3.6', + Boolean $manage_virtualenv = false, + Integer $reports_count = 40, + Boolean $offline_mode = true, + String $default_environment = '*', + String $puppetdb_host = lookup('profiles::puppet::puppetdb::puppetdb_host'), + Stdlib::AbsolutePath $basedir = '/opt/puppetboard', + Stdlib::Absolutepath $virtualenv_dir = "${basedir}/venv", + Stdlib::Absolutepath $settings_file = "${basedir}/settings.py", + String $user = 'puppetboard', + String $group = 'puppetboard', + String $gunicorn_bind = '127.0.0.1:8080', + String $gunicorn_bind_prefix = 'http://', + Integer $gunicorn_workers = 1, + Integer $gunicorn_threads = 4, + String $nginx_vhost = 'puppetboard.main.unkin.net', + Integer $nginx_port = 80, + #String[1] $secret_key = "${fqdn_rand_string(32)}", ) { + # store puppet-agents ssl settings/certname + $ssl_dir = $::settings::ssldir + $puppetboard_certname = $trusted['certname'] + + # setup the puppetboard venv class { 'puppetboard': python_version => $python_version, manage_virtualenv => $manage_virtualenv, reports_count => $reports_count, offline_mode => $offline_mode, + basedir => $basedir, + virtualenv_dir => $virtualenv_dir, + settings_file => $settings_file, + #secret_key => $secret_key, default_environment => $default_environment, + puppetdb_host => $puppetdb_host, + puppetdb_port => 8081, + puppetdb_key => "${basedir}/ssl/${puppetboard_certname}.pem", + puppetdb_ssl_verify => "${ssl_dir}/certs/ca.pem", + puppetdb_cert => "${ssl_dir}/certs/${puppetboard_certname}.pem", + user => $user, + group => $group, + notify => Service['puppetboard.service'], + } + + # install gunicorn + python::pip { 'puppetboard_gunicorn': + ensure => 'latest', + pkgname => 'gunicorn', + virtualenv => $virtualenv_dir, + require => Class['puppetboard'], + } + + # create ssl dir for puppetboard + file { "${basedir}/ssl": + ensure => directory, + owner => $user, + group => $group, + mode => '0750', + require => Class['puppetboard'], + } + + # copy the ssl certs for puppetboard + file { "${basedir}/ssl/${puppetboard_certname}.pem": + ensure => present, + owner => $user, + group => $group, + mode => '0750', + source => "${ssl_dir}/private_keys/${puppetboard_certname}.pem", + require => File["${basedir}/ssl"], + notify => Service['puppetboard.service'], + } + + # create script to start service + file { "${virtualenv_dir}/bin/start_puppetboard": + ensure => file, + owner => $user, + group => $group, + mode => '0755', + content => template('profiles/puppet/puppetboard/start_puppetboard.erb'), + require => Class['puppetboard'], + notify => Service['puppetboard.service'], + } + + # create systemd service unit + systemd::unit_file { 'puppetboard.service': + content => template('profiles/puppet/puppetboard/puppetboard.service.erb'), + active => true, + enable => true, + require => File["${virtualenv_dir}/bin/start_puppetboard"], + } + + # ensure the nginx service is managed + class { 'nginx': } + + # create the nginx vhost + nginx::resource::server { $nginx_vhost: + listen_port => $nginx_port, + server_name => [$nginx_vhost], + proxy => "${gunicorn_bind_prefix}${gunicorn_bind}", + proxy_set_header => [ + 'Host $http_host', + 'X-Real-IP $remote_addr', + 'X-Scheme $scheme', + ], + proxy_pass_header => ['Server'], + proxy_redirect => 'off', + proxy_connect_timeout => '10s', + proxy_read_timeout => '10s', + } + + # service static files from nginx for performance + nginx::resource::location { "${nginx_vhost}_static": + location => '/static', + server => $nginx_vhost, + location_alias => "${virtualenv_dir}/lib/python${python_version}/site-packages/puppetboard/static", } } diff --git a/site/profiles/manifests/puppet/puppetdb.pp b/site/profiles/manifests/puppet/puppetdb.pp deleted file mode 100644 index 9ca7a57..0000000 --- a/site/profiles/manifests/puppet/puppetdb.pp +++ /dev/null @@ -1,39 +0,0 @@ -# profiles::puppet::puppetdb -# -# This class manages the installation and configuration of PuppetDB -# and its underlying PostgreSQL database on a single node. -# -# It makes use of the puppetlabs-puppetdb module to manage both the -# PuppetDB service and its PostgreSQL backend. -# -class profiles::puppet::puppetdb( - String $puppetdb_host, - String $listen_address = $facts['networking']['ip'], -) { - - # disable the postgresql dnf module for el8+ - if $facts['os']['family'] == 'RedHat' and $facts['os']['release']['major'] >= '8' { - # based on https://github.com/puppetlabs/puppetlabs-postgresql/blob/main/manifests/dnfmodule.pp - package { 'postgresql dnf module': - ensure => 'disabled', - name => 'postgresql', - provider => 'dnfmodule', - before => Class['puppetdb::database::postgresql'], - } - } - - # Install and configure PostgreSQL for PuppetDB - class { 'puppetdb::database::postgresql': - listen_addresses => $listen_address, - postgresql_ssl_on => false, - postgres_version => '15', - puppetdb_server => $puppetdb_host, - before => Class['puppetdb::server'], - } - - class { 'puppetdb::server': - database_host => $listen_address, - postgresql_ssl_on => false, - manage_firewall => false, - } -} diff --git a/site/profiles/manifests/puppet/puppetdb_api.pp b/site/profiles/manifests/puppet/puppetdb_api.pp new file mode 100644 index 0000000..fb1be2e --- /dev/null +++ b/site/profiles/manifests/puppet/puppetdb_api.pp @@ -0,0 +1,16 @@ +# configure the puppetdb api service +class profiles::puppet::puppetdb_api ( + String $postgres_host = lookup('profiles::puppet::puppetdb::postgres_host'), + String $listen_address = $facts['networking']['ip'], +) { + + class { 'puppetdb::server': + database_host => $postgres_host, + manage_firewall => false, + ssl_listen_address => $listen_address, + listen_address => $listen_address, + } + + contain ::puppetdb::server + +} diff --git a/site/profiles/manifests/puppet/puppetdb_sql.pp b/site/profiles/manifests/puppet/puppetdb_sql.pp new file mode 100644 index 0000000..2d80d30 --- /dev/null +++ b/site/profiles/manifests/puppet/puppetdb_sql.pp @@ -0,0 +1,27 @@ +# configure the puppetdb sql service +class profiles::puppet::puppetdb_sql ( + String $puppetdb_host = lookup('profiles::puppet::puppetdb::puppetdb_host'), + String $listen_address = $facts['networking']['ip'], +) { + + # disable the postgresql dnf module for el8+ + if $facts['os']['family'] == 'RedHat' and $facts['os']['release']['major'] >= '8' { + # based on https://github.com/puppetlabs/puppetlabs-postgresql/blob/main/manifests/dnfmodule.pp + package { 'postgresql dnf module': + ensure => 'disabled', + name => 'postgresql', + provider => 'dnfmodule', + before => Class['puppetdb::database::postgresql'], + } + } + + # Install and configure PostgreSQL for PuppetDB + class { 'puppetdb::database::postgresql': + listen_addresses => $listen_address, + postgres_version => '15', + puppetdb_server => $puppetdb_host, + } + + contain ::puppetdb::database::postgresql + +} diff --git a/site/profiles/manifests/puppet/puppetmaster.pp b/site/profiles/manifests/puppet/puppetmaster.pp index 76a80b6..9819d5e 100644 --- a/site/profiles/manifests/puppet/puppetmaster.pp +++ b/site/profiles/manifests/puppet/puppetmaster.pp @@ -31,16 +31,17 @@ class profiles::puppet::puppetmaster ( include profiles::puppet::autosign class { 'puppetdb::master::config': - puppetdb_server => $puppetdb_host, + puppetdb_server => $puppetdb_host, + manage_storeconfigs => false, } class { 'profiles::puppet::server': - vardir => '/opt/puppetlabs/server/data/puppetserver', - logdir => '/var/log/puppetlabs/puppetserver', - rundir => '/var/run/puppetlabs/puppetserver', - pidfile => '/var/run/puppetlabs/puppetserver/puppetserver.pid', - codedir => '/etc/puppetlabs/code', - dns_alt_names => [ + vardir => '/opt/puppetlabs/server/data/puppetserver', + logdir => '/var/log/puppetlabs/puppetserver', + rundir => '/var/run/puppetlabs/puppetserver', + pidfile => '/var/run/puppetlabs/puppetserver/puppetserver.pid', + codedir => '/etc/puppetlabs/code', + dns_alt_names => [ 'prodinf01n01.main.unkin.net', 'puppet.main.unkin.net', 'puppetca.main.unkin.net', @@ -49,11 +50,15 @@ class profiles::puppet::puppetmaster ( 'puppetca', 'puppetmaster', ], - server => 'prodinf01n01.main.unkin.net', - node_terminus => 'exec', - external_nodes => '/opt/puppetlabs/bin/enc', - autosign => '/etc/puppetlabs/puppet/autosign.conf', - default_manifest => '/etc/puppetlabs/code/environments/develop/manifests', - default_environment => 'develop', + server => 'prodinf01n01.main.unkin.net', + node_terminus => 'exec', + external_nodes => '/opt/puppetlabs/bin/enc', + autosign => '/etc/puppetlabs/puppet/autosign.conf', + default_manifest => '/etc/puppetlabs/code/environments/develop/manifests', + default_environment => 'develop', + storeconfigs => true, + storeconfigs_backend => 'puppetdb', + reports => 'puppetdb', + usecacheonfailure => false, } } diff --git a/site/profiles/manifests/puppet/r10k.pp b/site/profiles/manifests/puppet/r10k.pp index 29d302f..402f49a 100644 --- a/site/profiles/manifests/puppet/r10k.pp +++ b/site/profiles/manifests/puppet/r10k.pp @@ -37,7 +37,7 @@ class profiles::puppet::r10k ( String $r10k_repo, ){ - include profiles::git::git + include profiles::packages::git vcsrepo { '/etc/puppetlabs/r10k': ensure => latest, diff --git a/site/profiles/manifests/puppet/server.pp b/site/profiles/manifests/puppet/server.pp index ca68998..7f0aec5 100644 --- a/site/profiles/manifests/puppet/server.pp +++ b/site/profiles/manifests/puppet/server.pp @@ -27,6 +27,10 @@ class profiles::puppet::server ( String $autosign, String $default_manifest, String $default_environment, + Boolean $storeconfigs, + String $storeconfigs_backend, + String $reports, + Boolean $usecacheonfailure, ) { file { '/etc/puppetlabs/puppet/puppet.conf': @@ -35,18 +39,22 @@ class profiles::puppet::server ( group => 'root', mode => '0644', content => epp('profiles/puppet/server/puppet.conf.epp', { - 'vardir' => $vardir, - 'logdir' => $logdir, - 'rundir' => $rundir, - 'pidfile' => $pidfile, - 'codedir' => $codedir, - 'dns_alt_names' => join($dns_alt_names, ','), - 'server' => $server, - 'node_terminus' => $node_terminus, - 'external_nodes' => $external_nodes, - 'autosign' => $autosign, - 'default_manifest' => $default_manifest, - 'default_environment' => $default_environment, + 'vardir' => $vardir, + 'logdir' => $logdir, + 'rundir' => $rundir, + 'pidfile' => $pidfile, + 'codedir' => $codedir, + 'dns_alt_names' => join($dns_alt_names, ','), + 'server' => $server, + 'node_terminus' => $node_terminus, + 'external_nodes' => $external_nodes, + 'autosign' => $autosign, + 'default_manifest' => $default_manifest, + 'default_environment' => $default_environment, + 'storeconfigs' => $storeconfigs, + 'storeconfigs_backend' => $storeconfigs_backend, + 'reports' => $reports, + 'usecacheonfailure' => $usecacheonfailure, }), notify => Service['puppetserver'], } diff --git a/site/profiles/manifests/reposync/autopromoter.pp b/site/profiles/manifests/reposync/autopromoter.pp new file mode 100644 index 0000000..63c2ab7 --- /dev/null +++ b/site/profiles/manifests/reposync/autopromoter.pp @@ -0,0 +1,105 @@ +# setup the autopromoter +class profiles::reposync::autopromoter { + + # Ensure the autopromoter script is present and executable + file { '/usr/local/bin/autopromoter': + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0755', + content => template('profiles/reposync/autopromoter.erb'), + } + + # daily autopromote service/timer + $_daily_timer = @(EOT) + [Unit] + Description=autopromoter daily timer + [Timer] + OnCalendar=*-*-* 05:00:00 + RandomizedDelaySec=1s + [Install] + WantedBy=timers.target + EOT + + $_daily_service = @(EOT) + [Unit] + Description=autopromoter daily service + [Service] + Type=oneshot + ExecStart=/usr/local/bin/autopromoter daily + User=root + Group=root + PermissionsStartOnly=false + PrivateTmp=no + EOT + + systemd::timer { 'autopromoter-daily.timer': + timer_content => $_daily_timer, + service_content => $_daily_service, + active => true, + enable => true, + require => File['/usr/local/bin/autopromoter'], + } + + # weekly autopromote service/timer + $_weekly_timer = @(EOT) + [Unit] + Description=autopromoter weekly timer + [Timer] + OnCalendar=Sun *-*-* 05:05:00 + RandomizedDelaySec=1s + [Install] + WantedBy=timers.target + EOT + + $_weekly_service = @(EOT) + [Unit] + Description=autopromoter weekly service + [Service] + Type=oneshot + ExecStart=/usr/local/bin/autopromoter weekly + User=root + Group=root + PermissionsStartOnly=false + PrivateTmp=no + EOT + + systemd::timer { 'autopromoter-weekly.timer': + timer_content => $_weekly_timer, + service_content => $_weekly_service, + active => true, + enable => true, + require => File['/usr/local/bin/autopromoter'], + } + + # monthly autopromote service/timer + $_monthly_timer = @(EOT) + [Unit] + Description=autopromoter monthly timer + [Timer] + OnCalendar=*-*-01 05:10:00 + RandomizedDelaySec=1s + [Install] + WantedBy=timers.target + EOT + + $_monthly_service = @(EOT) + [Unit] + Description=autopromoter monthly service + [Service] + Type=oneshot + ExecStart=/usr/local/bin/autopromoter monthly + User=root + Group=root + PermissionsStartOnly=false + PrivateTmp=no + EOT + + systemd::timer { 'autopromoter-monthly.timer': + timer_content => $_monthly_timer, + service_content => $_monthly_service, + active => true, + enable => true, + require => File['/usr/local/bin/autopromoter'], + } +} diff --git a/site/profiles/manifests/reposync/autosyncer.pp b/site/profiles/manifests/reposync/autosyncer.pp new file mode 100644 index 0000000..e2e8683 --- /dev/null +++ b/site/profiles/manifests/reposync/autosyncer.pp @@ -0,0 +1,44 @@ +# setup the autosyncer +class profiles::reposync::autosyncer { + + # Ensure the autosyncer script is present and executable + file { '/usr/local/bin/autosyncer': + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0755', + content => template('profiles/reposync/autosyncer.erb'), + require => Class['profiles::packages::reposync'], + } + + # daily autosyncr service/timer + $_timer = @(EOT) + [Unit] + Description=autosyncer timer + [Timer] + OnCalendar=*-*-* 03:00:00 + RandomizedDelaySec=1s + [Install] + WantedBy=timers.target + EOT + + $_service = @(EOT) + [Unit] + Description=autosyncer service + [Service] + Type=oneshot + ExecStart=/usr/local/bin/autosyncer + User=root + Group=root + PermissionsStartOnly=false + PrivateTmp=no + EOT + + systemd::timer { 'autosyncer.timer': + timer_content => $_timer, + service_content => $_service, + active => true, + enable => true, + require => File['/usr/local/bin/autosyncer'], + } +} diff --git a/site/profiles/manifests/reposync/repos.pp b/site/profiles/manifests/reposync/repos.pp new file mode 100644 index 0000000..5886785 --- /dev/null +++ b/site/profiles/manifests/reposync/repos.pp @@ -0,0 +1,46 @@ +# define to generate repositories in yum +define profiles::reposync::repos ( + String $repository, + String $description, + String $osname, + String $release, + Stdlib::HTTPUrl $baseurl, + Stdlib::HTTPUrl $gpgkey, + String $arch = 'x86_64', + String $repo_owner = 'root', + String $repo_group = 'root', + Stdlib::Absolutepath $basepath = '/data/repos', +){ + + $repos_name = downcase("${osname}-${release}-${repository}-${arch}") + $conf_file = "/etc/reposync/conf.d/${repos_name}.conf" + + # Create the repository configuration + yumrepo { $repos_name: + ensure => 'present', + descr => $description, + baseurl => $baseurl, + gpgkey => $gpgkey, + target => '/etc/yum.repos.d/reposync.repo', + enabled => 0, + gpgcheck => 1, + } + + # Ensure the repo dest path exists + file { "${basepath}/live/${repos_name}" : + ensure => 'directory', + owner => $repo_owner, + group => $repo_group, + mode => '0755', + } + + # Create the repo configuration file + file { $conf_file: + ensure => file, + owner => $repo_owner, + group => $repo_group, + mode => '0644', + content => template('profiles/reposync/repo_conf.erb'), + require => File['/etc/reposync/conf.d'], + } +} diff --git a/site/profiles/manifests/reposync/syncer.pp b/site/profiles/manifests/reposync/syncer.pp new file mode 100644 index 0000000..6f20996 --- /dev/null +++ b/site/profiles/manifests/reposync/syncer.pp @@ -0,0 +1,30 @@ +# setup a reposync syncer +class profiles::reposync::syncer { + + include profiles::packages::reposync + include profiles::reposync::autosyncer + include profiles::reposync::autopromoter + include profiles::reposync::webserver + + # Ensure the reposync config path exists + file { '/etc/reposync': + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', + } + file { '/etc/reposync/conf.d': + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', + } + + # get a list of repos as a hash, and iterate through them + $repos = lookup('profiles::reposync::repos_list', {}) + $repos.each | String $name, Hash $repo_hash | { + profiles::reposync::repos { $name: + * => $repo_hash, + } + } +} diff --git a/site/profiles/manifests/reposync/webserver.pp b/site/profiles/manifests/reposync/webserver.pp new file mode 100644 index 0000000..66f549a --- /dev/null +++ b/site/profiles/manifests/reposync/webserver.pp @@ -0,0 +1,58 @@ +# setup a reposync webserver +class profiles::reposync::webserver ( + String $www_root = '/data/repos/snap', + String $nginx_vhost = 'repos.main.unkin.net', + Integer $nginx_port = 80, + Boolean $favicon = true, + Boolean $selinux = true, +) { + + class { 'nginx': } + + # create the nginx vhost + nginx::resource::server { $nginx_vhost: + listen_port => $nginx_port, + server_name => [$nginx_vhost], + use_default_location => true, + access_log => "/var/log/nginx/${nginx_vhost}_access.log", + error_log => "/var/log/nginx/${nginx_vhost}_error.log", + www_root => $www_root, + autoindex => 'on', + } + + if $favicon { + file { "${www_root}/favicon.ico": + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0644', + source => 'puppet:///modules/profiles/reposync/favicon.ico', + } + } + + if $selinux { + + # include packages that are required + include profiles::packages::selinux + + # set httpd_sys_content_t to all files under the www_root + selinux::fcontext { $www_root: + ensure => 'present', + seltype => 'httpd_sys_content_t', + pathspec => "${www_root}(/.*)?", + } + + # make sure we can connect to port 80 + selboolean { 'httpd_can_network_connect': + persistent => true, + value => 'on', + } + + exec { "restorecon_${www_root}": + path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'], + command => "restorecon -Rv ${www_root}", + refreshonly => true, + subscribe => Selinux::Fcontext[$www_root], + } + } +} diff --git a/site/profiles/templates/base/facts/enc_env.erb b/site/profiles/templates/base/facts/enc_env.erb new file mode 100644 index 0000000..7695e4d --- /dev/null +++ b/site/profiles/templates/base/facts/enc_env.erb @@ -0,0 +1 @@ +enc_env=<%= @enc_env %> diff --git a/site/profiles/templates/base/facts/enc_role.erb b/site/profiles/templates/base/facts/enc_role.erb new file mode 100644 index 0000000..dbef811 --- /dev/null +++ b/site/profiles/templates/base/facts/enc_role.erb @@ -0,0 +1,2 @@ +enc_role=<%= @enc_role[0] %> +enc_role_path=<%= @enc_role[0].gsub('::', '/') %> diff --git a/site/profiles/templates/base/motd/motd.erb b/site/profiles/templates/base/motd/motd.erb new file mode 100644 index 0000000..7ca06df --- /dev/null +++ b/site/profiles/templates/base/motd/motd.erb @@ -0,0 +1,13 @@ +<% +# calculate padding for the longest word +max_length = ['fqdn:', 'os:', 'role:', 'branch:', 'addr:', 'nic:'].max_by(&:length).length +# helper lambda to right-align text +align = ->(word) { word.ljust(max_length) } +%> +<%= align.call('fqdn:') %> <%= @fqdn %> +<%= align.call('os:') %> <%= @os_name %> <%= @os_release %> +<%= align.call('role:') %> <%= @clean_role %> +<%= align.call('branch:') %> <%= @enc_env %> +<%= align.call('addr:') %> <%= @addr %> +<%= align.call('nic:') %> <%= @nic %> + diff --git a/site/profiles/templates/puppet/client/puppet.conf.erb b/site/profiles/templates/puppet/client/puppet.conf.erb new file mode 100644 index 0000000..e7a86c6 --- /dev/null +++ b/site/profiles/templates/puppet/client/puppet.conf.erb @@ -0,0 +1,13 @@ +[main] +dns_alt_names = <%= @dns_alt_names %> + +[agent] +server = <%= @server %> +ca_server = <%= @ca_server %> +environment = <%= @environment %> +report = true +report_server = <%= @server %> +runinterval = <%= @runinterval %> +runtimeout = <%= @runtimeout %> +show_diff = <%= @show_diff %> +usecacheonfailure = <%= @usecacheonfailure %> diff --git a/site/profiles/templates/puppet/puppetboard/puppetboard.service.erb b/site/profiles/templates/puppet/puppetboard/puppetboard.service.erb new file mode 100644 index 0000000..08fec4d --- /dev/null +++ b/site/profiles/templates/puppet/puppetboard/puppetboard.service.erb @@ -0,0 +1,12 @@ +[Unit] +Description=puppetboard daemon +After=network.target +[Service] +Type=simple +User=<%= @user %> +Group=<%= @group %> +Environment="PUPPETBOARD_SETTINGS=<%= @settings_file %>" +ExecStart=<%= @virtualenv_dir %>/bin/start_puppetboard +PrivateTmp=true +[Install] +WantedBy=multi-user.target diff --git a/site/profiles/templates/puppet/puppetboard/start_puppetboard.erb b/site/profiles/templates/puppet/puppetboard/start_puppetboard.erb new file mode 100644 index 0000000..46e6da3 --- /dev/null +++ b/site/profiles/templates/puppet/puppetboard/start_puppetboard.erb @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +<%= @virtualenv_dir %>/bin/gunicorn \ + --workers <%= @gunicorn_workers %> \ + --threads <%= @gunicorn_threads %> \ + --config <%= @settings_file %> \ + --bind <%= @gunicorn_bind %> \ + puppetboard.app:app diff --git a/site/profiles/templates/puppet/server/puppet.conf.epp b/site/profiles/templates/puppet/server/puppet.conf.epp index a22777b..226346d 100644 --- a/site/profiles/templates/puppet/server/puppet.conf.epp +++ b/site/profiles/templates/puppet/server/puppet.conf.epp @@ -17,3 +17,7 @@ external_nodes = <%= $external_nodes %> autosign = <%= $autosign %> default_manifest = <%= $default_manifest %> default_environment = <%= $default_environment %> +storeconfigs = <%= $storeconfigs %> +storeconfigs_backend = <%= $storeconfigs_backend %> +reports = <%= $reports %> +usecacheonfailure = <%= $usecacheonfailure %> diff --git a/site/profiles/templates/reposync/autopromoter.erb b/site/profiles/templates/reposync/autopromoter.erb new file mode 100644 index 0000000..0bf995f --- /dev/null +++ b/site/profiles/templates/reposync/autopromoter.erb @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +# Function to create symlink for snapshots +create_symlink() { + local osname="$1" + local release="$2" + local repository="$3" + local basepath="$4" + local label="$5" # 'monthly', 'weekly', or 'daily' + local date_format="$6" # Date format for finding the snapshot + + # The path where snapshots are stored + local snap_path="${basepath}/snap/${osname}/${release}/${repository}-${date_format}" + + # The target path for the symlink + local symlink_target="${basepath}/snap/${osname}/${release}/${repository}-${label}" + + # Check if the source directory exists + if [[ -d "$snap_path" ]]; then + # Create the symlink, overwrite if it already exists + ln -sfn "$snap_path" "$symlink_target" + echo "Symlink created for $snap_path -> $symlink_target" + else + echo "Snapshot path does not exist: $snap_path" + return 1 + fi +} + +# Determine which snapshot to promote based on the passed argument +case "$1" in + monthly) + promote_date=$(date --date="$(date +%Y%m01) -1 month" +%Y%m%d) + ;; + weekly) + promote_date=$(date --date="last Sunday" +%Y%m%d) + ;; + daily) + promote_date=$(date --date="yesterday" +%Y%m%d) + ;; + *) + echo "Usage: $0 {monthly|weekly|daily}" + exit 1 + ;; +esac + +# Call the function with appropriate arguments +# Iterate over the repositories to create symlinks for each +for conf in /etc/reposync/conf.d/*.conf; do + source "$conf" + + # Create symlink based on the provided argument + create_symlink "$OSNAME" "$RELEASE" "$REPOSITORY" "$BASEPATH" "$1" "$promote_date" +done diff --git a/site/profiles/templates/reposync/autosyncer.erb b/site/profiles/templates/reposync/autosyncer.erb new file mode 100644 index 0000000..a66ed5d --- /dev/null +++ b/site/profiles/templates/reposync/autosyncer.erb @@ -0,0 +1,97 @@ +#!/usr/bin/bash + +# Function to perform reposync +perform_reposync() { + local reponame="$1" + local basepath="$2" + + /usr/bin/dnf reposync \ + --gpgcheck \ + --delete \ + --downloadcomps \ + --download-metadata \ + --remote-time \ + --disablerepo="*" \ + --enablerepo="${reponame}" \ + --download-path="${basepath}/live" +} + +# Function to download GPG keys +download_gpg_key() { + local gpgkeyurl="$1" + local reponame="$2" + local basepath="$3" + + # Extract filename from URL + local filename=$(basename "$gpgkeyurl") + + # Download GPG key to the specified path with the filename from the URL + wget -q -O "${basepath}/live/${reponame}/${filename}" "$gpgkeyurl" || { + echo "Failed to download GPG key from $gpgkeyurl" + } +} + +# Function to perform rsync with hard links +perform_rsync() { + local source_path="$1" + local dest_path="$2" + + # Create the destination directory if it doesn't exist + mkdir -p "$dest_path" + + # Use rsync to create hard links to the files in the destination directory + rsync -a --link-dest="$source_path" "$source_path"/* "$dest_path" +} + +create_repo_metadata() { + local basepath="${1}" + local osname="${2}" + local release="${3}" + local repository="${4}" + local current_date="${5}" + + local repo_path="${basepath}/snap/${osname}/${release}/${repository}-${current_date}" + + if [[ -d "$repo_path" ]]; then + echo "Running createrepo on ${repo_path}..." + createrepo --update "${repo_path}" + if [[ $? -eq 0 ]]; then + echo "Successfully created repository metadata for ${repository}" + else + echo "Failed to create repository metadata for ${repository}" >&2 + return 1 + fi + else + echo "The specified repository path does not exist: ${repo_path}" >&2 + return 1 + fi +} + +# Current date in the required format +DATE=$(date +%Y%m%d) + +# iterate over each configuration file +for conf in /etc/reposync/conf.d/*.conf; do + + # source the configuration to get the variables + source "$conf" + + # Call the function to download the GPG key + download_gpg_key "$GPGKEYURL" "$REPONAME" "$BASEPATH" + + # Call the reposync function + perform_reposync "$REPONAME" "$BASEPATH" + + # Path for rsync source + live_path="${BASEPATH}/live/${REPONAME}" + + # Path for rsync destination + snap_path="${BASEPATH}/snap/${OSNAME}/${RELEASE}/${REPOSITORY}-${DATE}/${ARCH}/os" + + # Call the rsync function + perform_rsync "$live_path" "$snap_path" + + # After syncing each repo, fix the repository metadata + create_repo_metadata "${BASEPATH}" "${OSNAME}" "${RELEASE}" "${REPOSITORY}" "${DATE}" + +done diff --git a/site/profiles/templates/reposync/repo_conf.erb b/site/profiles/templates/reposync/repo_conf.erb new file mode 100644 index 0000000..99eb2b0 --- /dev/null +++ b/site/profiles/templates/reposync/repo_conf.erb @@ -0,0 +1,8 @@ +# <%= @osname %>-<%= @release %>-<%= @repository %> repository configuration +REPOSITORY="<%= @repository %>" +REPONAME="<%= @repos_name %>" +OSNAME="<%= @osname %>" +RELEASE="<%= @release %>" +ARCH="<%= @arch %>" +BASEPATH="<%= @basepath %>" +GPGKEYURL="<%= @gpgkey %>" diff --git a/site/roles/manifests/ceph/mds.pp b/site/roles/manifests/ceph/mds.pp new file mode 100644 index 0000000..a7a6a2e --- /dev/null +++ b/site/roles/manifests/ceph/mds.pp @@ -0,0 +1,6 @@ +# a role to deploy the ceph mds +# work in progress +class roles::ceph::mds { + include profiles::defaults + include profiles::base +} diff --git a/site/roles/manifests/ceph/mon.pp b/site/roles/manifests/ceph/mon.pp new file mode 100644 index 0000000..b1fe65a --- /dev/null +++ b/site/roles/manifests/ceph/mon.pp @@ -0,0 +1,6 @@ +# a role to deploy the ceph mon +# work in progress +class roles::ceph::mon { + include profiles::defaults + include profiles::base +} diff --git a/site/roles/manifests/ceph/osd.pp b/site/roles/manifests/ceph/osd.pp new file mode 100644 index 0000000..047718a --- /dev/null +++ b/site/roles/manifests/ceph/osd.pp @@ -0,0 +1,6 @@ +# a role to deploy the ceph osd +# work in progress +class roles::ceph::osd { + include profiles::defaults + include profiles::base +} diff --git a/site/roles/manifests/infra/ntpserver.pp b/site/roles/manifests/infra/ntpserver.pp new file mode 100644 index 0000000..887efce --- /dev/null +++ b/site/roles/manifests/infra/ntpserver.pp @@ -0,0 +1,6 @@ +# a role to deploy a ntp server +class roles::infra::ntpserver { + include profiles::defaults + include profiles::base + include profiles::ntp::server +} diff --git a/site/roles/manifests/infra/packagerepo.pp b/site/roles/manifests/infra/packagerepo.pp new file mode 100644 index 0000000..ff90820 --- /dev/null +++ b/site/roles/manifests/infra/packagerepo.pp @@ -0,0 +1,7 @@ +# a role to deploy a packagerepo +class roles::infra::packagerepo { + include profiles::defaults + include profiles::base + include profiles::base::datavol + include profiles::reposync::syncer +} diff --git a/site/roles/manifests/puppet/puppetboard.pp b/site/roles/manifests/puppet/puppetboard.pp new file mode 100644 index 0000000..34862c3 --- /dev/null +++ b/site/roles/manifests/puppet/puppetboard.pp @@ -0,0 +1,6 @@ +# a role to deploy the puppetboard +class roles::puppet::puppetboard { + include profiles::defaults + include profiles::base + include profiles::puppet::puppetboard + } diff --git a/site/roles/manifests/puppet/puppetdb_api.pp b/site/roles/manifests/puppet/puppetdb_api.pp new file mode 100644 index 0000000..991102d --- /dev/null +++ b/site/roles/manifests/puppet/puppetdb_api.pp @@ -0,0 +1,6 @@ +# a role to deploy the puppetdb api service +class roles::puppet::puppetdb_api { + include profiles::defaults + include profiles::base + include profiles::puppet::puppetdb_api + } diff --git a/site/roles/manifests/puppet/puppetdb_sql.pp b/site/roles/manifests/puppet/puppetdb_sql.pp new file mode 100644 index 0000000..db640a3 --- /dev/null +++ b/site/roles/manifests/puppet/puppetdb_sql.pp @@ -0,0 +1,6 @@ +# a role to deploy the puppetdb postgresql service +class roles::puppet::puppetdb_sql { + include profiles::defaults + include profiles::base + include profiles::puppet::puppetdb_sql + }