From e785bbfcc19fb3b4178f85f32836360124390f4f Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Thu, 26 Mar 2026 10:48:30 +0100 Subject: [PATCH 01/13] fix: fragments --- manifests/integrations/ansible.pp | 2 +- manifests/integrations/bolt.pp | 2 +- manifests/integrations/hiera.pp | 2 +- manifests/integrations/puppetdb.pp | 2 +- manifests/integrations/puppetserver.pp | 2 +- manifests/integrations/ssh.pp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/manifests/integrations/ansible.pp b/manifests/integrations/ansible.pp index 17de3f7..fb61738 100644 --- a/manifests/integrations/ansible.pp +++ b/manifests/integrations/ansible.pp @@ -131,7 +131,7 @@ target => 'pabawi_env_file', content => @("EOT"), # Ansible Integration - ANSIBLE_ENABLED=${enabled ? { true => 'true', false => 'false' }} + ANSIBLE_ENABLED=${enabled} ${env_lines} | EOT order => '24', diff --git a/manifests/integrations/bolt.pp b/manifests/integrations/bolt.pp index 250bc6e..f5a7c7f 100644 --- a/manifests/integrations/bolt.pp +++ b/manifests/integrations/bolt.pp @@ -102,7 +102,7 @@ target => 'pabawi_env_file', content => @("EOT"), # Bolt Integration - BOLT_ENABLED=${enabled ? { true => 'true', false => 'false' }} + BOLT_ENABLED=${enabled} ${env_lines} | EOT order => '20', diff --git a/manifests/integrations/hiera.pp b/manifests/integrations/hiera.pp index 37e0cd0..246f646 100644 --- a/manifests/integrations/hiera.pp +++ b/manifests/integrations/hiera.pp @@ -106,7 +106,7 @@ target => 'pabawi_env_file', content => @("EOT"), # Hiera Integration - HIERA_ENABLED=${enabled ? { true => 'true', false => 'false' }} + HIERA_ENABLED=${enabled} ${env_lines} | EOT order => '23', diff --git a/manifests/integrations/puppetdb.pp b/manifests/integrations/puppetdb.pp index 395a051..e748eff 100644 --- a/manifests/integrations/puppetdb.pp +++ b/manifests/integrations/puppetdb.pp @@ -230,7 +230,7 @@ target => 'pabawi_env_file', content => @("EOT"), # PuppetDB Integration - PUPPETDB_ENABLED=${enabled ? { true => 'true', false => 'false' }} + PUPPETDB_ENABLED=${enabled} ${env_lines} | EOT order => '21', diff --git a/manifests/integrations/puppetserver.pp b/manifests/integrations/puppetserver.pp index 65bf554..45df180 100644 --- a/manifests/integrations/puppetserver.pp +++ b/manifests/integrations/puppetserver.pp @@ -236,7 +236,7 @@ target => 'pabawi_env_file', content => @("EOT"), # Puppet Server Integration - PUPPETSERVER_ENABLED=${enabled ? { true => 'true', false => 'false' }} + PUPPETSERVER_ENABLED=${enabled} ${env_lines} | EOT order => '22', diff --git a/manifests/integrations/ssh.pp b/manifests/integrations/ssh.pp index 34e688f..c8d6f4f 100644 --- a/manifests/integrations/ssh.pp +++ b/manifests/integrations/ssh.pp @@ -72,7 +72,7 @@ target => 'pabawi_env_file', content => @("EOT"), # SSH Integration - SSH_ENABLED=${enabled ? { true => 'true', false => 'false' }} + SSH_ENABLED=${enabled} ${env_lines} | EOT order => '25', From deb9378865213fd8481abd28154ebd6fd128c336 Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Thu, 26 Mar 2026 10:59:36 +0100 Subject: [PATCH 02/13] fix: fragments --- manifests/integrations/puppetdb.pp | 12 +++--------- manifests/integrations/puppetserver.pp | 6 +++--- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/manifests/integrations/puppetdb.pp b/manifests/integrations/puppetdb.pp index e748eff..6c14630 100644 --- a/manifests/integrations/puppetdb.pp +++ b/manifests/integrations/puppetdb.pp @@ -68,12 +68,6 @@ if $ssl_key_source and !$settings['ssl_key'] { fail('pabawi::integrations::puppetdb: settings[\'ssl_key\'] is required when ssl_key_source is provided') } - - # SSL configuration validation - all three SSL sources should be provided together - $ssl_sources_provided = [$ssl_ca_source, $ssl_cert_source, $ssl_key_source].filter |$val| { $val != undef } - if $ssl_sources_provided.length > 0 and $ssl_sources_provided.length < 3 { - fail('pabawi::integrations::puppetdb: When SSL certificates are used, all three SSL sources (ssl_ca_source, ssl_cert_source, ssl_key_source) must be provided together') - } } # Deploy SSL certificates if sources are provided @@ -83,7 +77,7 @@ # Handle file:// URLs if $ssl_ca_source =~ /^file:\/\/(.+)$/ { - $source_path = $1 + $source_path = regsubst($ssl_ca_source, '^file://', '') file { $ssl_ca_path: ensure => file, source => $source_path, @@ -124,7 +118,7 @@ # Handle file:// URLs if $ssl_cert_source =~ /^file:\/\/(.+)$/ { - $source_path = $1 + $source_path = regsubst($ssl_cert_source, '^file://', '') file { $ssl_cert_path: ensure => file, source => $source_path, @@ -165,7 +159,7 @@ # Handle file:// URLs if $ssl_key_source =~ /^file:\/\/(.+)$/ { - $source_path = $1 + $source_path = regsubst($ssl_key_source, '^file://', '') file { $ssl_key_path: ensure => file, source => $source_path, diff --git a/manifests/integrations/puppetserver.pp b/manifests/integrations/puppetserver.pp index 45df180..2eccba7 100644 --- a/manifests/integrations/puppetserver.pp +++ b/manifests/integrations/puppetserver.pp @@ -89,7 +89,7 @@ # Handle file:// URLs if $ssl_ca_source =~ /^file:\/\/(.+)$/ { - $source_path = $1 + $source_path = regsubst($ssl_ca_source, '^file://', '') file { $ssl_ca_path: ensure => file, source => $source_path, @@ -130,7 +130,7 @@ # Handle file:// URLs if $ssl_cert_source =~ /^file:\/\/(.+)$/ { - $source_path = $1 + $source_path = regsubst($ssl_cert_source, '^file://', '') file { $ssl_cert_path: ensure => file, source => $source_path, @@ -171,7 +171,7 @@ # Handle file:// URLs if $ssl_key_source =~ /^file:\/\/(.+)$/ { - $source_path = $1 + $source_path = regsubst($ssl_key_source, '^file://', '') file { $ssl_key_path: ensure => file, source => $source_path, From a0ceafed6060ab9f4b0a704987503b7f981cf203 Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Thu, 26 Mar 2026 11:01:33 +0100 Subject: [PATCH 03/13] fix: fragments --- manifests/integrations/puppetdb.pp | 9 +++------ manifests/integrations/puppetserver.pp | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/manifests/integrations/puppetdb.pp b/manifests/integrations/puppetdb.pp index 6c14630..58ac27e 100644 --- a/manifests/integrations/puppetdb.pp +++ b/manifests/integrations/puppetdb.pp @@ -77,10 +77,9 @@ # Handle file:// URLs if $ssl_ca_source =~ /^file:\/\/(.+)$/ { - $source_path = regsubst($ssl_ca_source, '^file://', '') file { $ssl_ca_path: ensure => file, - source => $source_path, + source => regsubst($ssl_ca_source, '^file://', ''), mode => $ssl_ca_mode, owner => 'root', group => 'root', @@ -118,10 +117,9 @@ # Handle file:// URLs if $ssl_cert_source =~ /^file:\/\/(.+)$/ { - $source_path = regsubst($ssl_cert_source, '^file://', '') file { $ssl_cert_path: ensure => file, - source => $source_path, + source => regsubst($ssl_cert_source, '^file://', ''), mode => $ssl_cert_mode, owner => 'root', group => 'root', @@ -159,10 +157,9 @@ # Handle file:// URLs if $ssl_key_source =~ /^file:\/\/(.+)$/ { - $source_path = regsubst($ssl_key_source, '^file://', '') file { $ssl_key_path: ensure => file, - source => $source_path, + source => regsubst($ssl_key_source, '^file://', ''), mode => $ssl_key_mode, owner => 'root', group => 'root', diff --git a/manifests/integrations/puppetserver.pp b/manifests/integrations/puppetserver.pp index 2eccba7..dc3f2c3 100644 --- a/manifests/integrations/puppetserver.pp +++ b/manifests/integrations/puppetserver.pp @@ -89,10 +89,9 @@ # Handle file:// URLs if $ssl_ca_source =~ /^file:\/\/(.+)$/ { - $source_path = regsubst($ssl_ca_source, '^file://', '') file { $ssl_ca_path: ensure => file, - source => $source_path, + source => regsubst($ssl_ca_source, '^file://', ''), mode => $ssl_ca_mode, owner => 'root', group => 'root', @@ -130,10 +129,9 @@ # Handle file:// URLs if $ssl_cert_source =~ /^file:\/\/(.+)$/ { - $source_path = regsubst($ssl_cert_source, '^file://', '') file { $ssl_cert_path: ensure => file, - source => $source_path, + source => regsubst($ssl_cert_source, '^file://', ''), mode => $ssl_cert_mode, owner => 'root', group => 'root', @@ -171,10 +169,9 @@ # Handle file:// URLs if $ssl_key_source =~ /^file:\/\/(.+)$/ { - $source_path = regsubst($ssl_key_source, '^file://', '') file { $ssl_key_path: ensure => file, - source => $source_path, + source => regsubst($ssl_key_source, '^file://', ''), mode => $ssl_key_mode, owner => 'root', group => 'root', From c3a341d4c34af0b346c0db50a05510bd05a2a534 Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Thu, 26 Mar 2026 11:10:24 +0100 Subject: [PATCH 04/13] fix: fragments --- manifests/integrations/puppetdb.pp | 75 +++++++++++++++----------- manifests/integrations/puppetserver.pp | 75 +++++++++++++++----------- 2 files changed, 90 insertions(+), 60 deletions(-) diff --git a/manifests/integrations/puppetdb.pp b/manifests/integrations/puppetdb.pp index 58ac27e..c6b187b 100644 --- a/manifests/integrations/puppetdb.pp +++ b/manifests/integrations/puppetdb.pp @@ -73,16 +73,19 @@ # Deploy SSL certificates if sources are provided if $ssl_ca_source { $ssl_ca_path = $settings['ssl_ca'] + $ssl_ca_dir = dirname($ssl_ca_path) $ssl_ca_mode = '0644' + ensure_resource('file', $ssl_ca_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) # Handle file:// URLs if $ssl_ca_source =~ /^file:\/\/(.+)$/ { file { $ssl_ca_path: - ensure => file, - source => regsubst($ssl_ca_source, '^file://', ''), - mode => $ssl_ca_mode, - owner => 'root', - group => 'root', + ensure => file, + source => regsubst($ssl_ca_source, '^file://', ''), + mode => $ssl_ca_mode, + owner => 'root', + group => 'root', + require => File[$ssl_ca_dir], } } # Handle https:// URLs @@ -91,6 +94,7 @@ command => "curl -sL -o ${ssl_ca_path} ${ssl_ca_source}", path => ['/usr/bin', '/bin'], creates => $ssl_ca_path, + require => File[$ssl_ca_dir], } -> file { $ssl_ca_path: ensure => file, @@ -102,27 +106,31 @@ # Handle direct file paths else { file { $ssl_ca_path: - ensure => file, - source => $ssl_ca_source, - mode => $ssl_ca_mode, - owner => 'root', - group => 'root', + ensure => file, + source => $ssl_ca_source, + mode => $ssl_ca_mode, + owner => 'root', + group => 'root', + require => File[$ssl_ca_dir], } } } if $ssl_cert_source { $ssl_cert_path = $settings['ssl_cert'] + $ssl_cert_dir = dirname($ssl_cert_path) $ssl_cert_mode = '0644' + ensure_resource('file', $ssl_cert_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) # Handle file:// URLs if $ssl_cert_source =~ /^file:\/\/(.+)$/ { file { $ssl_cert_path: - ensure => file, - source => regsubst($ssl_cert_source, '^file://', ''), - mode => $ssl_cert_mode, - owner => 'root', - group => 'root', + ensure => file, + source => regsubst($ssl_cert_source, '^file://', ''), + mode => $ssl_cert_mode, + owner => 'root', + group => 'root', + require => File[$ssl_cert_dir], } } # Handle https:// URLs @@ -131,6 +139,7 @@ command => "curl -sL -o ${ssl_cert_path} ${ssl_cert_source}", path => ['/usr/bin', '/bin'], creates => $ssl_cert_path, + require => File[$ssl_cert_dir], } -> file { $ssl_cert_path: ensure => file, @@ -142,27 +151,31 @@ # Handle direct file paths else { file { $ssl_cert_path: - ensure => file, - source => $ssl_cert_source, - mode => $ssl_cert_mode, - owner => 'root', - group => 'root', + ensure => file, + source => $ssl_cert_source, + mode => $ssl_cert_mode, + owner => 'root', + group => 'root', + require => File[$ssl_cert_dir], } } } if $ssl_key_source { $ssl_key_path = $settings['ssl_key'] + $ssl_key_dir = dirname($ssl_key_path) $ssl_key_mode = '0600' + ensure_resource('file', $ssl_key_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) # Handle file:// URLs if $ssl_key_source =~ /^file:\/\/(.+)$/ { file { $ssl_key_path: - ensure => file, - source => regsubst($ssl_key_source, '^file://', ''), - mode => $ssl_key_mode, - owner => 'root', - group => 'root', + ensure => file, + source => regsubst($ssl_key_source, '^file://', ''), + mode => $ssl_key_mode, + owner => 'root', + group => 'root', + require => File[$ssl_key_dir], } } # Handle https:// URLs @@ -171,6 +184,7 @@ command => "curl -sL -o ${ssl_key_path} ${ssl_key_source}", path => ['/usr/bin', '/bin'], creates => $ssl_key_path, + require => File[$ssl_key_dir], } -> file { $ssl_key_path: ensure => file, @@ -182,11 +196,12 @@ # Handle direct file paths else { file { $ssl_key_path: - ensure => file, - source => $ssl_key_source, - mode => $ssl_key_mode, - owner => 'root', - group => 'root', + ensure => file, + source => $ssl_key_source, + mode => $ssl_key_mode, + owner => 'root', + group => 'root', + require => File[$ssl_key_dir], } } } diff --git a/manifests/integrations/puppetserver.pp b/manifests/integrations/puppetserver.pp index dc3f2c3..63b394d 100644 --- a/manifests/integrations/puppetserver.pp +++ b/manifests/integrations/puppetserver.pp @@ -85,16 +85,19 @@ # Deploy SSL certificates if sources are provided if $ssl_ca_source { $ssl_ca_path = $settings['ssl_ca'] + $ssl_ca_dir = dirname($ssl_ca_path) $ssl_ca_mode = '0644' + ensure_resource('file', $ssl_ca_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) # Handle file:// URLs if $ssl_ca_source =~ /^file:\/\/(.+)$/ { file { $ssl_ca_path: - ensure => file, - source => regsubst($ssl_ca_source, '^file://', ''), - mode => $ssl_ca_mode, - owner => 'root', - group => 'root', + ensure => file, + source => regsubst($ssl_ca_source, '^file://', ''), + mode => $ssl_ca_mode, + owner => 'root', + group => 'root', + require => File[$ssl_ca_dir], } } # Handle https:// URLs @@ -103,6 +106,7 @@ command => "curl -sL -o ${ssl_ca_path} ${ssl_ca_source}", path => ['/usr/bin', '/bin'], creates => $ssl_ca_path, + require => File[$ssl_ca_dir], } -> file { $ssl_ca_path: ensure => file, @@ -114,27 +118,31 @@ # Handle direct file paths else { file { $ssl_ca_path: - ensure => file, - source => $ssl_ca_source, - mode => $ssl_ca_mode, - owner => 'root', - group => 'root', + ensure => file, + source => $ssl_ca_source, + mode => $ssl_ca_mode, + owner => 'root', + group => 'root', + require => File[$ssl_ca_dir], } } } if $ssl_cert_source { $ssl_cert_path = $settings['ssl_cert'] + $ssl_cert_dir = dirname($ssl_cert_path) $ssl_cert_mode = '0644' + ensure_resource('file', $ssl_cert_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) # Handle file:// URLs if $ssl_cert_source =~ /^file:\/\/(.+)$/ { file { $ssl_cert_path: - ensure => file, - source => regsubst($ssl_cert_source, '^file://', ''), - mode => $ssl_cert_mode, - owner => 'root', - group => 'root', + ensure => file, + source => regsubst($ssl_cert_source, '^file://', ''), + mode => $ssl_cert_mode, + owner => 'root', + group => 'root', + require => File[$ssl_cert_dir], } } # Handle https:// URLs @@ -143,6 +151,7 @@ command => "curl -sL -o ${ssl_cert_path} ${ssl_cert_source}", path => ['/usr/bin', '/bin'], creates => $ssl_cert_path, + require => File[$ssl_cert_dir], } -> file { $ssl_cert_path: ensure => file, @@ -154,27 +163,31 @@ # Handle direct file paths else { file { $ssl_cert_path: - ensure => file, - source => $ssl_cert_source, - mode => $ssl_cert_mode, - owner => 'root', - group => 'root', + ensure => file, + source => $ssl_cert_source, + mode => $ssl_cert_mode, + owner => 'root', + group => 'root', + require => File[$ssl_cert_dir], } } } if $ssl_key_source { $ssl_key_path = $settings['ssl_key'] + $ssl_key_dir = dirname($ssl_key_path) $ssl_key_mode = '0600' + ensure_resource('file', $ssl_key_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) # Handle file:// URLs if $ssl_key_source =~ /^file:\/\/(.+)$/ { file { $ssl_key_path: - ensure => file, - source => regsubst($ssl_key_source, '^file://', ''), - mode => $ssl_key_mode, - owner => 'root', - group => 'root', + ensure => file, + source => regsubst($ssl_key_source, '^file://', ''), + mode => $ssl_key_mode, + owner => 'root', + group => 'root', + require => File[$ssl_key_dir], } } # Handle https:// URLs @@ -183,6 +196,7 @@ command => "curl -sL -o ${ssl_key_path} ${ssl_key_source}", path => ['/usr/bin', '/bin'], creates => $ssl_key_path, + require => File[$ssl_key_dir], } -> file { $ssl_key_path: ensure => file, @@ -194,11 +208,12 @@ # Handle direct file paths else { file { $ssl_key_path: - ensure => file, - source => $ssl_key_source, - mode => $ssl_key_mode, - owner => 'root', - group => 'root', + ensure => file, + source => $ssl_key_source, + mode => $ssl_key_mode, + owner => 'root', + group => 'root', + require => File[$ssl_key_dir], } } } From c622d2f7b8bc7e80bf4e38778a794c8fe2ba574e Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Thu, 26 Mar 2026 11:14:12 +0100 Subject: [PATCH 05/13] fix: fragments --- manifests/integrations/puppetdb.pp | 30 +++++++++++++++----------- manifests/integrations/puppetserver.pp | 30 +++++++++++++++----------- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/manifests/integrations/puppetdb.pp b/manifests/integrations/puppetdb.pp index c6b187b..8873653 100644 --- a/manifests/integrations/puppetdb.pp +++ b/manifests/integrations/puppetdb.pp @@ -72,10 +72,12 @@ # Deploy SSL certificates if sources are provided if $ssl_ca_source { - $ssl_ca_path = $settings['ssl_ca'] - $ssl_ca_dir = dirname($ssl_ca_path) - $ssl_ca_mode = '0644' - ensure_resource('file', $ssl_ca_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + $ssl_ca_path = $settings['ssl_ca'] + $ssl_ca_dir = dirname($ssl_ca_path) + $ssl_ca_parent = dirname($ssl_ca_dir) + $ssl_ca_mode = '0644' + ensure_resource('file', $ssl_ca_parent, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + ensure_resource('file', $ssl_ca_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755', require => File[$ssl_ca_parent] }) # Handle file:// URLs if $ssl_ca_source =~ /^file:\/\/(.+)$/ { @@ -117,10 +119,12 @@ } if $ssl_cert_source { - $ssl_cert_path = $settings['ssl_cert'] - $ssl_cert_dir = dirname($ssl_cert_path) - $ssl_cert_mode = '0644' - ensure_resource('file', $ssl_cert_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + $ssl_cert_path = $settings['ssl_cert'] + $ssl_cert_dir = dirname($ssl_cert_path) + $ssl_cert_parent = dirname($ssl_cert_dir) + $ssl_cert_mode = '0644' + ensure_resource('file', $ssl_cert_parent, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + ensure_resource('file', $ssl_cert_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755', require => File[$ssl_cert_parent] }) # Handle file:// URLs if $ssl_cert_source =~ /^file:\/\/(.+)$/ { @@ -162,10 +166,12 @@ } if $ssl_key_source { - $ssl_key_path = $settings['ssl_key'] - $ssl_key_dir = dirname($ssl_key_path) - $ssl_key_mode = '0600' - ensure_resource('file', $ssl_key_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + $ssl_key_path = $settings['ssl_key'] + $ssl_key_dir = dirname($ssl_key_path) + $ssl_key_parent = dirname($ssl_key_dir) + $ssl_key_mode = '0600' + ensure_resource('file', $ssl_key_parent, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + ensure_resource('file', $ssl_key_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755', require => File[$ssl_key_parent] }) # Handle file:// URLs if $ssl_key_source =~ /^file:\/\/(.+)$/ { diff --git a/manifests/integrations/puppetserver.pp b/manifests/integrations/puppetserver.pp index 63b394d..9cddbfe 100644 --- a/manifests/integrations/puppetserver.pp +++ b/manifests/integrations/puppetserver.pp @@ -84,10 +84,12 @@ # Deploy SSL certificates if sources are provided if $ssl_ca_source { - $ssl_ca_path = $settings['ssl_ca'] - $ssl_ca_dir = dirname($ssl_ca_path) - $ssl_ca_mode = '0644' - ensure_resource('file', $ssl_ca_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + $ssl_ca_path = $settings['ssl_ca'] + $ssl_ca_dir = dirname($ssl_ca_path) + $ssl_ca_parent = dirname($ssl_ca_dir) + $ssl_ca_mode = '0644' + ensure_resource('file', $ssl_ca_parent, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + ensure_resource('file', $ssl_ca_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755', require => File[$ssl_ca_parent] }) # Handle file:// URLs if $ssl_ca_source =~ /^file:\/\/(.+)$/ { @@ -129,10 +131,12 @@ } if $ssl_cert_source { - $ssl_cert_path = $settings['ssl_cert'] - $ssl_cert_dir = dirname($ssl_cert_path) - $ssl_cert_mode = '0644' - ensure_resource('file', $ssl_cert_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + $ssl_cert_path = $settings['ssl_cert'] + $ssl_cert_dir = dirname($ssl_cert_path) + $ssl_cert_parent = dirname($ssl_cert_dir) + $ssl_cert_mode = '0644' + ensure_resource('file', $ssl_cert_parent, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + ensure_resource('file', $ssl_cert_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755', require => File[$ssl_cert_parent] }) # Handle file:// URLs if $ssl_cert_source =~ /^file:\/\/(.+)$/ { @@ -174,10 +178,12 @@ } if $ssl_key_source { - $ssl_key_path = $settings['ssl_key'] - $ssl_key_dir = dirname($ssl_key_path) - $ssl_key_mode = '0600' - ensure_resource('file', $ssl_key_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + $ssl_key_path = $settings['ssl_key'] + $ssl_key_dir = dirname($ssl_key_path) + $ssl_key_parent = dirname($ssl_key_dir) + $ssl_key_mode = '0600' + ensure_resource('file', $ssl_key_parent, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + ensure_resource('file', $ssl_key_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755', require => File[$ssl_key_parent] }) # Handle file:// URLs if $ssl_key_source =~ /^file:\/\/(.+)$/ { From 74c847c7f234b6c1da26df2f18c6f448f65a1bfe Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Thu, 26 Mar 2026 16:45:16 +0100 Subject: [PATCH 06/13] fix: remove notify --- manifests/init.pp | 9 +-------- spec/classes/init_spec.rb | 6 ------ 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/manifests/init.pp b/manifests/init.pp index 70c8eea..b794173 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -82,13 +82,6 @@ # Process integrations - deduplicate then include each class $integrations.unique.each |String $name| { - $integration_class = "pabawi::integrations::${name}" - - notify { "pabawi_integration_${name}": - message => "Enabling integration: ${integration_class}", - loglevel => 'notice', - } - - include $integration_class + include "pabawi::integrations::${name}" } } diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index 39d29dd..ebbf5bb 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -120,12 +120,6 @@ is_expected.not_to contain_class('pabawi::integrations::ansible') end - it 'creates notify resource for each integration' do - is_expected.to contain_notify('pabawi_integration_terraform').with( - 'message' => 'Enabling integration: pabawi::integrations::terraform', - 'loglevel' => 'notice', - ) - end end context 'with multiple integrations' do From e4997e9b2302df9ddc61aa044b0a34b016e83478 Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Sun, 12 Apr 2026 10:14:03 +0200 Subject: [PATCH 07/13] feat(puppet-pabawi): refactor Docker installation to use systemd service - Replace puppetlabs/docker module dependency with native systemd service using `docker run` - Add optional Docker package installation via manage_docker parameter (default: false) - Update default database_path to /data/pabawi.db (container path) with separate database_host_dir for host mounting - Add container_uid and container_gid parameters for proper file ownership on host database directory - Change jwt_secret from optional to required with fqdn_rand_string(64) default generation - Implement direct docker pull and systemd service unit file instead of docker resource declarations - Add docker_extra_args parameter for passing additional arguments to docker run - Expand documentation with detailed parameter descriptions and additional usage examples - Improve environment variable handling and volume mount configuration for better container integration --- manifests/install/docker.pp | 208 ++++++++++++++++++++++++++---------- metadata.json | 4 - 2 files changed, 151 insertions(+), 61 deletions(-) diff --git a/manifests/install/docker.pp b/manifests/install/docker.pp index 9a358eb..d6c7201 100644 --- a/manifests/install/docker.pp +++ b/manifests/install/docker.pp @@ -1,56 +1,85 @@ -# @summary Install Pabawi using Docker containers +# @summary Install Pabawi as a Docker container managed by systemd # -# This class manages the installation of Pabawi using Docker, -# including Docker setup, image management, and container lifecycle. +# This class runs the Pabawi Docker container as a native systemd service +# using `docker run` directly, without requiring the puppetlabs/docker module. +# Docker packages can optionally be installed by this class. # # @param manage_docker -# Whether to manage the Docker installation. Set to false if Docker is managed elsewhere. +# Whether to install Docker packages. Default: false (assumes Docker is +# already installed and managed elsewhere). +# +# @param docker_package +# Name of the Docker package to install when manage_docker is true. # # @param image -# Docker image to use for Pabawi +# Docker image to use for Pabawi. # # @param container_name -# Name for the Docker container +# Name for the Docker container. # # @param environment -# Environment variables to pass to the container +# Environment variables to pass to the container. # # @param volumes -# Volume mounts for the container +# Volume mounts for the container (Docker -v format strings). # # @param ports -# Port mappings for the container (host => container) +# Port mappings for the container (host => container). # # @param auto_restart -# Whether to automatically restart the container on failure +# Whether systemd should restart the container on failure. +# +# @param install_dir +# Directory for configuration files (.env). # # @param log_level -# Application log level (debug, info, warn, error) +# Application log level (debug, info, warn, error). # # @param auth_enabled -# Whether authentication is enabled +# Whether authentication is enabled. # # @param jwt_secret -# JWT secret for authentication (required if auth_enabled is true) +# JWT secret for authentication (required if auth_enabled is true). # # @param database_path -# Path to application database file +# Path to application database file inside the container. +# Must match a writable path in the container image (default: /data/pabawi.db). # # @param concurrent_execution_limit -# Maximum number of concurrent executions +# Maximum number of concurrent executions. # # @param command_whitelist -# Array of allowed commands for execution control +# Array of allowed commands for execution control. # # @param command_whitelist_allow_all -# Whether to bypass command whitelist and allow all commands +# Whether to bypass command whitelist and allow all commands. +# +# @param database_host_dir +# Host directory to mount for the database. Will be mapped to the +# container directory containing database_path. +# +# @param container_uid +# UID of the application user inside the container. Used to set +# ownership on the host database directory. +# +# @param container_gid +# GID of the application group inside the container. # -# @example Basic usage +# @param docker_extra_args +# Additional arguments to pass to `docker run`. +# +# @example Basic usage (Docker already installed) # include pabawi::install::docker # +# @example Install Docker packages and use custom image +# class { 'pabawi::install::docker': +# manage_docker => true, +# image => 'example42/pabawi:v1.2.3', +# } +# # @example Custom configuration # class { 'pabawi::install::docker': -# image => 'pabawi/pabawi:v1.2.3', +# image => 'example42/pabawi:v1.2.3', # environment => { # 'NODE_ENV' => 'production', # 'PORT' => '3000', @@ -59,7 +88,8 @@ # } # class pabawi::install::docker ( - Boolean $manage_docker = true, + Boolean $manage_docker = false, + String[1] $docker_package = 'docker-ce', String[1] $image = 'example42/pabawi:latest', String[1] $container_name = 'pabawi', Hash[String[1], String] $environment = {}, @@ -69,15 +99,30 @@ Stdlib::Absolutepath $install_dir = '/opt/pabawi', String[1] $log_level = 'info', Boolean $auth_enabled = false, - Optional[String[1]] $jwt_secret = undef, - Stdlib::Absolutepath $database_path = '/var/lib/pabawi/pabawi.db', + String[1] $jwt_secret = fqdn_rand_string(64), + Stdlib::Absolutepath $database_path = '/data/pabawi.db', + Stdlib::Absolutepath $database_host_dir = '/var/lib/pabawi', + Integer $container_uid = 1001, + Integer $container_gid = 1001, Integer $concurrent_execution_limit = 5, Array[String[1]] $command_whitelist = [], Boolean $command_whitelist_allow_all = false, + String $docker_extra_args = '', ) { - # Validate auth configuration - if $auth_enabled and !$jwt_secret { - fail('pabawi::install::docker: jwt_secret is required when auth_enabled is true') + # Docker binary path + $docker_bin = '/usr/bin/docker' + + # Optionally install Docker packages + if $manage_docker { + package { $docker_package: + ensure => installed, + } + + service { 'docker': + ensure => running, + enable => true, + require => Package[$docker_package], + } } # Create installation directory for .env file @@ -88,17 +133,16 @@ mode => '0755', } - # Create database directory - $database_dir = dirname($database_path) - exec { "create_database_dir_${database_path}": - command => "mkdir -p ${database_dir}", + # Create database host directory with container user ownership + exec { "create_database_dir_${database_host_dir}": + command => "mkdir -p ${database_host_dir}", path => ['/usr/bin', '/bin'], - creates => $database_dir, + creates => $database_host_dir, } - -> file { $database_dir: + -> file { $database_host_dir: ensure => directory, - owner => 'root', - group => 'root', + owner => $container_uid, + group => $container_gid, mode => '0755', } @@ -123,7 +167,7 @@ # Pabawi Base Configuration LOG_LEVEL=${log_level} AUTH_ENABLED=${auth_enabled} - JWT_SECRET=${pick($jwt_secret, 'not-set')} + JWT_SECRET=${jwt_secret} DATABASE_PATH=${database_path} CONCURRENT_EXECUTION_LIMIT=${concurrent_execution_limit} COMMAND_WHITELIST=${command_whitelist_json} @@ -132,34 +176,84 @@ order => '10', } - # Conditionally manage Docker installation - if $manage_docker { - class { 'docker': - ensure => present, - } - } + # Build docker run arguments + $database_container_dir = dirname($database_path) + $port_args = $ports.map |$host, $container| { "-p ${host}:${container}" }.join(' ') + $all_volumes = $volumes + ["${database_host_dir}:${database_container_dir}"] + $volume_args = $all_volumes.map |$v| { "-v ${v}" }.join(' ') + $env_args = $environment.map |$key, $value| { "-e ${key}=${value}" }.join(' ') + + $docker_run_args = [ + '--rm', + "--name ${container_name}", + "--env-file ${env_file_path}", + $port_args, + $volume_args, + $env_args, + $docker_extra_args, + $image, + ].filter |$arg| { $arg != '' }.join(' ') - # Pull the Docker image - docker::image { $image: - ensure => present, + # Pull the image before starting the service + exec { "docker_pull_${container_name}": + command => "${docker_bin} pull ${image}", + path => ['/usr/bin', '/bin'], + unless => "${docker_bin} image inspect ${image} > /dev/null 2>&1", require => $manage_docker ? { - true => Class['docker'], - default => undef, + true => Service['docker'], + default => [], }, } - # Create and run the container - docker::run { $container_name: - image => $image, - env => $environment.map |$key, $value| { "${key}=${value}" }, - volumes => $volumes + ["${env_file_path}:/app/.env:ro"], - ports => $ports.map |$host, $container| { "${host}:${container}" }, - restart => $auto_restart ? { - true => 'always', - default => 'no', - }, - require => [ - Docker::Image[$image], + # Create systemd service file + file { "/etc/systemd/system/${container_name}.service": + ensure => file, + mode => '0644', + owner => 'root', + group => 'root', + content => @("EOT"), + [Unit] + Description=Pabawi Docker Container + After=network-online.target docker.service + Wants=network-online.target + Requires=docker.service + + [Service] + Type=simple + ExecStartPre=-${docker_bin} stop ${container_name} + ExecStartPre=-${docker_bin} rm ${container_name} + ExecStart=${docker_bin} run ${docker_run_args} + ExecStop=${docker_bin} stop ${container_name} + Restart=${auto_restart ? { true => 'on-failure', default => 'no' }} + RestartSec=10 + StandardOutput=journal + StandardError=journal + + [Install] + WantedBy=multi-user.target + | EOT + notify => Exec["systemd_reload_${container_name}"], + } + + # Reload systemd when service file changes + exec { "systemd_reload_${container_name}": + command => 'systemctl daemon-reload', + path => ['/usr/bin', '/bin'], + refreshonly => true, + } + + # Manage the container service + service { $container_name: + ensure => running, + enable => true, + require => [ + File["/etc/systemd/system/${container_name}.service"], + Exec["docker_pull_${container_name}"], + Exec["systemd_reload_${container_name}"], + Concat['pabawi_env_file'], + ], + subscribe => [ + File["/etc/systemd/system/${container_name}.service"], Concat['pabawi_env_file'], ], } diff --git a/metadata.json b/metadata.json index 5447114..20d2251 100644 --- a/metadata.json +++ b/metadata.json @@ -12,10 +12,6 @@ "name": "puppetlabs/stdlib", "version_requirement": ">= 6.0.0 < 10.0.0" }, - { - "name": "puppetlabs/docker", - "version_requirement": ">= 4.0.0 < 10.0.0" - }, { "name": "puppetlabs/vcsrepo", "version_requirement": ">= 5.0.0 < 7.0.0" From f693d9d0ef84d928a3bfa137c4aee95e32638b2e Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Sun, 12 Apr 2026 12:07:43 +0200 Subject: [PATCH 08/13] feat(puppet-pabawi): add SSH, Proxmox, and AWS integrations - Add SSH integration class for direct SSH execution with connection pooling and sudo support - Add Proxmox integration class for VM/LXC management with SSL certificate support - Add AWS integration class for EC2 inventory and provisioning - Update design documentation with new integration components and architecture diagrams - Refactor integration configuration to use array-based list instead of hash format - Update README with SSH, Proxmox, and AWS integration sections and examples - Add hiera_full_integrations.yaml example configuration file - Add ssh_ansible_proxmox.pp example manifest - Update all integration classes to support new settings-based configuration pattern - Update metadata.json with new integration dependencies - Update module specs to reflect new integration architecture --- .kiro/puppet-pabawi-module/design.md | 89 ++++- README.md | 466 ++++++++++++------------- data/common.yaml | 130 +++++-- examples/docker_custom_ssl.pp | 8 +- examples/full_integrations.pp | 54 ++- examples/hiera_full_integrations.yaml | 144 ++++++++ examples/ssh_ansible_proxmox.pp | 46 +++ manifests/init.pp | 10 +- manifests/install/docker.pp | 20 +- manifests/install/npm.pp | 11 +- manifests/integrations/ansible.pp | 25 +- manifests/integrations/aws.pp | 94 +++++ manifests/integrations/bolt.pp | 18 +- manifests/integrations/hiera.pp | 20 +- manifests/integrations/proxmox.pp | 256 ++++++++++++++ manifests/integrations/puppetdb.pp | 26 +- manifests/integrations/puppetserver.pp | 30 +- metadata.json | 2 +- spec/classes/init_spec.rb | 38 +- 19 files changed, 1082 insertions(+), 405 deletions(-) create mode 100644 examples/hiera_full_integrations.yaml create mode 100644 examples/ssh_ansible_proxmox.pp create mode 100644 manifests/integrations/aws.pp create mode 100644 manifests/integrations/proxmox.pp diff --git a/.kiro/puppet-pabawi-module/design.md b/.kiro/puppet-pabawi-module/design.md index deb15bb..0af8b28 100644 --- a/.kiro/puppet-pabawi-module/design.md +++ b/.kiro/puppet-pabawi-module/design.md @@ -2,7 +2,7 @@ ## Overview -This Puppet module provides a flexible, modular approach to installing and configuring the Pabawi application with support for multiple installation methods (npm, docker), proxy configurations (nginx with SSL), and various integrations (Bolt, PuppetDB, and extensible integration framework). The design emphasizes separation of concerns through a class-based architecture where each component (proxy, installation, integrations) can be independently enabled, disabled, or swapped with alternative implementations. +This Puppet module provides a flexible, modular approach to installing and configuring the Pabawi application with support for multiple installation methods (npm, docker), proxy configurations (nginx with SSL), and various integrations (Bolt, PuppetDB, Puppetserver, Hiera, Ansible, SSH, Proxmox, and AWS). The design emphasizes separation of concerns through a class-based architecture where each component (proxy, installation, integrations) can be independently enabled, disabled, or swapped with alternative implementations. The module follows Puppet best practices with Hiera-driven configuration, allowing users to customize behavior through data rather than code modifications. The architecture supports extensibility for future integrations while maintaining backward compatibility and sensible defaults. @@ -28,7 +28,12 @@ graph TD K -->|true| N[pabawi::integrations::bolt] L -->|true| O[pabawi::integrations::puppetdb] - M --> P[pabawi::integrations::*] + M --> P[pabawi::integrations::puppetserver] + M --> Q2[pabawi::integrations::hiera] + M --> R2[pabawi::integrations::ansible] + M --> S2[pabawi::integrations::ssh] + M --> T2[pabawi::integrations::proxmox] + M --> U2[pabawi::integrations::aws] F --> Q[SSL Configuration] Q --> R[Self-Signed Certs] @@ -263,6 +268,69 @@ class pabawi::integrations::puppetdb ( - Set up query timeout and connection parameters - Create integration configuration files +### Component 7: SSH Integration Class (pabawi::integrations::ssh) + +**Purpose**: Configure Pabawi integration with direct SSH execution (connection pool, sudo support) + +**Interface**: +```puppet +class pabawi::integrations::ssh ( + Boolean $enabled = true, + Hash $settings = {}, +) { + # Class implementation +} +``` + +**Responsibilities**: +- Configure SSH connection defaults (host, port, user, key path) +- Set connection pool and concurrency limits +- Configure sudo settings for privilege escalation +- Write SSH_* environment variables to .env via concat fragment + +### Component 8: Proxmox Integration Class (pabawi::integrations::proxmox) + +**Purpose**: Configure Pabawi integration with Proxmox Virtual Environment for VM/LXC management + +**Interface**: +```puppet +class pabawi::integrations::proxmox ( + Boolean $enabled = true, + Hash $settings = {}, + Optional[String[1]] $ssl_ca_source = undef, + Optional[String[1]] $ssl_cert_source = undef, + Optional[String[1]] $ssl_key_source = undef, +) { + # Class implementation +} +``` + +**Responsibilities**: +- Configure Proxmox host, port, and authentication (token or username/password) +- Deploy SSL certificates for Proxmox API connection +- Write PROXMOX_* environment variables to .env via concat fragment +- Support token-based (recommended) and username/password authentication + +### Component 9: AWS Integration Class (pabawi::integrations::aws) + +**Purpose**: Configure Pabawi integration with AWS EC2 for inventory, lifecycle, and provisioning + +**Interface**: +```puppet +class pabawi::integrations::aws ( + Boolean $enabled = true, + Hash $settings = {}, +) { + # Class implementation +} +``` + +**Responsibilities**: +- Configure AWS credentials (access key, profile, or default chain) +- Set default region and multi-region discovery +- Write AWS_* environment variables to .env via concat fragment +- Support three authentication modes: explicit keys, named profile, default credential chain + ## Data Models ### Model 1: Module Configuration @@ -676,16 +744,15 @@ include pabawi pabawi::proxy_manage: true pabawi::install_manage: true -pabawi::bolt_enable: true -pabawi::bolt_project_path: '/opt/bolt-project' - -pabawi::puppetdb_enable: true -pabawi::puppetdb_server_url: 'https://puppetdb.example.com:8081' - pabawi::integrations: - terraform: true - ansible: true - custom_integration: true + - bolt + - puppetdb + - puppetserver + - hiera + - ansible + - ssh + - proxmox + - aws # In manifest include pabawi diff --git a/README.md b/README.md index 604d7a0..46140b8 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,9 @@ Puppet module for managing Pabawi - a unified interface for Puppet ecosystem too - [PuppetDB](#puppetdb-integration) - [Puppet Server](#puppet-server-integration) - [Hiera](#hiera-integration) + - [SSH](#ssh-integration) + - [Proxmox](#proxmox-integration) + - [AWS](#aws-integration) - [Examples](#examples) - [Reference](#reference) - [Limitations](#limitations) @@ -31,7 +34,7 @@ Puppet module for managing Pabawi - a unified interface for Puppet ecosystem too ## Description -Pabawi is a unified web interface for interacting with various Puppet ecosystem tools including Bolt, PuppetDB, Puppet Server, Hiera, and Ansible. This Puppet module manages the installation and configuration of Pabawi and its integrations. +Pabawi is a unified web interface for interacting with various Puppet ecosystem tools including Bolt, PuppetDB, Puppet Server, Hiera, Ansible, SSH, Proxmox, and AWS. This Puppet module manages the installation and configuration of Pabawi and its integrations. **Key Features:** - `.env` file-based configuration for all integrations @@ -220,8 +223,8 @@ DATABASE_PATH=... CONCURRENT_EXECUTION_LIMIT=10 # Bolt Integration (order: 20) +BOLT_ENABLED=true BOLT_PROJECT_PATH=/opt/bolt-project -COMMAND_WHITELIST=["ls","pwd"] ... # PuppetDB Integration (order: 21) @@ -240,6 +243,18 @@ HIERA_ENABLED=true # Ansible Integration (order: 24) ANSIBLE_ENABLED=true ... + +# SSH Integration (order: 25) +SSH_ENABLED=true +... + +# Proxmox Integration (order: 26) +PROXMOX_ENABLED=true +... + +# AWS Integration (order: 27) +AWS_ENABLED=true +... ``` ### Content Sources @@ -569,6 +584,164 @@ HIERA_ENVIRONMENTS=["production","development","staging"] HIERA_FACT_SOURCE_PREFER_PUPPETDB=true ``` +### SSH Integration + +Manages direct SSH execution configuration. + +**Parameters:** + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `enabled` | Boolean | true | Whether the integration is enabled (sets SSH_ENABLED in .env) | +| `settings` | Hash | {} | Hash of configuration settings (see below) | + +**Settings Hash Keys:** + +| Key | Type | Description | +|-----|------|-------------| +| `config_path` | String | Path to SSH config file | +| `default_user` | String | Default SSH username | +| `default_port` | Integer | Default SSH port | +| `default_key` | String | Path to default SSH private key | +| `host_key_check` | Boolean | Enable host key checking | +| `connection_timeout` | Integer | Connection timeout (seconds) | +| `command_timeout` | Integer | Command timeout (seconds) | +| `max_connections` | Integer | Maximum total connections | +| `max_connections_per_host` | Integer | Maximum connections per host | +| `idle_timeout` | Integer | Idle connection timeout (seconds) | +| `concurrency_limit` | Integer | Concurrent execution limit | + +**Example:** + +```yaml +pabawi::integrations: + - ssh + +pabawi::integrations::ssh::settings: + default_user: 'automation' + default_port: 22 + default_key: '/opt/pabawi/ssh/id_ed25519' + host_key_check: true + connection_timeout: 30 + command_timeout: 300 + max_connections: 50 + concurrency_limit: 10 +``` + +**Generated .env entries:** +``` +SSH_ENABLED=true +SSH_DEFAULT_USER=automation +SSH_DEFAULT_PORT=22 +SSH_DEFAULT_KEY=/opt/pabawi/ssh/id_ed25519 +SSH_HOST_KEY_CHECK=true +SSH_CONNECTION_TIMEOUT=30 +SSH_COMMAND_TIMEOUT=300 +SSH_MAX_CONNECTIONS=50 +SSH_CONCURRENCY_LIMIT=10 +``` + +### Proxmox Integration + +Manages Proxmox VE connection for VM/LXC provisioning and lifecycle management. + +**Parameters:** + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `enabled` | Boolean | true | Whether the integration is enabled (sets PROXMOX_ENABLED in .env) | +| `settings` | Hash | {} | Hash of configuration settings (see below) | +| `ssl_ca_source` | String | undef | URL to download CA cert from | +| `ssl_cert_source` | String | undef | URL to download client cert from | +| `ssl_key_source` | String | undef | URL to download private key from | + +**Settings Hash Keys:** + +| Key | Type | Description | +|-----|------|-------------| +| `host` | String | Proxmox host (required) | +| `port` | Integer | Proxmox API port (default 8006) | +| `token` | String | API token (recommended auth method) | +| `username` | String | Username (alternative auth) | +| `password` | String | Password (alternative auth) | +| `realm` | String | Authentication realm | +| `ssl_reject_unauthorized` | Boolean | Reject unauthorized certificates | +| `ssl_ca` | String | Path to CA certificate | +| `ssl_cert` | String | Path to client certificate | +| `ssl_key` | String | Path to private key | +| `timeout` | Integer | API timeout (milliseconds) | +| `priority` | Integer | Integration priority | + +**Example:** + +```yaml +pabawi::integrations: + - proxmox + +pabawi::integrations::proxmox::settings: + host: 'proxmox.example.com' + port: 8006 + token: 'user@pam!tokenid=token-value' + ssl_reject_unauthorized: true + timeout: 30000 +``` + +**Generated .env entries:** +``` +PROXMOX_ENABLED=true +PROXMOX_HOST=proxmox.example.com +PROXMOX_PORT=8006 +PROXMOX_TOKEN=user@pam!tokenid=token-value +PROXMOX_SSL_REJECT_UNAUTHORIZED=true +PROXMOX_TIMEOUT=30000 +``` + +### AWS Integration + +Manages AWS EC2 integration for inventory discovery, lifecycle actions, and provisioning. + +**Parameters:** + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `enabled` | Boolean | true | Whether the integration is enabled (sets AWS_ENABLED in .env) | +| `settings` | Hash | {} | Hash of configuration settings (see below) | + +**Settings Hash Keys:** + +| Key | Type | Description | +|-----|------|-------------| +| `access_key_id` | String | AWS access key ID (explicit auth) | +| `secret_access_key` | String | AWS secret access key (explicit auth) | +| `default_region` | String | Default AWS region | +| `regions` | Array[String] | Regions to query for inventory | +| `session_token` | String | AWS session token (temporary credentials) | +| `profile` | String | AWS named profile (recommended) | +| `endpoint` | String | Custom AWS endpoint URL | + +**Example:** + +```yaml +pabawi::integrations: + - aws + +# Using named profile (recommended) +pabawi::integrations::aws::settings: + profile: 'pabawi-prod' + default_region: 'us-east-1' + regions: + - 'us-east-1' + - 'eu-west-1' +``` + +**Generated .env entries:** +``` +AWS_ENABLED=true +AWS_PROFILE=pabawi-prod +AWS_DEFAULT_REGION=us-east-1 +AWS_REGIONS=["us-east-1","eu-west-1"] +``` + ## Examples ### Complete Multi-Integration Setup @@ -587,19 +760,22 @@ pabawi::integrations: - puppetdb - puppetserver - hiera + - ssh + - proxmox + - aws # Bolt integration configuration pabawi::integrations::bolt::manage_package: true pabawi::integrations::bolt::settings: - project_path: '/opt/bolt-project' + project_path: '/opt/pabawi/bolt-project' execution_timeout: 300000 pabawi::integrations::bolt::project_path_source: 'https://github.com/myorg/bolt-project.git' # Ansible integration configuration pabawi::integrations::ansible::manage_package: true pabawi::integrations::ansible::settings: - inventory_path: '/etc/ansible/inventory' - playbook_path: '/etc/ansible/playbooks' + inventory_path: '/opt/pabawi/ansible/inventory' + playbook_path: '/opt/pabawi/ansible/playbooks' execution_timeout: 300000 pabawi::integrations::ansible::inventory_source: 'https://github.com/myorg/ansible-inventory.git' pabawi::integrations::ansible::playbook_source: 'https://github.com/myorg/ansible-playbooks.git' @@ -609,9 +785,6 @@ pabawi::integrations::puppetdb::settings: server_url: 'https://puppetdb.myorg.com' port: 8081 ssl_enabled: true - ssl_ca: '/etc/pabawi/ssl/puppetdb/ca.pem' - ssl_cert: '/etc/pabawi/ssl/puppetdb/cert.pem' - ssl_key: '/etc/pabawi/ssl/puppetdb/key.pem' ssl_reject_unauthorized: true pabawi::integrations::puppetdb::ssl_ca_source: 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem' pabawi::integrations::puppetdb::ssl_cert_source: 'file:///etc/puppetlabs/puppet/ssl/certs/agent.pem' @@ -622,9 +795,6 @@ pabawi::integrations::puppetserver::settings: server_url: 'https://puppet.myorg.com' port: 8140 ssl_enabled: true - ssl_ca: '/etc/pabawi/ssl/puppetserver/ca.pem' - ssl_cert: '/etc/pabawi/ssl/puppetserver/cert.pem' - ssl_key: '/etc/pabawi/ssl/puppetserver/key.pem' ssl_reject_unauthorized: true inactivity_threshold: 3600 cache_ttl: 300000 @@ -633,9 +803,8 @@ pabawi::integrations::puppetserver::ssl_cert_source: 'file:///etc/puppetlabs/pup pabawi::integrations::puppetserver::ssl_key_source: 'file:///etc/puppetlabs/puppet/ssl/private_keys/agent.pem' # Hiera integration configuration -pabawi::integrations::hiera::manage_package: false pabawi::integrations::hiera::settings: - control_repo_path: '/opt/control-repo' + control_repo_path: '/opt/pabawi/control-repo' config_path: 'hiera.yaml' environments: - 'production' @@ -643,16 +812,42 @@ pabawi::integrations::hiera::settings: fact_source_prefer_puppetdb: true pabawi::integrations::hiera::control_repo_source: 'https://github.com/myorg/control-repo.git' +# SSH integration configuration +pabawi::integrations::ssh::settings: + default_user: 'automation' + default_port: 22 + default_key: '/opt/pabawi/ssh/id_ed25519' + host_key_check: true + connection_timeout: 30 + max_connections: 50 + concurrency_limit: 10 + +# Proxmox integration configuration +pabawi::integrations::proxmox::settings: + host: 'proxmox.myorg.com' + port: 8006 + token: 'automation@pve!pabawi=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + ssl_reject_unauthorized: true + timeout: 30000 + +# AWS integration configuration +pabawi::integrations::aws::settings: + profile: 'pabawi-prod' + default_region: 'us-east-1' + regions: + - 'us-east-1' + - 'eu-west-1' + # Nginx proxy settings pabawi::proxy::nginx::ssl_enable: true pabawi::proxy::nginx::ssl_self_signed: false -pabawi::proxy::nginx::ssl_cert: '/etc/ssl/certs/pabawi.crt' -pabawi::proxy::nginx::ssl_key: '/etc/ssl/private/pabawi.key' +pabawi::proxy::nginx::ssl_cert_source: 'puppet:///modules/site/ssl/pabawi.crt' +pabawi::proxy::nginx::ssl_key_source: 'puppet:///modules/site/ssl/pabawi.key' pabawi::proxy::nginx::listen_port: 443 pabawi::proxy::nginx::backend_port: 3000 # NPM installation settings -pabawi::install::npm::install_dir: '/opt/pabawi' +pabawi::install::npm::install_dir: '/opt/pabawi/app' pabawi::install::npm::repo_url: 'https://github.com/example42/pabawi.git' pabawi::install::npm::version: 'v1.0.0' pabawi::install::npm::auth_enabled: true @@ -695,237 +890,19 @@ pabawi::integrations: # Configure Bolt pabawi::integrations::bolt::settings: - project_path: '/opt/bolt-project' + project_path: '/opt/pabawi/bolt-project' ``` ### Complete Hiera Configuration Examples -#### NPM Installation with Full Integration Stack - -Complete Hiera configuration for NPM-based installation with Bolt, Hiera, PuppetDB, and Puppet Server integrations: - -```yaml ---- -# File: data/common.yaml or data/nodes/.yaml - -# Installation method -pabawi::install_manage: true -pabawi::install_class: 'pabawi::install::npm' - -# NPM installation settings -pabawi::install::npm::install_dir: '/opt/pabawi' -pabawi::install::npm::repo_url: 'https://github.com/example42/pabawi.git' -pabawi::install::npm::version: 'main' -pabawi::install::npm::user: 'pabawi' -pabawi::install::npm::group: 'pabawi' -pabawi::install::npm::auth_enabled: true -pabawi::install::npm::jwt_secret: 'change-this-to-a-secure-random-string' -pabawi::install::npm::log_level: 'info' -pabawi::install::npm::concurrent_execution_limit: 10 +For full Hiera configuration examples covering all integrations (Bolt, PuppetDB, Puppet Server, Hiera, Ansible, SSH, Proxmox, AWS), see the `examples/` directory: -# Proxy configuration -pabawi::proxy_manage: true -pabawi::proxy_class: 'pabawi::proxy::nginx' - -# Nginx proxy settings -pabawi::proxy::nginx::server_name: 'pabawi.example.com' -pabawi::proxy::nginx::listen_port: 443 -pabawi::proxy::nginx::backend_port: 3000 -pabawi::proxy::nginx::ssl_enable: true -pabawi::proxy::nginx::ssl_self_signed: false -pabawi::proxy::nginx::ssl_cert: '/etc/ssl/certs/pabawi.example.com.crt' -pabawi::proxy::nginx::ssl_key: '/etc/ssl/private/pabawi.example.com.key' - -# Enable integrations -pabawi::integrations: - - bolt - - hiera - - puppetdb - - puppetserver - -# Bolt Integration -pabawi::integrations::bolt::enabled: true -pabawi::integrations::bolt::manage_package: true -pabawi::integrations::bolt::settings: - project_path: '/opt/pabawi-bolt-project' - execution_timeout: 300000 -pabawi::integrations::bolt::project_path_source: 'https://github.com/example/bolt-project.git' - -# Hiera Integration -pabawi::integrations::hiera::enabled: true -pabawi::integrations::hiera::manage_package: false -pabawi::integrations::hiera::settings: - control_repo_path: '/opt/pabawi-control-repo' - config_path: 'hiera.yaml' - environments: - - 'production' - - 'development' - - 'staging' - fact_source_prefer_puppetdb: true -pabawi::integrations::hiera::control_repo_source: 'https://github.com/example/control-repo.git' - -# PuppetDB Integration -pabawi::integrations::puppetdb::enabled: true -pabawi::integrations::puppetdb::settings: - server_url: 'https://puppetdb.example.com' - port: 8081 - ssl_enabled: true - ssl_ca: '/etc/pabawi/ssl/puppetdb/ca.pem' - ssl_cert: '/etc/pabawi/ssl/puppetdb/cert.pem' - ssl_key: '/etc/pabawi/ssl/puppetdb/key.pem' - ssl_reject_unauthorized: true -pabawi::integrations::puppetdb::ssl_ca_source: 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem' -pabawi::integrations::puppetdb::ssl_cert_source: 'file:///etc/puppetlabs/puppet/ssl/certs/%{facts.fqdn}.pem' -pabawi::integrations::puppetdb::ssl_key_source: 'file:///etc/puppetlabs/puppet/ssl/private_keys/%{facts.fqdn}.pem' - -# Puppet Server Integration -pabawi::integrations::puppetserver::enabled: true -pabawi::integrations::puppetserver::settings: - server_url: 'https://puppet.example.com' - port: 8140 - ssl_enabled: true - ssl_ca: '/etc/pabawi/ssl/puppetserver/ca.pem' - ssl_cert: '/etc/pabawi/ssl/puppetserver/cert.pem' - ssl_key: '/etc/pabawi/ssl/puppetserver/key.pem' - ssl_reject_unauthorized: true - inactivity_threshold: 3600 - cache_ttl: 300000 - circuit_breaker_threshold: 5 - circuit_breaker_timeout: 60000 - circuit_breaker_reset_timeout: 30000 -pabawi::integrations::puppetserver::ssl_ca_source: 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem' -pabawi::integrations::puppetserver::ssl_cert_source: 'file:///etc/puppetlabs/puppet/ssl/certs/%{facts.fqdn}.pem' -pabawi::integrations::puppetserver::ssl_key_source: 'file:///etc/puppetlabs/puppet/ssl/private_keys/%{facts.fqdn}.pem' -``` - -#### Docker Installation with Full Integration Stack - -Complete Hiera configuration for Docker-based installation with the same integrations: - -```yaml ---- -# File: data/common.yaml or data/nodes/.yaml - -# Installation method -pabawi::install_manage: true -pabawi::install_class: 'pabawi::install::docker' - -# Docker installation settings -pabawi::install::docker::install_dir: '/opt/pabawi' -pabawi::install::docker::image: 'example42/pabawi:latest' -pabawi::install::docker::container_name: 'pabawi' -pabawi::install::docker::backend_port: 3000 -pabawi::install::docker::user: 'pabawi' -pabawi::install::docker::group: 'pabawi' -pabawi::install::docker::auth_enabled: true -pabawi::install::docker::jwt_secret: 'change-this-to-a-secure-random-string' -pabawi::install::docker::log_level: 'info' -pabawi::install::docker::concurrent_execution_limit: 10 -pabawi::install::docker::volumes: - - '/opt/pabawi-bolt-project:/app/bolt-project:ro' - - '/opt/pabawi-control-repo:/app/control-repo:ro' - - '/etc/pabawi/ssl:/app/ssl:ro' - - '/opt/pabawi/data:/app/data' - -# Proxy configuration -pabawi::proxy_manage: true -pabawi::proxy_class: 'pabawi::proxy::nginx' - -# Nginx proxy settings -pabawi::proxy::nginx::server_name: 'pabawi.example.com' -pabawi::proxy::nginx::listen_port: 443 -pabawi::proxy::nginx::backend_port: 3000 -pabawi::proxy::nginx::ssl_enable: true -pabawi::proxy::nginx::ssl_self_signed: false -pabawi::proxy::nginx::ssl_cert: '/etc/ssl/certs/pabawi.example.com.crt' -pabawi::proxy::nginx::ssl_key: '/etc/ssl/private/pabawi.example.com.key' - -# Enable integrations -pabawi::integrations: - - bolt - - hiera - - puppetdb - - puppetserver - -# Bolt Integration -pabawi::integrations::bolt::enabled: true -pabawi::integrations::bolt::manage_package: true -pabawi::integrations::bolt::settings: - project_path: '/app/bolt-project' # Path inside container - execution_timeout: 300000 -pabawi::integrations::bolt::project_path_source: 'https://github.com/example/bolt-project.git' - -# Hiera Integration -pabawi::integrations::hiera::enabled: true -pabawi::integrations::hiera::manage_package: false -pabawi::integrations::hiera::settings: - control_repo_path: '/app/control-repo' # Path inside container - config_path: 'hiera.yaml' - environments: - - 'production' - - 'development' - - 'staging' - fact_source_prefer_puppetdb: true -pabawi::integrations::hiera::control_repo_source: 'https://github.com/example/control-repo.git' - -# PuppetDB Integration -pabawi::integrations::puppetdb::enabled: true -pabawi::integrations::puppetdb::settings: - server_url: 'https://puppetdb.example.com' - port: 8081 - ssl_enabled: true - ssl_ca: '/app/ssl/puppetdb/ca.pem' # Path inside container - ssl_cert: '/app/ssl/puppetdb/cert.pem' - ssl_key: '/app/ssl/puppetdb/key.pem' - ssl_reject_unauthorized: true -pabawi::integrations::puppetdb::ssl_ca_source: 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem' -pabawi::integrations::puppetdb::ssl_cert_source: 'file:///etc/puppetlabs/puppet/ssl/certs/%{facts.fqdn}.pem' -pabawi::integrations::puppetdb::ssl_key_source: 'file:///etc/puppetlabs/puppet/ssl/private_keys/%{facts.fqdn}.pem' - -# Puppet Server Integration -pabawi::integrations::puppetserver::enabled: true -pabawi::integrations::puppetserver::settings: - server_url: 'https://puppet.example.com' - port: 8140 - ssl_enabled: true - ssl_ca: '/app/ssl/puppetserver/ca.pem' # Path inside container - ssl_cert: '/app/ssl/puppetserver/cert.pem' - ssl_key: '/app/ssl/puppetserver/key.pem' - ssl_reject_unauthorized: true - inactivity_threshold: 3600 - cache_ttl: 300000 - circuit_breaker_threshold: 5 - circuit_breaker_timeout: 60000 - circuit_breaker_reset_timeout: 30000 -pabawi::integrations::puppetserver::ssl_ca_source: 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem' -pabawi::integrations::puppetserver::ssl_cert_source: 'file:///etc/puppetlabs/puppet/ssl/certs/%{facts.fqdn}.pem' -pabawi::integrations::puppetserver::ssl_key_source: 'file:///etc/puppetlabs/puppet/ssl/private_keys/%{facts.fqdn}.pem' -``` - -#### Key Differences Between NPM and Docker Configurations - -**NPM Installation:** -- `.env` file location: `/opt/pabawi/backend/.env` -- Paths reference host filesystem directly -- Bolt project path: `/opt/pabawi-bolt-project` -- Control repo path: `/opt/pabawi-control-repo` -- SSL certificates: `/etc/pabawi/ssl//` - -**Docker Installation:** -- `.env` file location: `/opt/pabawi/.env` (mounted into container) -- Paths reference container filesystem (mounted volumes) -- Bolt project path: `/app/bolt-project` (mounted from `/opt/pabawi-bolt-project`) -- Control repo path: `/app/control-repo` (mounted from `/opt/pabawi-control-repo`) -- SSL certificates: `/app/ssl//` (mounted from `/etc/pabawi/ssl`) -- Requires volume mounts in `pabawi::install::docker::volumes` - -**Important Notes:** -1. Replace `example.com` with your actual domain -2. Change JWT secret to a secure random string -3. Update git repository URLs to your actual repositories -4. Adjust SSL certificate paths if using different locations -5. For Docker, ensure volume mounts align with paths in settings -6. Use Puppet facts (e.g., `%{facts.fqdn}`) for dynamic certificate paths +- `examples/hiera_full_integrations.yaml` — Complete Hiera data with every integration +- `examples/full_integrations.pp` — Puppet-centric setup (Bolt, PuppetDB, Puppet Server, Hiera) +- `examples/ssh_ansible_proxmox.pp` — Agentless setup (SSH, Ansible, Proxmox) +- `examples/docker_custom_ssl.pp` — Docker installation with custom SSL +- `examples/basic_nginx_npm.pp` — Minimal defaults +- `examples/minimal_no_proxy.pp` — No proxy, npm only ## Reference @@ -965,7 +942,10 @@ puppet-pabawi/ │ ├── ansible.pp # Ansible integration │ ├── puppetdb.pp # PuppetDB integration │ ├── puppetserver.pp # Puppet Server integration -│ └── hiera.pp # Hiera integration +│ ├── hiera.pp # Hiera integration +│ ├── ssh.pp # SSH integration +│ ├── proxmox.pp # Proxmox integration +│ └── aws.pp # AWS integration ├── data/ │ └── common.yaml # Default Hiera data ├── examples/ # Usage examples diff --git a/data/common.yaml b/data/common.yaml index d217598..024aa0a 100644 --- a/data/common.yaml +++ b/data/common.yaml @@ -1,6 +1,10 @@ --- # Default configuration for Pabawi module # These values can be overridden in environment-specific or node-specific Hiera data +# +# All paths default to /opt/pabawi/ for both npm and Docker installs. +# Users only need to specify *_source parameters in Hiera to tell Puppet where +# to fetch git repos, certificates, or other files from. # Proxy management pabawi::proxy_manage: true @@ -20,6 +24,9 @@ pabawi::integrations: [] # - hiera # - puppetdb # - puppetserver +# - ssh +# - proxmox +# - aws # Integration Control: # 1. Array inclusion: Integration class is included (resources created, .env fragment added) @@ -28,58 +35,105 @@ pabawi::integrations: [] # This allows pre-configuration without enabling, and easy toggling via enabled parameter # Bolt integration configuration -# pabawi::integrations::bolt::enabled: true # Set to false to disable but keep configured -pabawi::integrations::bolt::project_path: '/opt/bolt-project' +# pabawi::integrations::bolt::enabled: true +# pabawi::integrations::bolt::settings: +# project_path: '/opt/pabawi/bolt-project' # default, override if needed +# execution_timeout: 300000 # pabawi::integrations::bolt::project_path_source: 'https://github.com/example/bolt-project.git' # pabawi::integrations::bolt::manage_package: false -# pabawi::integrations::bolt::command_whitelist: ['plan run', 'task run'] -# pabawi::integrations::bolt::command_whitelist_allow_all: false -# pabawi::integrations::bolt::execution_timeout: 300000 # PuppetDB integration configuration -# pabawi::integrations::puppetdb::enabled: true # Set to false to disable but keep configured -pabawi::integrations::puppetdb::server_url: 'https://puppetdb.example.com:8081' -# pabawi::integrations::puppetdb::port: 8081 -# pabawi::integrations::puppetdb::ssl_enabled: true -# pabawi::integrations::puppetdb::ssl_cert: '/etc/puppetlabs/puppet/ssl/certs/agent.pem' -# pabawi::integrations::puppetdb::ssl_key: '/etc/puppetlabs/puppet/ssl/private_keys/agent.pem' -# pabawi::integrations::puppetdb::ssl_ca: '/etc/puppetlabs/puppet/ssl/certs/ca.pem' -# pabawi::integrations::puppetdb::ssl_reject_unauthorized: true +# pabawi::integrations::puppetdb::enabled: true +# pabawi::integrations::puppetdb::settings: +# server_url: 'https://puppetdb.example.com' +# port: 8081 +# ssl_enabled: true +# ssl_ca: '/opt/pabawi/certs/puppetdb/ca.pem' # default, override if needed +# ssl_cert: '/opt/pabawi/certs/puppetdb/cert.pem' # default, override if needed +# ssl_key: '/opt/pabawi/certs/puppetdb/key.pem' # default, override if needed +# ssl_reject_unauthorized: true +# pabawi::integrations::puppetdb::ssl_ca_source: 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem' +# pabawi::integrations::puppetdb::ssl_cert_source: 'file:///etc/puppetlabs/puppet/ssl/certs/agent.pem' +# pabawi::integrations::puppetdb::ssl_key_source: 'file:///etc/puppetlabs/puppet/ssl/private_keys/agent.pem' # Puppet Server integration configuration -# pabawi::integrations::puppetserver::enabled: true # Set to false to disable but keep configured -pabawi::integrations::puppetserver::server_url: 'https://puppet.example.com:8140' -# pabawi::integrations::puppetserver::port: 8140 -# pabawi::integrations::puppetserver::ssl_enabled: true -# pabawi::integrations::puppetserver::ssl_cert: '/etc/puppetlabs/puppet/ssl/certs/agent.pem' -# pabawi::integrations::puppetserver::ssl_key: '/etc/puppetlabs/puppet/ssl/private_keys/agent.pem' -# pabawi::integrations::puppetserver::ssl_ca: '/etc/puppetlabs/puppet/ssl/certs/ca.pem' -# pabawi::integrations::puppetserver::ssl_reject_unauthorized: true -# pabawi::integrations::puppetserver::inactivity_threshold: 3600 -# pabawi::integrations::puppetserver::cache_ttl: 300000 -# pabawi::integrations::puppetserver::circuit_breaker_threshold: 5 -# pabawi::integrations::puppetserver::circuit_breaker_timeout: 60000 -# pabawi::integrations::puppetserver::circuit_breaker_reset_timeout: 30000 +# pabawi::integrations::puppetserver::enabled: true +# pabawi::integrations::puppetserver::settings: +# server_url: 'https://puppet.example.com' +# port: 8140 +# ssl_enabled: true +# ssl_ca: '/opt/pabawi/certs/puppetserver/ca.pem' # default, override if needed +# ssl_cert: '/opt/pabawi/certs/puppetserver/cert.pem' # default, override if needed +# ssl_key: '/opt/pabawi/certs/puppetserver/key.pem' # default, override if needed +# ssl_reject_unauthorized: true +# inactivity_threshold: 3600 +# cache_ttl: 300000 +# circuit_breaker_threshold: 5 +# circuit_breaker_timeout: 60000 +# circuit_breaker_reset_timeout: 30000 +# pabawi::integrations::puppetserver::ssl_ca_source: 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem' +# pabawi::integrations::puppetserver::ssl_cert_source: 'file:///etc/puppetlabs/puppet/ssl/certs/agent.pem' +# pabawi::integrations::puppetserver::ssl_key_source: 'file:///etc/puppetlabs/puppet/ssl/private_keys/agent.pem' # Hiera integration configuration -# pabawi::integrations::hiera::enabled: true # Set to false to disable but keep configured -pabawi::integrations::hiera::control_repo_path: '/opt/control-repo' +# pabawi::integrations::hiera::enabled: true +# pabawi::integrations::hiera::settings: +# control_repo_path: '/opt/pabawi/control-repo' # default, override if needed +# config_path: 'hiera_pabawi.yaml' +# environments: ['production'] +# fact_source_prefer_puppetdb: true +# fact_source_local_path: '/opt/pabawi/facts' # pabawi::integrations::hiera::control_repo_source: 'https://github.com/example/control-repo.git' # pabawi::integrations::hiera::manage_package: false -# pabawi::integrations::hiera::config_path: 'hiera_pabawi.yaml' -# pabawi::integrations::hiera::environments: ['production'] -# pabawi::integrations::hiera::fact_source_prefer_puppetdb: true -# pabawi::integrations::hiera::fact_source_local_path: '/var/lib/puppet/facts' # Ansible integration configuration -# pabawi::integrations::ansible::enabled: true # Set to false to disable but keep configured -pabawi::integrations::ansible::inventory_path: '/etc/ansible/inventory' +# pabawi::integrations::ansible::enabled: true +# pabawi::integrations::ansible::settings: +# inventory_path: '/opt/pabawi/ansible/inventory' # default, override if needed +# playbook_path: '/opt/pabawi/ansible/playbooks' # default, override if needed +# execution_timeout: 300000 +# config: '/opt/pabawi/ansible/ansible.cfg' # pabawi::integrations::ansible::inventory_source: 'https://github.com/example/ansible-inventory.git' -# pabawi::integrations::ansible::playbook_path: '/etc/ansible/playbooks' # pabawi::integrations::ansible::playbook_source: 'https://github.com/example/ansible-playbooks.git' # pabawi::integrations::ansible::manage_package: false -# pabawi::integrations::ansible::execution_timeout: 300000 -# pabawi::integrations::ansible::config: '/etc/ansible/ansible.cfg' + +# SSH integration configuration +# pabawi::integrations::ssh::enabled: true +# pabawi::integrations::ssh::settings: +# config_path: '/opt/pabawi/ssh/config' +# default_user: 'root' +# default_port: 22 +# default_key: '/opt/pabawi/ssh/id_rsa' + +# Proxmox integration configuration +# pabawi::integrations::proxmox::enabled: true +# pabawi::integrations::proxmox::settings: +# host: 'proxmox.example.com' +# port: 8006 +# token: 'user@pam!tokenid=token-value' +# ssl_reject_unauthorized: true +# ssl_ca: '/opt/pabawi/certs/proxmox/ca.pem' # default, override if needed +# ssl_cert: '/opt/pabawi/certs/proxmox/cert.pem' # default, override if needed +# ssl_key: '/opt/pabawi/certs/proxmox/key.pem' # default, override if needed +# timeout: 30000 +# priority: 7 +# pabawi::integrations::proxmox::ssl_ca_source: 'file:///etc/ssl/certs/proxmox-ca.pem' +# pabawi::integrations::proxmox::ssl_cert_source: 'file:///etc/ssl/certs/proxmox-cert.pem' +# pabawi::integrations::proxmox::ssl_key_source: 'file:///etc/ssl/private/proxmox-key.pem' + +# AWS integration configuration +# pabawi::integrations::aws::enabled: true +# pabawi::integrations::aws::settings: +# profile: 'pabawi-prod' +# default_region: 'us-east-1' +# regions: +# - 'us-east-1' +# - 'eu-west-1' +# Or with explicit credentials: +# pabawi::integrations::aws::settings: +# access_key_id: 'AKIAIOSFODNN7EXAMPLE' +# secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' +# default_region: 'us-east-1' # Nginx proxy configuration pabawi::proxy::nginx::ssl_enable: true @@ -103,7 +157,7 @@ pabawi::install::npm::concurrent_execution_limit: 5 pabawi::install::docker::image: 'example42/pabawi:latest' pabawi::install::docker::container_name: 'pabawi' pabawi::install::docker::auto_restart: true -pabawi::install::docker::install_dir: '/opt/pabawi/app' +pabawi::install::docker::install_dir: '/opt/pabawi' pabawi::install::docker::log_level: 'info' pabawi::install::docker::auth_enabled: false # pabawi::install::docker::jwt_secret: 'your-secret-key-here' diff --git a/examples/docker_custom_ssl.pp b/examples/docker_custom_ssl.pp index 812c745..4eb8259 100644 --- a/examples/docker_custom_ssl.pp +++ b/examples/docker_custom_ssl.pp @@ -14,9 +14,7 @@ } class { 'pabawi::install::docker': - image => 'example42/pabawi:v0.8.0', - environment => { - 'NODE_ENV' => 'production', - 'PORT' => '3000', - }, + image => 'example42/pabawi:v1.0.0', + auth_enabled => true, + jwt_secret => 'change-this-to-a-secure-random-string', } diff --git a/examples/full_integrations.pp b/examples/full_integrations.pp index a6409a9..a370480 100644 --- a/examples/full_integrations.pp +++ b/examples/full_integrations.pp @@ -1,32 +1,50 @@ -# Example: Full installation with all integrations enabled +# Example: Puppet ecosystem setup # -# This example demonstrates a complete Pabawi setup with -# Bolt, PuppetDB, and Hiera integrations enabled. +# Minimal configuration for a Puppet-centric deployment with Bolt, +# PuppetDB, Puppet Server, and Hiera. SSL certificates are sourced +# from the local Puppet agent. All other settings use defaults. +# +# For the full Hiera version with every integration, see +# hiera_full_integrations.yaml in this directory. class { 'pabawi': - integrations => ['bolt', 'puppetdb', 'hiera'], + integrations => ['bolt', 'puppetdb', 'puppetserver', 'hiera'], } -# Configure Bolt integration via Hiera or class parameters +# Bolt — clone project from git class { 'pabawi::integrations::bolt': - project_path => '/opt/bolt-project', - command_whitelist => ['plan run', 'task run'], - execution_timeout => 300000, - manage_package => false, + project_path_source => 'https://github.com/example/bolt-project.git', } -# Configure PuppetDB integration +# PuppetDB — deploy SSL certs from Puppet agent class { 'pabawi::integrations::puppetdb': - server_url => 'https://puppetdb.example.com:8081', - ssl_ca_source => 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem', - ssl_cert_source => 'file:///etc/puppetlabs/puppet/ssl/certs/agent.pem', - ssl_key_source => 'file:///etc/puppetlabs/puppet/ssl/private_keys/agent.pem', - ssl_reject_unauthorized => true, + settings => { + 'server_url' => 'https://puppetdb.example.com', + 'port' => 8081, + 'ssl_enabled' => true, + }, + ssl_ca_source => 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem', + ssl_cert_source => 'file:///etc/puppetlabs/puppet/ssl/certs/agent.pem', + ssl_key_source => 'file:///etc/puppetlabs/puppet/ssl/private_keys/agent.pem', +} + +# Puppet Server — reuse same certs +class { 'pabawi::integrations::puppetserver': + settings => { + 'server_url' => 'https://puppet.example.com', + 'port' => 8140, + 'ssl_enabled' => true, + }, + ssl_ca_source => 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem', + ssl_cert_source => 'file:///etc/puppetlabs/puppet/ssl/certs/agent.pem', + ssl_key_source => 'file:///etc/puppetlabs/puppet/ssl/private_keys/agent.pem', } -# Configure Hiera integration +# Hiera — clone control repo from git class { 'pabawi::integrations::hiera': - control_repo_path => '/opt/control-repo', + settings => { + 'config_path' => 'hiera_pabawi.yaml', + 'environments' => ['production', 'development'], + }, control_repo_source => 'https://github.com/example/control-repo.git', - environments => ['production', 'development'], } diff --git a/examples/hiera_full_integrations.yaml b/examples/hiera_full_integrations.yaml new file mode 100644 index 0000000..a9a7a64 --- /dev/null +++ b/examples/hiera_full_integrations.yaml @@ -0,0 +1,144 @@ +# Example: Full Hiera configuration with all integrations +# +# This file shows the complete Hiera data for a Pabawi deployment with +# every integration enabled. Place in data/common.yaml or a node-specific +# Hiera file and simply `include pabawi` in your manifest. +# +# All paths default to /opt/pabawi/. Only override what you need. +# SSL certificate sources use the local Puppet agent certs by default. +--- + +# Installation +pabawi::install_class: 'pabawi::install::npm' + +# Proxy +pabawi::proxy_manage: true +pabawi::proxy::nginx::ssl_enable: true +pabawi::proxy::nginx::ssl_self_signed: true +pabawi::proxy::nginx::listen_port: 443 +pabawi::proxy::nginx::backend_port: 3000 + +# NPM installation +pabawi::install::npm::install_dir: '/opt/pabawi/app' +pabawi::install::npm::repo_url: 'https://github.com/example42/pabawi.git' +pabawi::install::npm::version: 'main' +pabawi::install::npm::user: 'pabawi' +pabawi::install::npm::group: 'pabawi' +pabawi::install::npm::log_level: 'info' +pabawi::install::npm::auth_enabled: true +pabawi::install::npm::jwt_secret: 'change-this-to-a-secure-random-string' +pabawi::install::npm::database_path: '/opt/pabawi/data/pabawi.db' +pabawi::install::npm::concurrent_execution_limit: 10 + +# All integrations enabled +pabawi::integrations: + - bolt + - puppetdb + - puppetserver + - hiera + - ansible + - ssh + - proxmox + - aws + +# --- Bolt --- +pabawi::integrations::bolt::enabled: true +pabawi::integrations::bolt::manage_package: true +pabawi::integrations::bolt::settings: + project_path: '/opt/pabawi/bolt-project' + execution_timeout: 300000 +pabawi::integrations::bolt::project_path_source: 'https://github.com/example/bolt-project.git' + +# --- PuppetDB --- +pabawi::integrations::puppetdb::enabled: true +pabawi::integrations::puppetdb::settings: + server_url: 'https://puppetdb.example.com' + port: 8081 + ssl_enabled: true + ssl_ca: '/opt/pabawi/certs/puppetdb/ca.pem' + ssl_cert: '/opt/pabawi/certs/puppetdb/cert.pem' + ssl_key: '/opt/pabawi/certs/puppetdb/key.pem' + ssl_reject_unauthorized: true +pabawi::integrations::puppetdb::ssl_ca_source: 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem' +pabawi::integrations::puppetdb::ssl_cert_source: 'file:///etc/puppetlabs/puppet/ssl/certs/agent.pem' +pabawi::integrations::puppetdb::ssl_key_source: 'file:///etc/puppetlabs/puppet/ssl/private_keys/agent.pem' + +# --- Puppet Server --- +pabawi::integrations::puppetserver::enabled: true +pabawi::integrations::puppetserver::settings: + server_url: 'https://puppet.example.com' + port: 8140 + ssl_enabled: true + ssl_ca: '/opt/pabawi/certs/puppetserver/ca.pem' + ssl_cert: '/opt/pabawi/certs/puppetserver/cert.pem' + ssl_key: '/opt/pabawi/certs/puppetserver/key.pem' + ssl_reject_unauthorized: true + inactivity_threshold: 3600 + cache_ttl: 300000 + circuit_breaker_threshold: 5 + circuit_breaker_timeout: 60000 + circuit_breaker_reset_timeout: 30000 +pabawi::integrations::puppetserver::ssl_ca_source: 'file:///etc/puppetlabs/puppet/ssl/certs/ca.pem' +pabawi::integrations::puppetserver::ssl_cert_source: 'file:///etc/puppetlabs/puppet/ssl/certs/agent.pem' +pabawi::integrations::puppetserver::ssl_key_source: 'file:///etc/puppetlabs/puppet/ssl/private_keys/agent.pem' + +# --- Hiera --- +pabawi::integrations::hiera::enabled: true +pabawi::integrations::hiera::settings: + control_repo_path: '/opt/pabawi/control-repo' + config_path: 'hiera_pabawi.yaml' + environments: + - 'production' + - 'development' + fact_source_prefer_puppetdb: true +pabawi::integrations::hiera::control_repo_source: 'https://github.com/example/control-repo.git' + +# --- Ansible --- +pabawi::integrations::ansible::enabled: true +pabawi::integrations::ansible::manage_package: true +pabawi::integrations::ansible::settings: + inventory_path: '/opt/pabawi/ansible/inventory' + playbook_path: '/opt/pabawi/ansible/playbooks' + execution_timeout: 300000 +pabawi::integrations::ansible::inventory_source: 'https://github.com/example/ansible-inventory.git' +pabawi::integrations::ansible::playbook_source: 'https://github.com/example/ansible-playbooks.git' + +# --- SSH --- +pabawi::integrations::ssh::enabled: true +pabawi::integrations::ssh::settings: + config_path: '/opt/pabawi/ssh/config' + default_user: 'root' + default_port: 22 + default_key: '/opt/pabawi/ssh/id_rsa' + host_key_check: true + connection_timeout: 30 + command_timeout: 300 + max_connections: 50 + max_connections_per_host: 5 + idle_timeout: 300 + concurrency_limit: 10 + +# --- Proxmox --- +pabawi::integrations::proxmox::enabled: true +pabawi::integrations::proxmox::settings: + host: 'proxmox.example.com' + port: 8006 + token: 'user@pam!tokenid=token-value' + ssl_reject_unauthorized: true + ssl_ca: '/opt/pabawi/certs/proxmox/ca.pem' + ssl_cert: '/opt/pabawi/certs/proxmox/cert.pem' + ssl_key: '/opt/pabawi/certs/proxmox/key.pem' + timeout: 30000 + priority: 7 +pabawi::integrations::proxmox::ssl_ca_source: 'file:///etc/ssl/certs/proxmox-ca.pem' +pabawi::integrations::proxmox::ssl_cert_source: 'file:///etc/ssl/certs/proxmox-cert.pem' +pabawi::integrations::proxmox::ssl_key_source: 'file:///etc/ssl/private/proxmox-key.pem' + +# --- AWS --- +pabawi::integrations::aws::enabled: true +pabawi::integrations::aws::settings: + profile: 'pabawi-prod' + default_region: 'us-east-1' + regions: + - 'us-east-1' + - 'eu-west-1' diff --git a/examples/ssh_ansible_proxmox.pp b/examples/ssh_ansible_proxmox.pp new file mode 100644 index 0000000..c14b079 --- /dev/null +++ b/examples/ssh_ansible_proxmox.pp @@ -0,0 +1,46 @@ +# Example: Agentless infrastructure with SSH, Ansible, and Proxmox +# +# This setup is for environments without Puppet agents where you manage +# nodes via SSH and Ansible, and provision VMs/LXCs on Proxmox. + +class { 'pabawi': + integrations => ['ssh', 'ansible', 'proxmox'], +} + +# SSH — direct execution with connection pool +class { 'pabawi::integrations::ssh': + settings => { + 'default_user' => 'automation', + 'default_port' => 22, + 'default_key' => '/opt/pabawi/ssh/id_ed25519', + 'host_key_check' => true, + 'connection_timeout' => 30, + 'command_timeout' => 300, + 'max_connections' => 50, + 'max_connections_per_host' => 5, + 'concurrency_limit' => 10, + }, +} + +# Ansible — clone inventory and playbooks from git +class { 'pabawi::integrations::ansible': + manage_package => true, + settings => { + 'inventory_path' => '/opt/pabawi/ansible/inventory', + 'playbook_path' => '/opt/pabawi/ansible/playbooks', + 'execution_timeout' => 300000, + }, + inventory_source => 'https://github.com/example/ansible-inventory.git', + playbook_source => 'https://github.com/example/ansible-playbooks.git', +} + +# Proxmox — token authentication (recommended) +class { 'pabawi::integrations::proxmox': + settings => { + 'host' => 'proxmox.example.com', + 'port' => 8006, + 'token' => 'automation@pve!pabawi=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', + 'ssl_reject_unauthorized' => true, + 'timeout' => 30000, + }, +} diff --git a/manifests/init.pp b/manifests/init.pp index b794173..c366923 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -22,10 +22,10 @@ # # @param integrations # Array of integration names to enable. Only the following integrations are -# supported: puppetdb, puppetserver, hiera, bolt, ansible. Duplicates are -# automatically removed. Integration-specific configuration is managed via -# class parameters in Hiera. -# Example: ['bolt', 'puppetdb', 'hiera'] +# supported: puppetdb, puppetserver, hiera, bolt, ansible, ssh, proxmox, aws. +# Duplicates are automatically removed. Integration-specific configuration +# is managed via class parameters in Hiera. +# Example: ['bolt', 'puppetdb', 'hiera', 'ssh', 'proxmox', 'aws'] # # @example Basic usage with defaults # include pabawi @@ -50,7 +50,7 @@ String[1] $proxy_class = 'pabawi::proxy::nginx', Boolean $install_manage = true, String[1] $install_class = 'pabawi::install::npm', - Array[Enum['puppetdb', 'puppetserver', 'hiera', 'bolt', 'ansible']] $integrations = [], + Array[Enum['puppetdb', 'puppetserver', 'hiera', 'bolt', 'ansible', 'ssh', 'proxmox', 'aws']] $integrations = [], ) { # Validate proxy_class is a valid class name format if $proxy_manage { diff --git a/manifests/install/docker.pp b/manifests/install/docker.pp index d6c7201..12bdfb0 100644 --- a/manifests/install/docker.pp +++ b/manifests/install/docker.pp @@ -26,6 +26,10 @@ # @param ports # Port mappings for the container (host => container). # +# @param bind_address +# IP address to bind port mappings to. Defaults to 127.0.0.1 when +# pabawi::proxy_manage is true (looked up from Hiera), 0.0.0.0 otherwise. +# # @param auto_restart # Whether systemd should restart the container on failure. # @@ -43,7 +47,7 @@ # # @param database_path # Path to application database file inside the container. -# Must match a writable path in the container image (default: /data/pabawi.db). +# Must match a writable path in the container image (default: /opt/pabawi/data/pabawi.db). # # @param concurrent_execution_limit # Maximum number of concurrent executions. @@ -95,13 +99,16 @@ Hash[String[1], String] $environment = {}, Array[String[1]] $volumes = [], Hash[String[1], String[1]] $ports = { '3000' => '3000' }, + String[1] $bind_address = lookup('pabawi::proxy_manage', Boolean, 'first', false) ? { + true => '127.0.0.1', + default => '0.0.0.0', + }, Boolean $auto_restart = true, - Stdlib::Absolutepath $install_dir = '/opt/pabawi', - String[1] $log_level = 'info', + Stdlib::Absolutepath $install_dir = '/opt/pabawi', String[1] $log_level = 'info', Boolean $auth_enabled = false, String[1] $jwt_secret = fqdn_rand_string(64), - Stdlib::Absolutepath $database_path = '/data/pabawi.db', - Stdlib::Absolutepath $database_host_dir = '/var/lib/pabawi', + Stdlib::Absolutepath $database_path = '/opt/pabawi/data/pabawi.db', + Stdlib::Absolutepath $database_host_dir = '/opt/pabawi/data', Integer $container_uid = 1001, Integer $container_gid = 1001, Integer $concurrent_execution_limit = 5, @@ -165,6 +172,7 @@ target => 'pabawi_env_file', content => @("EOT"), # Pabawi Base Configuration + HOST=${bind_address} LOG_LEVEL=${log_level} AUTH_ENABLED=${auth_enabled} JWT_SECRET=${jwt_secret} @@ -178,7 +186,7 @@ # Build docker run arguments $database_container_dir = dirname($database_path) - $port_args = $ports.map |$host, $container| { "-p ${host}:${container}" }.join(' ') + $port_args = $ports.map |$host, $container| { "-p ${bind_address}:${host}:${container}" }.join(' ') $all_volumes = $volumes + ["${database_host_dir}:${database_container_dir}"] $volume_args = $all_volumes.map |$v| { "-v ${v}" }.join(' ') $env_args = $environment.map |$key, $value| { "-e ${key}=${value}" }.join(' ') diff --git a/manifests/install/npm.pp b/manifests/install/npm.pp index 05a7b6c..4dc53df 100644 --- a/manifests/install/npm.pp +++ b/manifests/install/npm.pp @@ -42,6 +42,10 @@ # @param concurrent_execution_limit # Maximum number of concurrent executions # +# @param bind_address +# IP address for the application to listen on. Defaults to 127.0.0.1 when +# pabawi::proxy_manage is true (looked up from Hiera), 0.0.0.0 otherwise. +# # @example Basic usage # include pabawi::install::npm # @@ -65,6 +69,10 @@ Optional[String[1]] $jwt_secret = undef, Stdlib::Absolutepath $database_path = '/opt/pabawi/data/pabawi.db', Integer $concurrent_execution_limit = 5, + String[1] $bind_address = lookup('pabawi::proxy_manage', Boolean, 'first', false) ? { + true => '127.0.0.1', + default => '0.0.0.0', + }, ) { # Validate auth configuration if $auth_enabled and !$jwt_secret { @@ -128,6 +136,7 @@ target => 'pabawi_env_file', content => @("EOT"), # Pabawi Base Configuration + HOST=${bind_address} LOG_LEVEL=${log_level} AUTH_ENABLED=${auth_enabled} JWT_SECRET=${pick($jwt_secret, 'not-set')} @@ -213,7 +222,7 @@ Type=simple User=${user} Group=${group} - WorkingDirectory=${install_dir} + WorkingDirectory=${install_dir}/backend ExecStart=/usr/bin/node ${install_dir}/backend/dist/server.js Restart=on-failure RestartSec=10 diff --git a/manifests/integrations/ansible.pp b/manifests/integrations/ansible.pp index fb61738..23110dd 100644 --- a/manifests/integrations/ansible.pp +++ b/manifests/integrations/ansible.pp @@ -29,12 +29,8 @@ # }, # } # -# @example With git repositories +# @example Minimal usage with git repositories (paths default to /opt/pabawi/ansible/*) # class { 'pabawi::integrations::ansible': -# settings => { -# 'inventory_path' => '/opt/pabawi/ansible/inventory', -# 'playbook_path' => '/opt/pabawi/ansible/playbooks', -# }, # inventory_source => 'https://github.com/example/ansible-inventory.git', # playbook_source => 'https://github.com/example/ansible-playbooks.git', # } @@ -46,15 +42,12 @@ Optional[String[1]] $inventory_source = undef, Optional[String[1]] $playbook_source = undef, ) { - # Validate required parameters when integration is enabled - if $enabled { - if $inventory_source and !$settings['inventory_path'] { - fail('pabawi::integrations::ansible: settings[\'inventory_path\'] is required when inventory_source is provided') - } - if $playbook_source and !$settings['playbook_path'] { - fail('pabawi::integrations::ansible: settings[\'playbook_path\'] is required when playbook_source is provided') - } + # Merge sane defaults for local paths when source is provided but path is not + $_default_settings = { + 'inventory_path' => '/opt/pabawi/ansible/inventory', + 'playbook_path' => '/opt/pabawi/ansible/playbooks', } + $_settings = $_default_settings + $settings # Manage ansible package if requested if $manage_package { @@ -65,7 +58,7 @@ # Clone inventory repository if source is provided if $inventory_source { - $inventory_path = $settings['inventory_path'] + $inventory_path = $_settings['inventory_path'] # Ensure parent directory exists $inventory_parent_dir = dirname($inventory_path) exec { "create_ansible_inventory_parent_dir_${inventory_path}": @@ -84,7 +77,7 @@ # Clone playbook repository if source is provided if $playbook_source { - $playbook_path = $settings['playbook_path'] + $playbook_path = $_settings['playbook_path'] # Ensure parent directory exists $playbook_parent_dir = dirname($playbook_path) exec { "create_ansible_playbook_parent_dir_${playbook_path}": @@ -103,7 +96,7 @@ # Transform settings hash values to .env format # Arrays -> JSON, Booleans -> lowercase strings, Integers -> strings, undef/empty -> 'not-set' - $env_vars = $settings.reduce({}) |$memo, $pair| { + $env_vars = $_settings.reduce({}) |$memo, $pair| { $key = $pair[0] $value = $pair[1] diff --git a/manifests/integrations/aws.pp b/manifests/integrations/aws.pp new file mode 100644 index 0000000..1f7a4e4 --- /dev/null +++ b/manifests/integrations/aws.pp @@ -0,0 +1,94 @@ +# @summary Configure Pabawi integration with AWS EC2 +# +# This class manages the integration between Pabawi and AWS EC2, +# writing configuration to the .env file for EC2 inventory discovery, +# lifecycle management, and provisioning. +# +# Authentication supports three modes: +# 1. Explicit access key + secret key (via settings) +# 2. AWS named profile (via settings) +# 3. Default credential chain (env vars, ~/.aws/credentials, instance profile) +# +# @param enabled +# Whether the integration is enabled (sets AWS_ENABLED in .env) +# +# @param settings +# Hash of Pabawi application configuration settings written to .env with AWS_ prefix. +# Supported keys: access_key_id, secret_access_key, default_region, regions, +# session_token, profile, endpoint +# +# @example Basic usage with access keys +# class { 'pabawi::integrations::aws': +# settings => { +# 'access_key_id' => 'AKIAIOSFODNN7EXAMPLE', +# 'secret_access_key' => 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY', +# 'default_region' => 'us-east-1', +# 'regions' => ['us-east-1', 'eu-west-1'], +# }, +# } +# +# @example Using AWS profile (recommended for non-EC2 hosts) +# class { 'pabawi::integrations::aws': +# settings => { +# 'profile' => 'pabawi-prod', +# 'default_region' => 'us-east-1', +# 'regions' => ['us-east-1', 'us-west-2'], +# }, +# } +# +# @example Using default credential chain (recommended on EC2 with instance profile) +# class { 'pabawi::integrations::aws': +# settings => { +# 'default_region' => 'us-east-1', +# }, +# } +# +# @example Via Hiera +# pabawi::integrations::aws::enabled: true +# pabawi::integrations::aws::settings: +# profile: 'pabawi-prod' +# default_region: 'us-east-1' +# regions: +# - 'us-east-1' +# - 'eu-west-1' +# +class pabawi::integrations::aws ( + Boolean $enabled = true, + Hash $settings = {}, +) { + # Transform settings hash values to .env format + # Arrays -> JSON, Booleans -> lowercase strings, Integers -> strings, undef/empty -> 'not-set' + $env_vars = $settings.reduce({}) |$memo, $pair| { + $key = $pair[0] + $value = $pair[1] + + # Transform value based on type + $transformed = $value ? { + Array => inline_template('[<%= @value.map { |v| "\"#{v}\"" }.join(",") %>]'), + Boolean => $value ? { true => 'true', false => 'false' }, + Integer => String($value), + String => $value, + Undef => 'not-set', + default => pick($value, 'not-set'), + } + + $env_key = upcase($key) + $memo + { "AWS_${env_key}" => $transformed } + } + + # Build environment variable lines + $env_lines = $env_vars.map |$key, $value| { + "${key}=${value}" + }.join("\n") + + # Add configuration to .env file via concat fragment + concat::fragment { 'pabawi_env_aws': + target => 'pabawi_env_file', + content => @("EOT"), + # AWS Integration + AWS_ENABLED=${enabled} + ${env_lines} + | EOT + order => '27', + } +} diff --git a/manifests/integrations/bolt.pp b/manifests/integrations/bolt.pp index f5a7c7f..83efa79 100644 --- a/manifests/integrations/bolt.pp +++ b/manifests/integrations/bolt.pp @@ -25,11 +25,8 @@ # }, # } # -# @example With git repository +# @example Minimal usage with git repository (project_path defaults to /opt/pabawi/bolt-project) # class { 'pabawi::integrations::bolt': -# settings => { -# 'project_path' => '/opt/pabawi/bolt-project', -# }, # project_path_source => 'https://github.com/example/bolt-project.git', # } # @@ -39,12 +36,11 @@ Boolean $manage_package = false, Optional[String[1]] $project_path_source = undef, ) { - # Validate required parameters when integration is enabled - if $enabled { - if $project_path_source and !$settings['project_path'] { - fail('pabawi::integrations::bolt: settings[\'project_path\'] is required when project_path_source is provided') - } + # Merge sane defaults for local paths when source is provided but path is not + $_default_settings = { + 'project_path' => '/opt/pabawi/bolt-project', } + $_settings = $_default_settings + $settings # Manage bolt package if requested if $manage_package { @@ -55,7 +51,7 @@ # Clone git repository if source is provided if $project_path_source { - $project_path = $settings['project_path'] + $project_path = $_settings['project_path'] # Ensure parent directory exists $parent_dir = dirname($project_path) exec { "create_bolt_parent_dir_${project_path}": @@ -74,7 +70,7 @@ # Transform settings hash values to .env format # Arrays -> JSON, Booleans -> lowercase strings, Integers -> strings, undef/empty -> 'not-set' - $env_vars = $settings.reduce({}) |$memo, $pair| { + $env_vars = $_settings.reduce({}) |$memo, $pair| { $key = $pair[0] $value = $pair[1] diff --git a/manifests/integrations/hiera.pp b/manifests/integrations/hiera.pp index 246f646..f7e55b9 100644 --- a/manifests/integrations/hiera.pp +++ b/manifests/integrations/hiera.pp @@ -27,13 +27,8 @@ # }, # } # -# @example With git repository +# @example Minimal usage with git repository (control_repo_path defaults to /opt/pabawi/control-repo) # class { 'pabawi::integrations::hiera': -# settings => { -# 'control_repo_path' => '/opt/pabawi/control-repo', -# 'config_path' => 'hiera_pabawi.yaml', -# 'environments' => ['production'], -# }, # control_repo_source => 'https://github.com/example/control-repo.git', # } # @@ -43,12 +38,11 @@ Boolean $manage_package = false, Optional[String[1]] $control_repo_source = undef, ) { - # Validate required parameters when integration is enabled - if $enabled { - if $control_repo_source and !$settings['control_repo_path'] { - fail('pabawi::integrations::hiera: settings[\'control_repo_path\'] is required when control_repo_source is provided') - } + # Merge sane defaults for local paths when source is provided but path is not + $_default_settings = { + 'control_repo_path' => '/opt/pabawi/control-repo', } + $_settings = $_default_settings + $settings # Manage hiera package if requested if $manage_package { @@ -59,7 +53,7 @@ # Clone git repository if source is provided if $control_repo_source { - $control_repo_path = $settings['control_repo_path'] + $control_repo_path = $_settings['control_repo_path'] # Ensure parent directory exists $parent_dir = dirname($control_repo_path) exec { "create_hiera_parent_dir_${control_repo_path}": @@ -78,7 +72,7 @@ # Transform settings hash values to .env format # Arrays -> JSON, Booleans -> lowercase strings, Integers -> strings, undef/empty -> 'not-set' - $env_vars = $settings.reduce({}) |$memo, $pair| { + $env_vars = $_settings.reduce({}) |$memo, $pair| { $key = $pair[0] $value = $pair[1] diff --git a/manifests/integrations/proxmox.pp b/manifests/integrations/proxmox.pp new file mode 100644 index 0000000..488af34 --- /dev/null +++ b/manifests/integrations/proxmox.pp @@ -0,0 +1,256 @@ +# @summary Configure Pabawi integration with Proxmox VE +# +# This class manages the integration between Pabawi and Proxmox Virtual Environment, +# including SSL certificate deployment and .env configuration for VM/LXC management. +# +# @param enabled +# Whether the integration is enabled (sets PROXMOX_ENABLED in .env) +# +# @param settings +# Hash of Pabawi application configuration settings written to .env with PROXMOX_ prefix. +# Supported keys: host, port, token, username, password, realm, +# ssl_reject_unauthorized, ssl_ca, ssl_cert, ssl_key, timeout, priority +# +# @param ssl_ca_source +# Source URL for SSL CA certificate (supports file://, https://, or local path). +# Deploys to path specified in settings['ssl_ca'] +# +# @param ssl_cert_source +# Source URL for SSL certificate (supports file://, https://, or local path). +# Deploys to path specified in settings['ssl_cert'] +# +# @param ssl_key_source +# Source URL for SSL private key (supports file://, https://, or local path). +# Deploys to path specified in settings['ssl_key'] +# +# @example Basic usage with token authentication (recommended) +# class { 'pabawi::integrations::proxmox': +# settings => { +# 'host' => 'proxmox.example.com', +# 'port' => 8006, +# 'token' => 'user@pam!tokenid=token-value', +# }, +# } +# +# @example With username/password and SSL certificates +# class { 'pabawi::integrations::proxmox': +# settings => { +# 'host' => 'proxmox.example.com', +# 'port' => 8006, +# 'username' => 'root@pam', +# 'password' => 'secret', +# 'realm' => 'pam', +# 'ssl_reject_unauthorized' => true, +# 'ssl_ca' => '/opt/pabawi/certs/proxmox/ca.pem', +# 'ssl_cert' => '/opt/pabawi/certs/proxmox/cert.pem', +# 'ssl_key' => '/opt/pabawi/certs/proxmox/key.pem', +# 'timeout' => 30000, +# 'priority' => 7, +# }, +# ssl_ca_source => 'file:///etc/ssl/certs/proxmox-ca.pem', +# ssl_cert_source => 'file:///etc/ssl/certs/proxmox-cert.pem', +# ssl_key_source => 'file:///etc/ssl/private/proxmox-key.pem', +# } +# +# @example Via Hiera +# pabawi::integrations::proxmox::enabled: true +# pabawi::integrations::proxmox::settings: +# host: 'proxmox.example.com' +# port: 8006 +# token: 'user@pam!tokenid=token-value' +# ssl_reject_unauthorized: true +# timeout: 30000 +# +class pabawi::integrations::proxmox ( + Boolean $enabled = true, + Hash $settings = {}, + Optional[String[1]] $ssl_ca_source = undef, + Optional[String[1]] $ssl_cert_source = undef, + Optional[String[1]] $ssl_key_source = undef, +) { + # Merge sane defaults for SSL paths + $_default_settings = { + 'ssl_ca' => '/opt/pabawi/certs/proxmox/ca.pem', + 'ssl_cert' => '/opt/pabawi/certs/proxmox/cert.pem', + 'ssl_key' => '/opt/pabawi/certs/proxmox/key.pem', + } + $_settings = $_default_settings + $settings + + # Deploy SSL certificates if sources are provided + if $ssl_ca_source { + $ssl_ca_path = $_settings['ssl_ca'] + $ssl_ca_dir = dirname($ssl_ca_path) + $ssl_ca_parent = dirname($ssl_ca_dir) + $ssl_ca_mode = '0644' + ensure_resource('file', $ssl_ca_parent, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + ensure_resource('file', $ssl_ca_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755', require => File[$ssl_ca_parent] }) + + # Handle file:// URLs + if $ssl_ca_source =~ /^file:\/\/(.+)$/ { + file { $ssl_ca_path: + ensure => file, + source => regsubst($ssl_ca_source, '^file://', ''), + mode => $ssl_ca_mode, + owner => 'root', + group => 'root', + require => File[$ssl_ca_dir], + } + } + # Handle https:// URLs + elsif $ssl_ca_source =~ /^https:\/\/.+$/ { + exec { 'download_proxmox_ssl_ca': + command => "curl -sL -o ${ssl_ca_path} ${ssl_ca_source}", + path => ['/usr/bin', '/bin'], + creates => $ssl_ca_path, + require => File[$ssl_ca_dir], + } + -> file { $ssl_ca_path: + ensure => file, + mode => $ssl_ca_mode, + owner => 'root', + group => 'root', + } + } + # Handle direct file paths + else { + file { $ssl_ca_path: + ensure => file, + source => $ssl_ca_source, + mode => $ssl_ca_mode, + owner => 'root', + group => 'root', + require => File[$ssl_ca_dir], + } + } + } + + if $ssl_cert_source { + $ssl_cert_path = $_settings['ssl_cert'] + $ssl_cert_dir = dirname($ssl_cert_path) + $ssl_cert_parent = dirname($ssl_cert_dir) + $ssl_cert_mode = '0644' + ensure_resource('file', $ssl_cert_parent, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + ensure_resource('file', $ssl_cert_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755', require => File[$ssl_cert_parent] }) + + # Handle file:// URLs + if $ssl_cert_source =~ /^file:\/\/(.+)$/ { + file { $ssl_cert_path: + ensure => file, + source => regsubst($ssl_cert_source, '^file://', ''), + mode => $ssl_cert_mode, + owner => 'root', + group => 'root', + require => File[$ssl_cert_dir], + } + } + # Handle https:// URLs + elsif $ssl_cert_source =~ /^https:\/\/.+$/ { + exec { 'download_proxmox_ssl_cert': + command => "curl -sL -o ${ssl_cert_path} ${ssl_cert_source}", + path => ['/usr/bin', '/bin'], + creates => $ssl_cert_path, + require => File[$ssl_cert_dir], + } + -> file { $ssl_cert_path: + ensure => file, + mode => $ssl_cert_mode, + owner => 'root', + group => 'root', + } + } + # Handle direct file paths + else { + file { $ssl_cert_path: + ensure => file, + source => $ssl_cert_source, + mode => $ssl_cert_mode, + owner => 'root', + group => 'root', + require => File[$ssl_cert_dir], + } + } + } + + if $ssl_key_source { + $ssl_key_path = $_settings['ssl_key'] + $ssl_key_dir = dirname($ssl_key_path) + $ssl_key_parent = dirname($ssl_key_dir) + $ssl_key_mode = '0600' + ensure_resource('file', $ssl_key_parent, { ensure => directory, owner => 'root', group => 'root', mode => '0755' }) + ensure_resource('file', $ssl_key_dir, { ensure => directory, owner => 'root', group => 'root', mode => '0755', require => File[$ssl_key_parent] }) + + # Handle file:// URLs + if $ssl_key_source =~ /^file:\/\/(.+)$/ { + file { $ssl_key_path: + ensure => file, + source => regsubst($ssl_key_source, '^file://', ''), + mode => $ssl_key_mode, + owner => 'root', + group => 'root', + require => File[$ssl_key_dir], + } + } + # Handle https:// URLs + elsif $ssl_key_source =~ /^https:\/\/.+$/ { + exec { 'download_proxmox_ssl_key': + command => "curl -sL -o ${ssl_key_path} ${ssl_key_source}", + path => ['/usr/bin', '/bin'], + creates => $ssl_key_path, + require => File[$ssl_key_dir], + } + -> file { $ssl_key_path: + ensure => file, + mode => $ssl_key_mode, + owner => 'root', + group => 'root', + } + } + # Handle direct file paths + else { + file { $ssl_key_path: + ensure => file, + source => $ssl_key_source, + mode => $ssl_key_mode, + owner => 'root', + group => 'root', + require => File[$ssl_key_dir], + } + } + } + + # Transform settings hash values to .env format + # Arrays -> JSON, Booleans -> lowercase strings, Integers -> strings, undef/empty -> 'not-set' + $env_vars = $_settings.reduce({}) |$memo, $pair| { + $key = $pair[0] + $value = $pair[1] + + # Transform value based on type + $transformed = $value ? { + Array => inline_template('[<%= @value.map { |v| "\"#{v}\"" }.join(",") %>]'), + Boolean => $value ? { true => 'true', false => 'false' }, + Integer => String($value), + String => $value, + Undef => 'not-set', + default => pick($value, 'not-set'), + } + + $env_key = upcase($key) + $memo + { "PROXMOX_${env_key}" => $transformed } + } + + # Build environment variable lines + $env_lines = $env_vars.map |$key, $value| { + "${key}=${value}" + }.join("\n") + + # Add configuration to .env file via concat fragment + concat::fragment { 'pabawi_env_proxmox': + target => 'pabawi_env_file', + content => @("EOT"), + # Proxmox Integration + PROXMOX_ENABLED=${enabled} + ${env_lines} + | EOT + order => '26', + } +} diff --git a/manifests/integrations/puppetdb.pp b/manifests/integrations/puppetdb.pp index 8873653..6d931f7 100644 --- a/manifests/integrations/puppetdb.pp +++ b/manifests/integrations/puppetdb.pp @@ -56,23 +56,17 @@ Optional[String[1]] $ssl_cert_source = undef, Optional[String[1]] $ssl_key_source = undef, ) { - # Validate required parameters when integration is enabled - if $enabled { - # Source-path consistency validation - if $ssl_ca_source and !$settings['ssl_ca'] { - fail('pabawi::integrations::puppetdb: settings[\'ssl_ca\'] is required when ssl_ca_source is provided') - } - if $ssl_cert_source and !$settings['ssl_cert'] { - fail('pabawi::integrations::puppetdb: settings[\'ssl_cert\'] is required when ssl_cert_source is provided') - } - if $ssl_key_source and !$settings['ssl_key'] { - fail('pabawi::integrations::puppetdb: settings[\'ssl_key\'] is required when ssl_key_source is provided') - } + # Merge sane defaults for local paths when source is provided but path is not + $_default_settings = { + 'ssl_ca' => '/opt/pabawi/certs/puppetdb/ca.pem', + 'ssl_cert' => '/opt/pabawi/certs/puppetdb/cert.pem', + 'ssl_key' => '/opt/pabawi/certs/puppetdb/key.pem', } + $_settings = $_default_settings + $settings # Deploy SSL certificates if sources are provided if $ssl_ca_source { - $ssl_ca_path = $settings['ssl_ca'] + $ssl_ca_path = $_settings['ssl_ca'] $ssl_ca_dir = dirname($ssl_ca_path) $ssl_ca_parent = dirname($ssl_ca_dir) $ssl_ca_mode = '0644' @@ -119,7 +113,7 @@ } if $ssl_cert_source { - $ssl_cert_path = $settings['ssl_cert'] + $ssl_cert_path = $_settings['ssl_cert'] $ssl_cert_dir = dirname($ssl_cert_path) $ssl_cert_parent = dirname($ssl_cert_dir) $ssl_cert_mode = '0644' @@ -166,7 +160,7 @@ } if $ssl_key_source { - $ssl_key_path = $settings['ssl_key'] + $ssl_key_path = $_settings['ssl_key'] $ssl_key_dir = dirname($ssl_key_path) $ssl_key_parent = dirname($ssl_key_dir) $ssl_key_mode = '0600' @@ -214,7 +208,7 @@ # Transform settings hash values to .env format # Arrays -> JSON, Booleans -> lowercase strings, Integers -> strings, undef/empty -> 'not-set' - $env_vars = $settings.reduce({}) |$memo, $pair| { + $env_vars = $_settings.reduce({}) |$memo, $pair| { $key = $pair[0] $value = $pair[1] diff --git a/manifests/integrations/puppetserver.pp b/manifests/integrations/puppetserver.pp index 9cddbfe..b12f251 100644 --- a/manifests/integrations/puppetserver.pp +++ b/manifests/integrations/puppetserver.pp @@ -62,20 +62,16 @@ Optional[String[1]] $ssl_cert_source = undef, Optional[String[1]] $ssl_key_source = undef, ) { - # Validate required parameters when integration is enabled - if $enabled { - # Source-path consistency validation - if $ssl_ca_source and !$settings['ssl_ca'] { - fail('pabawi::integrations::puppetserver: settings[\'ssl_ca\'] is required when ssl_ca_source is provided') - } - if $ssl_cert_source and !$settings['ssl_cert'] { - fail('pabawi::integrations::puppetserver: settings[\'ssl_cert\'] is required when ssl_cert_source is provided') - } - if $ssl_key_source and !$settings['ssl_key'] { - fail('pabawi::integrations::puppetserver: settings[\'ssl_key\'] is required when ssl_key_source is provided') - } + # Merge sane defaults for local paths when source is provided but path is not + $_default_settings = { + 'ssl_ca' => '/opt/pabawi/certs/puppetserver/ca.pem', + 'ssl_cert' => '/opt/pabawi/certs/puppetserver/cert.pem', + 'ssl_key' => '/opt/pabawi/certs/puppetserver/key.pem', + } + $_settings = $_default_settings + $settings - # SSL configuration validation - all three SSL sources should be provided together + # Validate that SSL sources are provided together when any is specified + if $enabled { $ssl_sources_provided = [$ssl_ca_source, $ssl_cert_source, $ssl_key_source].filter |$val| { $val != undef } if $ssl_sources_provided.length > 0 and $ssl_sources_provided.length < 3 { fail('pabawi::integrations::puppetserver: When SSL certificates are used, all three SSL sources (ssl_ca_source, ssl_cert_source, ssl_key_source) must be provided together') @@ -84,7 +80,7 @@ # Deploy SSL certificates if sources are provided if $ssl_ca_source { - $ssl_ca_path = $settings['ssl_ca'] + $ssl_ca_path = $_settings['ssl_ca'] $ssl_ca_dir = dirname($ssl_ca_path) $ssl_ca_parent = dirname($ssl_ca_dir) $ssl_ca_mode = '0644' @@ -131,7 +127,7 @@ } if $ssl_cert_source { - $ssl_cert_path = $settings['ssl_cert'] + $ssl_cert_path = $_settings['ssl_cert'] $ssl_cert_dir = dirname($ssl_cert_path) $ssl_cert_parent = dirname($ssl_cert_dir) $ssl_cert_mode = '0644' @@ -178,7 +174,7 @@ } if $ssl_key_source { - $ssl_key_path = $settings['ssl_key'] + $ssl_key_path = $_settings['ssl_key'] $ssl_key_dir = dirname($ssl_key_path) $ssl_key_parent = dirname($ssl_key_dir) $ssl_key_mode = '0600' @@ -226,7 +222,7 @@ # Transform settings hash values to .env format # Arrays -> JSON, Booleans -> lowercase strings, Integers -> strings, undef/empty -> 'not-set' - $env_vars = $settings.reduce({}) |$memo, $pair| { + $env_vars = $_settings.reduce({}) |$memo, $pair| { $key = $pair[0] $value = $pair[1] diff --git a/metadata.json b/metadata.json index 20d2251..7aec553 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "example42-pabawi", - "version": "0.2.0", + "version": "1.0.0", "author": "Pabawi Team", "summary": "Puppet module for installing and configuring Pabawi application", "license": "Apache-2.0", diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index ebbf5bb..b8a1192 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -106,14 +106,14 @@ context 'with custom integrations array' do let(:params) do { - integrations: ['terraform'], + integrations: ['proxmox'], } end it { is_expected.to compile.with_all_deps } it 'includes listed integration classes' do - is_expected.to contain_class('pabawi::integrations::terraform') + is_expected.to contain_class('pabawi::integrations::proxmox') end it 'does not include unlisted integration classes' do @@ -122,10 +122,38 @@ end + context 'with aws integration' do + let(:params) do + { + integrations: ['aws'], + } + end + + it { is_expected.to compile.with_all_deps } + + it 'includes aws integration class' do + is_expected.to contain_class('pabawi::integrations::aws') + end + end + + context 'with ssh integration' do + let(:params) do + { + integrations: ['ssh'], + } + end + + it { is_expected.to compile.with_all_deps } + + it 'includes ssh integration class' do + is_expected.to contain_class('pabawi::integrations::ssh') + end + end + context 'with multiple integrations' do let(:params) do { - integrations: ['bolt', 'puppetdb', 'custom'], + integrations: ['bolt', 'puppetdb', 'ssh', 'proxmox', 'aws'], } end @@ -134,7 +162,9 @@ it 'includes all listed integration classes' do is_expected.to contain_class('pabawi::integrations::bolt') is_expected.to contain_class('pabawi::integrations::puppetdb') - is_expected.to contain_class('pabawi::integrations::custom') + is_expected.to contain_class('pabawi::integrations::ssh') + is_expected.to contain_class('pabawi::integrations::proxmox') + is_expected.to contain_class('pabawi::integrations::aws') end end From be3d0423a393f5cf29b22d125d1653144c8c198a Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Sun, 12 Apr 2026 12:24:29 +0200 Subject: [PATCH 09/13] doc CHANGELOG --- CHANGELOG.md | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..4c0158c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,118 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.0.0] - 2025-04-12 + +### Added + +- **Proxmox integration** (`pabawi::integrations::proxmox`) — Proxmox VE + support for VM/LXC provisioning and lifecycle management. Token and + username/password authentication, SSL certificate deployment via + `ssl_ca_source`, `ssl_cert_source`, `ssl_key_source` parameters. +- **AWS integration** (`pabawi::integrations::aws`) — AWS EC2 inventory + discovery, lifecycle actions (start/stop/reboot/terminate), and instance + provisioning. Supports explicit access keys, named profiles, and the + default AWS credential chain. +- **SSH integration** added to the `integrations` enum — the manifest existed + since 0.2.0 but was not accepted by the `Enum` type on `pabawi::integrations`. +- New example `examples/ssh_ansible_proxmox.pp` — agentless infrastructure + setup with SSH, Ansible, and Proxmox. +- New example `examples/hiera_full_integrations.yaml` — complete Hiera data + covering all eight integrations. +- SSH, Proxmox, and AWS integration reference sections in README with + parameter tables, Hiera examples, and generated `.env` samples. + +### Changed + +- **Docker installation refactored to systemd** — `pabawi::install::docker` + now runs the container as a native systemd service via `docker run`, + removing the dependency on the `puppetlabs/docker` module. New parameters: + `manage_docker`, `docker_package`, `bind_address`, `database_host_dir`, + `container_uid`, `container_gid`, `command_whitelist`, + `command_whitelist_allow_all`, `docker_extra_args`. +- **NPM installation** — added `bind_address` parameter that defaults to + `127.0.0.1` when `pabawi::proxy_manage` is true, `0.0.0.0` otherwise. +- `pabawi::integrations` enum expanded from + `['puppetdb','puppetserver','hiera','bolt','ansible']` to + `['puppetdb','puppetserver','hiera','bolt','ansible','ssh','proxmox','aws']`. +- Integration SSL certificate deployment (PuppetDB, Puppet Server) refactored + to use `ensure_resource` for directory management, avoiding duplicate + resource declarations when multiple integrations share parent directories. +- `examples/full_integrations.pp` slimmed to a minimal Puppet-centric setup + (Bolt, PuppetDB, Puppet Server, Hiera). Full verbose examples moved to + `hiera_full_integrations.yaml`. +- `examples/docker_custom_ssl.pp` updated to use `v1.0.0` image and proper + `auth_enabled`/`jwt_secret` parameters. +- README rewritten: added SSH/Proxmox/AWS integration reference, updated all + inline examples to use current parameter names and default paths, replaced + large inline Hiera examples with pointers to `examples/` directory. +- Hiera defaults (`data/common.yaml`) updated with commented examples for all + eight integrations. +- Design document updated with Proxmox (Component 8), SSH (Component 7), and + AWS (Component 9) sections; architecture diagram expanded. +- Spec tests updated to cover `ssh`, `proxmox`, and `aws` integration values. + +### Fixed + +- `.env` concat fragment ordering now correctly sequences all integrations: + Bolt (20), PuppetDB (21), Puppet Server (22), Hiera (23), Ansible (24), + SSH (25), Proxmox (26), AWS (27). +- Fixed service exec path in NPM installation (contributed by @tam116 in #9). + +### Removed + +- `puppetlabs/docker` is no longer a required dependency — Docker installation + uses direct `docker run` via systemd instead. + +## [0.2.0] - 2025-02-15 + +### Changed + +- Refactored all integrations to use a `settings` hash parameter instead of + individual parameters, providing a uniform interface across integrations. +- Updated integration configuration examples and documentation to use the new + settings hash pattern. +- Updated module dependencies version ranges. + +## [0.1.1] - 2025-01-20 + +### Changed + +- Updated supported OS matrix (Ubuntu 24.04, Debian 13, RHEL 8/9/10). +- Upgraded `puppetlabs_spec_helper` dependency. + +### Fixed + +- Various Gemfile dependency fixes for CI compatibility. + +## [0.1.0] - 2025-01-10 + +### Added + +- Initial release. +- Core module with `pabawi::init` entry point, proxy management, and + installation management. +- NPM installation method (`pabawi::install::npm`). +- Docker installation method (`pabawi::install::docker`). +- Nginx reverse proxy with SSL (`pabawi::proxy::nginx`). +- Bolt integration (`pabawi::integrations::bolt`). +- PuppetDB integration (`pabawi::integrations::puppetdb`). +- Puppet Server integration (`pabawi::integrations::puppetserver`). +- Hiera integration (`pabawi::integrations::hiera`). +- Ansible integration (`pabawi::integrations::ansible`). +- SSH integration (`pabawi::integrations::ssh`). +- Hiera-driven configuration with `data/common.yaml` defaults. +- `Pabawi::Config`, `Pabawi::SSL::Config`, `Pabawi::Integration::Config` types. +- `pabawi::validate_configuration` function. +- rspec-puppet spec tests. +- GitHub Actions CI/CD workflows. +- Usage examples in `examples/`. + +[1.0.0]: https://github.com/example42/puppet-pabawi/compare/0.2.0...1.0.0 +[0.2.0]: https://github.com/example42/puppet-pabawi/compare/0.1.1...0.2.0 +[0.1.1]: https://github.com/example42/puppet-pabawi/compare/0.1.0...0.1.1 +[0.1.0]: https://github.com/example42/puppet-pabawi/releases/tag/0.1.0 From 74899acbcc0af36c9ca1097f69bd6d81b147c09e Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Sun, 12 Apr 2026 12:44:34 +0200 Subject: [PATCH 10/13] refactor(puppet-pabawi): simplify integrations from flags to array - Replace individual boolean flags (bolt_enable, puppetdb_enable) with single integrations array parameter - Update Pabawi::Config type to use Array[String[1]] instead of Hash[String, Boolean] for integrations - Simplify integration processing logic to iterate through array instead of checking multiple flags - Refactor design documentation to reflect new integrations loop architecture - Update validate_configuration function to validate integrations array format - Standardize code formatting and alignment across manifests and examples - Improve type safety by using String[1] constraints for class name parameters - Streamline integration initialization sequence diagram in documentation --- .kiro/puppet-pabawi-module/design.md | 88 +++++++++------------------- examples/docker_custom_ssl.pp | 6 +- functions/validate_configuration.pp | 60 +++++++++---------- manifests/install/docker.pp | 20 +++++-- manifests/install/npm.pp | 8 +-- manifests/integrations/ssh.pp | 41 +++++++------ manifests/proxy/nginx.pp | 28 +++++---- spec/classes/init_spec.rb | 4 +- types/config.pp | 12 ++-- 9 files changed, 119 insertions(+), 148 deletions(-) diff --git a/.kiro/puppet-pabawi-module/design.md b/.kiro/puppet-pabawi-module/design.md index 0af8b28..e871679 100644 --- a/.kiro/puppet-pabawi-module/design.md +++ b/.kiro/puppet-pabawi-module/design.md @@ -12,7 +12,7 @@ The module follows Puppet best practices with Hiera-driven configuration, allowi graph TD A[pabawi::init] --> B{proxy_manage?} A --> C{install_manage?} - A --> D[Integration Manager] + A --> D[Integrations Loop] B -->|true| E[Dynamic Proxy Class] E --> F[pabawi::proxy::nginx] @@ -22,18 +22,14 @@ graph TD H --> I[pabawi::install::npm] H --> J[pabawi::install::docker] - D --> K{bolt_enable?} - D --> L{puppetdb_enable?} - D --> M[Other Integrations] - - K -->|true| N[pabawi::integrations::bolt] - L -->|true| O[pabawi::integrations::puppetdb] - M --> P[pabawi::integrations::puppetserver] - M --> Q2[pabawi::integrations::hiera] - M --> R2[pabawi::integrations::ansible] - M --> S2[pabawi::integrations::ssh] - M --> T2[pabawi::integrations::proxmox] - M --> U2[pabawi::integrations::aws] + D --> N[pabawi::integrations::bolt] + D --> O[pabawi::integrations::puppetdb] + D --> P[pabawi::integrations::puppetserver] + D --> Q2[pabawi::integrations::hiera] + D --> R2[pabawi::integrations::ansible] + D --> S2[pabawi::integrations::ssh] + D --> T2[pabawi::integrations::proxmox] + D --> U2[pabawi::integrations::aws] F --> Q[SSL Configuration] Q --> R[Self-Signed Certs] @@ -68,14 +64,10 @@ sequenceDiagram Install->>Install: Install pabawi (npm/docker) end - Init->>Integrations: Process integration flags - - alt bolt_enable == true - Integrations->>Integrations: Configure Bolt integration - end + Init->>Integrations: Process integrations array - alt puppetdb_enable == true - Integrations->>Integrations: Configure PuppetDB integration + loop For each integration in array + Integrations->>Integrations: include pabawi::integrations:: end Integrations-->>Init: Integrations configured @@ -122,12 +114,10 @@ sequenceDiagram ```puppet class pabawi ( Boolean $proxy_manage = true, - String $proxy_class = 'pabawi::proxy::nginx', + String[1] $proxy_class = 'pabawi::proxy::nginx', Boolean $install_manage = true, - String $install_class = 'pabawi::install::npm', - Boolean $bolt_enable = false, - Boolean $puppetdb_enable = false, - Hash[String, Boolean] $integrations = {}, + String[1] $install_class = 'pabawi::install::npm', + Array[Enum['puppetdb', 'puppetserver', 'hiera', 'bolt', 'ansible', 'ssh', 'proxmox', 'aws']] $integrations = [], ) { # Class implementation } @@ -137,13 +127,13 @@ class pabawi ( - Load and validate Hiera configuration parameters - Conditionally include proxy class based on proxy_manage flag - Conditionally include installation class based on install_manage flag -- Iterate through integration flags and include appropriate integration classes +- Iterate through integrations array and include appropriate integration classes - Ensure proper ordering and dependencies between components **Validation Rules**: - proxy_class must be a valid Puppet class name - install_class must be a valid Puppet class name -- Integration flags must be boolean values +- integrations must contain only valid integration names ### Component 2: Nginx Proxy Class (pabawi::proxy::nginx) @@ -337,20 +327,18 @@ class pabawi::integrations::aws ( ```puppet type Pabawi::Config = Struct[{ - proxy_manage => Boolean, - proxy_class => String[1], - install_manage => Boolean, - install_class => String[1], - bolt_enable => Boolean, - puppetdb_enable => Boolean, - integrations => Hash[String[1], Boolean], + proxy_manage => Boolean, + proxy_class => String[1], + install_manage => Boolean, + install_class => String[1], + integrations => Array[String[1]], }] ``` **Validation Rules**: - All class names must be non-empty strings - Boolean flags must be explicitly true or false -- Integration hash keys must be non-empty strings +- integrations must be an array of valid integration names ### Model 2: SSL Configuration @@ -431,32 +419,12 @@ INPUT: config of type Pabawi::Config OUTPUT: configured integrations BEGIN - // Process built-in integrations - IF config.bolt_enable = true THEN - ASSERT config.bolt_project_path is defined - includeClass('pabawi::integrations::bolt') - END IF - - IF config.puppetdb_enable = true THEN - ASSERT config.puppetdb_server_url is defined - includeClass('pabawi::integrations::puppetdb') - END IF - - // Process custom integrations from hash - FOR each (name, enabled) IN config.integrations DO - ASSERT enabled is Boolean - - IF enabled = true THEN - integrationClass ← "pabawi::integrations::" + name - - IF classExists(integrationClass) THEN - includeClass(integrationClass) - ELSE - logWarning("Integration class not found: " + integrationClass) - END IF - END IF + // Process integrations from array + FOR each name IN config.integrations.unique DO + integrationClass ← "pabawi::integrations::" + name + includeClass(integrationClass) END FOR - + RETURN success END ``` diff --git a/examples/docker_custom_ssl.pp b/examples/docker_custom_ssl.pp index 4eb8259..d65bb57 100644 --- a/examples/docker_custom_ssl.pp +++ b/examples/docker_custom_ssl.pp @@ -14,7 +14,7 @@ } class { 'pabawi::install::docker': - image => 'example42/pabawi:v1.0.0', - auth_enabled => true, - jwt_secret => 'change-this-to-a-secure-random-string', + image => 'example42/pabawi:v1.0.0', + auth_enabled => true, + jwt_secret => 'change-this-to-a-secure-random-string', } diff --git a/functions/validate_configuration.pp b/functions/validate_configuration.pp index b6ae6fc..6a08f1e 100644 --- a/functions/validate_configuration.pp +++ b/functions/validate_configuration.pp @@ -11,82 +11,78 @@ # # @example Validate a configuration # $config = { -# 'proxy_manage' => true, -# 'proxy_class' => 'pabawi::proxy::nginx', +# 'proxy_manage' => true, +# 'proxy_class' => 'pabawi::proxy::nginx', +# 'install_manage' => true, +# 'install_class' => 'pabawi::install::npm', +# 'integrations' => ['bolt', 'puppetdb'], # } # $valid = pabawi::validate_configuration($config) # function pabawi::validate_configuration(Hash $config) >> Boolean { # Check for required keys $required_keys = ['proxy_manage', 'install_manage'] - + $required_keys.each |$key| { unless $config[$key] =~ NotUndef { fail("Configuration missing required key: ${key}") } } - + # Validate proxy_manage is boolean unless $config['proxy_manage'] =~ Boolean { fail("proxy_manage must be a Boolean, got: ${config['proxy_manage']}") } - + # Validate install_manage is boolean unless $config['install_manage'] =~ Boolean { fail("install_manage must be a Boolean, got: ${config['install_manage']}") } - + # If proxy is managed, validate proxy_class if $config['proxy_manage'] { if $config['proxy_class'] { unless $config['proxy_class'] =~ String[1] { - fail("proxy_class must be a non-empty String") + fail('proxy_class must be a non-empty String') } - + unless $config['proxy_class'] =~ /^[a-z][a-z0-9_]*(::[a-z][a-z0-9_]*)*$/ { fail("proxy_class must be a valid Puppet class name: ${config['proxy_class']}") } } } - + # If installation is managed, validate install_class if $config['install_manage'] { if $config['install_class'] { unless $config['install_class'] =~ String[1] { - fail("install_class must be a non-empty String") + fail('install_class must be a non-empty String') } - + unless $config['install_class'] =~ /^[a-z][a-z0-9_]*(::[a-z][a-z0-9_]*)*$/ { fail("install_class must be a valid Puppet class name: ${config['install_class']}") } } } - - # Validate integration flags if present - if $config['bolt_enable'] { - unless $config['bolt_enable'] =~ Boolean { - fail("bolt_enable must be a Boolean") - } - } - - if $config['puppetdb_enable'] { - unless $config['puppetdb_enable'] =~ Boolean { - fail("puppetdb_enable must be a Boolean") - } - } - + + # Validate integrations if present if $config['integrations'] { - unless $config['integrations'] =~ Hash { - fail("integrations must be a Hash") + unless $config['integrations'] =~ Array { + fail('integrations must be an Array') } - - $config['integrations'].each |$name, $enabled| { - unless $enabled =~ Boolean { - fail("Integration '${name}' must have a Boolean value") + + $valid_integrations = [ + 'puppetdb', 'puppetserver', 'hiera', + 'bolt', 'ansible', 'ssh', 'proxmox', 'aws', + ] + + $config['integrations'].each |$name| { + unless $name in $valid_integrations { + fail("Unknown integration: '${name}'. Valid: ${valid_integrations.join(', ')}") } } } - + # All validations passed true } diff --git a/manifests/install/docker.pp b/manifests/install/docker.pp index 12bdfb0..ce0070d 100644 --- a/manifests/install/docker.pp +++ b/manifests/install/docker.pp @@ -104,7 +104,8 @@ default => '0.0.0.0', }, Boolean $auto_restart = true, - Stdlib::Absolutepath $install_dir = '/opt/pabawi', String[1] $log_level = 'info', + Stdlib::Absolutepath $install_dir = '/opt/pabawi', + String[1] $log_level = 'info', Boolean $auth_enabled = false, String[1] $jwt_secret = fqdn_rand_string(64), Stdlib::Absolutepath $database_path = '/opt/pabawi/data/pabawi.db', @@ -203,14 +204,21 @@ ].filter |$arg| { $arg != '' }.join(' ') # Pull the image before starting the service + $_pull_require = $manage_docker ? { + true => Service['docker'], + default => [], + } + exec { "docker_pull_${container_name}": command => "${docker_bin} pull ${image}", path => ['/usr/bin', '/bin'], unless => "${docker_bin} image inspect ${image} > /dev/null 2>&1", - require => $manage_docker ? { - true => Service['docker'], - default => [], - }, + require => $_pull_require, + } + + $_restart_policy = $auto_restart ? { + true => 'on-failure', + default => 'no', } # Create systemd service file @@ -232,7 +240,7 @@ ExecStartPre=-${docker_bin} rm ${container_name} ExecStart=${docker_bin} run ${docker_run_args} ExecStop=${docker_bin} stop ${container_name} - Restart=${auto_restart ? { true => 'on-failure', default => 'no' }} + Restart=${_restart_policy} RestartSec=10 StandardOutput=journal StandardError=journal diff --git a/manifests/install/npm.pp b/manifests/install/npm.pp index 4dc53df..21e19d4 100644 --- a/manifests/install/npm.pp +++ b/manifests/install/npm.pp @@ -125,10 +125,10 @@ # Create .env file using concat $env_file_path = "${install_dir}/backend/.env" concat { 'pabawi_env_file': - path => $env_file_path, - owner => $user, - group => $group, - mode => '0600', + path => $env_file_path, + owner => $user, + group => $group, + mode => '0600', } # Base configuration fragment diff --git a/manifests/integrations/ssh.pp b/manifests/integrations/ssh.pp index c8d6f4f..6640614 100644 --- a/manifests/integrations/ssh.pp +++ b/manifests/integrations/ssh.pp @@ -1,42 +1,41 @@ # @summary Configure Pabawi integration with SSH # # This class manages the integration between Pabawi and SSH, -# including SSH connection configuration and .env file settings. +# writing connection pool and execution defaults to the .env file. # # @param enabled # Whether the integration is enabled (sets SSH_ENABLED in .env) # # @param settings -# Hash of SSH configuration settings that will be written to .env file -# with SSH_ prefix. Supported keys include: -# - host: SSH host to connect to -# - port: SSH port (default 22) -# - username: SSH username -# - private_key_path: Path to SSH private key -# - timeout: Connection timeout in milliseconds -# - known_hosts_path: Path to known_hosts file +# Hash of SSH configuration settings written to .env with SSH_ prefix. +# Supported keys: config_path, default_user, default_port, default_key, +# host_key_check, connection_timeout, command_timeout, max_connections, +# max_connections_per_host, idle_timeout, concurrency_limit, +# sudo_enabled, sudo_command, sudo_passwordless, sudo_user, priority # # @example Basic usage # class { 'pabawi::integrations::ssh': -# enabled => true, # settings => { -# 'host' => 'remote.example.com', -# 'port' => 22, -# 'username' => 'automation', -# 'private_key_path' => '/opt/pabawi/ssh/id_rsa', -# 'timeout' => 30000, +# 'default_user' => 'automation', +# 'default_port' => 22, +# 'default_key' => '/opt/pabawi/ssh/id_ed25519', +# 'host_key_check' => true, +# 'connection_timeout' => 30, +# 'command_timeout' => 300, +# 'max_connections' => 50, +# 'concurrency_limit' => 10, # }, # } # # @example Via Hiera # pabawi::integrations::ssh::enabled: true # pabawi::integrations::ssh::settings: -# host: 'remote.example.com' -# port: 22 -# username: 'automation' -# private_key_path: '/opt/pabawi/ssh/id_rsa' -# timeout: 30000 -# known_hosts_path: '/opt/pabawi/ssh/known_hosts' +# default_user: 'automation' +# default_port: 22 +# default_key: '/opt/pabawi/ssh/id_ed25519' +# host_key_check: true +# connection_timeout: 30 +# max_connections: 50 # class pabawi::integrations::ssh ( Boolean $enabled = true, diff --git a/manifests/proxy/nginx.pp b/manifests/proxy/nginx.pp index aae5a98..823caae 100644 --- a/manifests/proxy/nginx.pp +++ b/manifests/proxy/nginx.pp @@ -78,13 +78,15 @@ } # Manage nginx service + $_nginx_service_require = $manage_package ? { + true => Package['nginx'], + default => undef, + } + service { 'nginx': - ensure => running, - enable => true, - require => $manage_package ? { - true => Package['nginx'], - default => undef, - }, + ensure => running, + enable => true, + require => $_nginx_service_require, } # Setup SSL if enabled @@ -181,6 +183,12 @@ $ssl_config_content = '' } + # Build require list for config file + $_config_file_require = $manage_package ? { + true => [File[$config_dir], Package['nginx']], + default => [File[$config_dir]], + } + file { $config_file: ensure => file, mode => '0644', @@ -194,13 +202,7 @@ 'command_whitelist' => $command_whitelist, 'command_whitelist_allow_all' => $command_whitelist_allow_all, }), - require => [ - File[$config_dir], - $manage_package ? { - true => Package['nginx'], - default => [], - }, - ], + require => $_config_file_require, notify => Service['nginx'], } diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index b8a1192..85844b0 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -171,12 +171,12 @@ context 'with invalid integration type' do let(:params) do { - integrations: [123], + integrations: ['nonexistent'], } end it 'fails with validation error' do - is_expected.to compile.and_raise_error(/expects an Array\[String/) + is_expected.to compile.and_raise_error(/expects.*Enum/) end end end diff --git a/types/config.pp b/types/config.pp index 8ce2121..3024b6f 100644 --- a/types/config.pp +++ b/types/config.pp @@ -1,11 +1,9 @@ # Pabawi::Config type # Defines the structure for main module configuration type Pabawi::Config = Struct[{ - proxy_manage => Boolean, - proxy_class => String[1], - install_manage => Boolean, - install_class => String[1], - bolt_enable => Boolean, - puppetdb_enable => Boolean, - integrations => Hash[String[1], Boolean], + proxy_manage => Boolean, + proxy_class => String[1], + install_manage => Boolean, + install_class => String[1], + integrations => Array[String[1]], }] From 9e7203b2bce965d62091834d1eb7953e64d5db08 Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Sun, 12 Apr 2026 12:53:01 +0200 Subject: [PATCH 11/13] ci: add git safe directory configuration to workflows - Add git ownership fix step to pr.yml validation job - Add git ownership fix step to pr.yml unit tests job - Add git ownership fix step to pr.yml Puppet 6 tests job - Add git ownership fix step to release.yml build job - Remove commented container configuration from unit tests job - Resolves git safe directory permission issues in containerized CI environments --- .github/workflows/pr.yml | 7 ++++++- .github/workflows/release.yml | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 725bc1e..3fde793 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -11,6 +11,8 @@ jobs: container: puppet/pdk:3.4.0.1.55.g4519dd0 steps: - uses: actions/checkout@v4 + - name: Fix git ownership + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - name: Run static validations run: /usr/local/bin/pdk bundle exec rake validate lint check env: @@ -20,10 +22,11 @@ jobs: name: 'Unit tests' runs-on: ubuntu-latest timeout-minutes: 60 -# container: puppet/puppet-dev-tools:4.x container: puppet/pdk:3.4.0.1.55.g4519dd0 steps: - uses: actions/checkout@v4 + - name: Fix git ownership + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - name: Run unit tests on Puppet 8 run: /usr/local/bin/pdk test unit --puppet-version=8 env: @@ -42,6 +45,8 @@ jobs: container: puppet/pdk:3.4.0.1.55.g4519dd0 steps: - uses: actions/checkout@v4 + - name: Fix git ownership + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - name: Run unit tests on Puppet 6 run: /usr/local/bin/pdk test unit --puppet-version=6 env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 19e4835..ddfc75b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,6 +18,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Fix git ownership + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - name: "PDK Build" uses: docker://puppet/pdk:3.4.0.1.55.g4519dd0 with: From 02e4db1d89b35e732260b0a62bb1b9867b8af71f Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Sun, 12 Apr 2026 12:57:29 +0200 Subject: [PATCH 12/13] Update manifests/integrations/puppetdb.pp Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- manifests/integrations/puppetdb.pp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/manifests/integrations/puppetdb.pp b/manifests/integrations/puppetdb.pp index 6d931f7..0fdec88 100644 --- a/manifests/integrations/puppetdb.pp +++ b/manifests/integrations/puppetdb.pp @@ -64,6 +64,9 @@ } $_settings = $_default_settings + $settings + if ($ssl_ca_source or $ssl_cert_source or $ssl_key_source) and !($ssl_ca_source and $ssl_cert_source and $ssl_key_source) { + fail('When configuring pabawi::integrations::puppetdb SSL sources, ssl_ca_source, ssl_cert_source, and ssl_key_source must all be set together.') + } # Deploy SSL certificates if sources are provided if $ssl_ca_source { $ssl_ca_path = $_settings['ssl_ca'] From 55ec886b626d4fc090d82bc4e9016423753586de Mon Sep 17 00:00:00 2001 From: Alessandro Franceschi Date: Sun, 12 Apr 2026 12:57:53 +0200 Subject: [PATCH 13/13] Update manifests/install/docker.pp Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- manifests/install/docker.pp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/manifests/install/docker.pp b/manifests/install/docker.pp index ce0070d..adfa6b2 100644 --- a/manifests/install/docker.pp +++ b/manifests/install/docker.pp @@ -43,7 +43,8 @@ # Whether authentication is enabled. # # @param jwt_secret -# JWT secret for authentication (required if auth_enabled is true). +# JWT secret for authentication. If not provided, a random secret is +# generated automatically. # # @param database_path # Path to application database file inside the container.