promote develop to master #6

Merged
unkinben merged 449 commits from develop into master 2024-06-01 14:48:48 +10:00
53 changed files with 1179 additions and 174 deletions
Showing only changes of commit 1ff4611318 - Show all commits

View File

@ -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'

View File

@ -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"

View File

@ -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

View File

@ -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'

View File

@ -10,3 +10,5 @@ profiles::apt::components:
- contrib
- main
- non-free
profiles::puppet::client::puppet_version: '7.25.0-1bullseye'

View File

@ -11,3 +11,5 @@ profiles::apt::components:
- main
- non-free
- non-free-firmware
profiles::puppet::client::puppet_version: 'latest'

View File

@ -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'

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -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
}

View File

@ -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}"],
}
}

View File

@ -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],
}
}
}

View File

@ -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'),
}
}

View File

@ -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})
}

View File

@ -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'],
}
}
}

View File

@ -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,
}
}

View File

@ -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,
}
}
}
}

View File

@ -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,
}
}
}
}

View File

@ -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})
}

View File

@ -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,
}
}
}

View File

@ -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,
}
}
}

View File

@ -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,
}
}
}

View File

@ -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'],
}
}

View File

@ -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'],
}

View File

@ -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",
}
}

View File

@ -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,
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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,
}
}

View File

@ -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,

View File

@ -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'],
}

View File

@ -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'],
}
}

View File

@ -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'],
}
}

View File

@ -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'],
}
}

View File

@ -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,
}
}
}

View File

@ -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],
}
}
}

View File

@ -0,0 +1 @@
enc_env=<%= @enc_env %>

View File

@ -0,0 +1,2 @@
enc_role=<%= @enc_role[0] %>
enc_role_path=<%= @enc_role[0].gsub('::', '/') %>

View File

@ -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 %>

View File

@ -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 %>

View File

@ -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

View File

@ -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

View File

@ -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 %>

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,8 @@
# <%= @osname %>-<%= @release %>-<%= @repository %> repository configuration
REPOSITORY="<%= @repository %>"
REPONAME="<%= @repos_name %>"
OSNAME="<%= @osname %>"
RELEASE="<%= @release %>"
ARCH="<%= @arch %>"
BASEPATH="<%= @basepath %>"
GPGKEYURL="<%= @gpgkey %>"

View File

@ -0,0 +1,6 @@
# a role to deploy the ceph mds
# work in progress
class roles::ceph::mds {
include profiles::defaults
include profiles::base
}

View File

@ -0,0 +1,6 @@
# a role to deploy the ceph mon
# work in progress
class roles::ceph::mon {
include profiles::defaults
include profiles::base
}

View File

@ -0,0 +1,6 @@
# a role to deploy the ceph osd
# work in progress
class roles::ceph::osd {
include profiles::defaults
include profiles::base
}

View File

@ -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
}

View File

@ -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
}

View File

@ -0,0 +1,6 @@
# a role to deploy the puppetboard
class roles::puppet::puppetboard {
include profiles::defaults
include profiles::base
include profiles::puppet::puppetboard
}

View File

@ -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
}

View File

@ -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
}