From 85ff76913ebdac40fefd805ab479298b97b915e7 Mon Sep 17 00:00:00 2001 From: Josh Partlow Date: Thu, 31 Aug 2023 17:23:54 -0700 Subject: [PATCH 1/3] (PE-36580) Add r10k_known_hosts to install plan Starting with PE 2023.3, updates to r10k libraries from PE-35980 changes in libgit2 now verify host keys. Because of this code manager now needs to be configured with known hosts public key information for the r10k remote host. Without this, PE will install but code manager will fail to deploy. This patch will fail the plan early if installing PE 2023.3+, with r10k_private_key (so using ssh protocol) and no r10k_known_hosts array. --- REFERENCE.md | 27 +++++++++++++++ plans/install.pp | 2 ++ plans/subplans/install.pp | 25 ++++++++++++-- spec/plans/subplans/install_spec.rb | 51 ++++++++++++++++++++++++++++- types/known_hosts.pp | 10 ++++++ 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 types/known_hosts.pp diff --git a/REFERENCE.md b/REFERENCE.md index 6ca9b911..7e748988 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -37,6 +37,7 @@ ### Data types +* [`Peadm::Known_hosts`](#Peadm--Known_hosts) * [`Peadm::Ldap_config`](#Peadm--Ldap_config) * [`Peadm::Pe_version`](#Peadm--Pe_version) * [`Peadm::Pem`](#Peadm--Pem) @@ -776,6 +777,23 @@ Data type: `TargetSpec` ## Data types +### `Peadm::Known_hosts` + +The Peadm::Known_hosts data type. + +Alias of + +```puppet +Array[Struct[ + 'title' => Optional[String[1]], + 'ensure' => Optional[Enum['present','absent']], + 'name' => String[1], + 'type' => String[1], + 'key' => String[1], + 'host_aliases' => Optional[Variant[String[1],Array[String[1]]]], + ]] +``` + ### `Peadm::Ldap_config` The Peadm::Ldap_config data type. @@ -1548,6 +1566,7 @@ The following parameters are available in the `peadm::install` plan: * [`r10k_remote`](#-peadm--install--r10k_remote) * [`r10k_private_key_file`](#-peadm--install--r10k_private_key_file) * [`r10k_private_key_content`](#-peadm--install--r10k_private_key_content) +* [`r10k_known_hosts`](#-peadm--install--r10k_known_hosts) * [`deploy_environment`](#-peadm--install--deploy_environment) * [`license_key_file`](#-peadm--install--license_key_file) * [`license_key_content`](#-peadm--install--license_key_content) @@ -1714,6 +1733,14 @@ Data type: `Optional[Peadm::Pem]` +Default value: `undef` + +##### `r10k_known_hosts` + +Data type: `Optional[Peadm::Known_hosts]` + + + Default value: `undef` ##### `deploy_environment` diff --git a/plans/install.pp b/plans/install.pp index aefb69dc..8eead8d9 100644 --- a/plans/install.pp +++ b/plans/install.pp @@ -53,6 +53,7 @@ Optional[String] $r10k_remote = undef, Optional[String] $r10k_private_key_file = undef, Optional[Peadm::Pem] $r10k_private_key_content = undef, + Optional[Peadm::Known_hosts] $r10k_known_hosts = undef, Optional[String] $deploy_environment = undef, # License Key @@ -94,6 +95,7 @@ r10k_remote => $r10k_remote, r10k_private_key_file => $r10k_private_key_file, r10k_private_key_content => $r10k_private_key_content, + r10k_known_hosts => $r10k_known_hosts, # License Key license_key_file => $license_key_file, diff --git a/plans/subplans/install.pp b/plans/subplans/install.pp index 168fe06c..74e3d957 100644 --- a/plans/subplans/install.pp +++ b/plans/subplans/install.pp @@ -11,6 +11,12 @@ # over to the primary at /etc/puppetlabs/puppetserver/ssh/id-control_repo.rsa # If the file does not exist the value will simply be supplied to the primary # +# @param r10k_known_hosts +# Puppet Enterprise 2023.3+ requires host key verification for the +# r10k_remote host. When setting \$r10k_private_key, you must also provide +# \$r10k_known_hosts information in the form of an array of hashes with +# 'name', 'type' and 'key' information for hostname, key-type and public key. +# # @param license_key_file # The license key to use with Puppet Enterprise. If this is a local file it # will be copied over to the MoM at /etc/puppetlabs/license.key @@ -50,6 +56,7 @@ Optional[String] $r10k_remote = undef, Optional[String] $r10k_private_key_file = undef, Optional[Peadm::Pem] $r10k_private_key_content = undef, + Optional[Peadm::Known_hosts] $r10k_known_hosts = undef, # License key Optional[String] $license_key_file = undef, @@ -125,7 +132,21 @@ # either be undef or else the key content to write. $r10k_private_key = peadm::file_or_content('r10k_private_key', $r10k_private_key_file, $r10k_private_key_content) - # Same for license key + # Determine whether r10k_known_hosts is required and has been provided. + $is_pe_2023_3_or_greater = (versioncmp($version, '2023.3.0') >= 0) + if (($is_pe_2023_3_or_greater) and + ($r10k_private_key =~ NotUndef) and + ($r10k_known_hosts =~ Undef)) { + fail_plan("In Puppet Enterprise 2023.3+ r10k 4.0 requires host key verification for the r10k_remote host. When setting \$r10k_private_key, you must also provide \$r10k_known_hosts information in the form of an array of hashes with 'name', 'type' and 'key' information for hostname, key-type and public key. Puppet Enterprise version: ${version}, r10k_known_hosts: ${r10k_known_hosts}") + } + $r10k_known_hosts_config = $r10k_known_hosts ? { + undef => {}, + default => { + 'puppet_enterprise::profile::master::r10k_known_hosts' => $r10k_known_hosts, + }, + } + + # Process user input for license key (same process as for r10k private key above). $license_key = peadm::file_or_content('license_key', $license_key_file, $license_key_content) $precheck_results = run_task('peadm::precheck', $all_targets) @@ -170,7 +191,7 @@ undef => undef, default => '/etc/puppetlabs/puppetserver/ssh/id-control_repo.rsa', }, - } + $puppetdb_database_temp_config + $pe_conf_data) + } + $r10k_known_hosts_config + $puppetdb_database_temp_config + $pe_conf_data) $primary_postgresql_pe_conf = peadm::generate_pe_conf({ 'console_admin_password' => 'not used', diff --git a/spec/plans/subplans/install_spec.rb b/spec/plans/subplans/install_spec.rb index 4a687adf..354f6d02 100644 --- a/spec/plans/subplans/install_spec.rb +++ b/spec/plans/subplans/install_spec.rb @@ -4,7 +4,7 @@ # Include the BoltSpec library functions include BoltSpec::Plans - it 'minimum variables to run' do + before(:each) do allow_any_task allow_any_plan allow_any_command @@ -35,7 +35,9 @@ # rubocop:enable AnyInstance ## ########## + end + it 'minimum variables to run' do params = { 'primary_host' => 'primary', 'console_password' => 'puppetlabs', @@ -44,4 +46,51 @@ expect(run_plan('peadm::subplans::install', params)).to be_ok end + + it 'installs 2023.2 without r10k_known_hosts' do + params = { + 'primary_host' => 'primary', + 'console_password' => 'puppetlabs', + 'version' => '2023.2.0', + 'r10k_remote' => 'git@github.com:puppetlabs/nothing', + 'r10k_private_key_content' => '-----BEGINfoo', + } + + expect(run_plan('peadm::subplans::install', params)).to be_ok + end + + it 'fails if 2023.3+ and r10k_private_key set but r10k_known_hosts not set' do + params = { + 'primary_host' => 'primary', + 'console_password' => 'puppetlabs', + 'version' => '2023.3.0', + 'r10k_remote' => 'git@github.com:puppetlabs/nothing', + 'r10k_private_key_content' => '-----BEGINfoo', + 'permit_unsafe_versions' => true, + } + + result = run_plan('peadm::subplans::install', params) + expect(result).not_to be_ok + expect(result.value.message).to match(%r{Puppet Enterprise 2023\.3\+ .*requires host key verification}) + end + + it 'installs 2023.3+ with r10k_private_key and r10k_known_hosts' do + params = { + 'primary_host' => 'primary', + 'console_password' => 'puppetlabs', + 'version' => '2023.3.0', + 'r10k_remote' => 'git@github.com:puppetlabs/nothing', + 'r10k_private_key_content' => '-----BEGINfoo', + 'r10k_known_hosts' => [ + { + 'name' => 'test', + 'type' => 'key-type', + 'key' => 'abcdef', + }, + ], + 'permit_unsafe_versions' => true, + } + + expect(run_plan('peadm::subplans::install', params)).to be_ok + end end diff --git a/types/known_hosts.pp b/types/known_hosts.pp new file mode 100644 index 00000000..d08805ea --- /dev/null +++ b/types/known_hosts.pp @@ -0,0 +1,10 @@ +type Peadm::Known_hosts = Array[ + Struct[ + 'title' => Optional[String[1]], + 'ensure' => Optional[Enum['present','absent']], + 'name' => String[1], + 'type' => String[1], + 'key' => String[1], + 'host_aliases' => Optional[Variant[String[1],Array[String[1]]]], + ] +] From 5a37ee5e10296495e0fbf6baa998bfa26d42ff56 Mon Sep 17 00:00:00 2001 From: Josh Partlow Date: Thu, 7 Sep 2023 16:10:58 -0700 Subject: [PATCH 2/3] (PE-36580) Remove fail_plan for r10k_known_hosts Since we aren't testing whether r10k_remote using git@ or ssh:// also has r10k_private_key set, testing for r10k_known_hosts seems like overkill. Removing that plan_fail, and setting r10k_known_hosts directly in the generate_pe_conf call alongside the other r10k parameters. It's true that this parameter only exists in 2023.3+, but peadm::generate_pe_conf() will drop parameters with undef values, and if r10k_known_hosts is explicitly set by mistake by a user on an earlier version than 2023.3, an unmatched parameter in pe.conf hiera is not fatal. --- plans/subplans/install.pp | 24 ++++++------------------ spec/plans/subplans/install_spec.rb | 15 --------------- 2 files changed, 6 insertions(+), 33 deletions(-) diff --git a/plans/subplans/install.pp b/plans/subplans/install.pp index 74e3d957..de4fbabe 100644 --- a/plans/subplans/install.pp +++ b/plans/subplans/install.pp @@ -13,9 +13,10 @@ # # @param r10k_known_hosts # Puppet Enterprise 2023.3+ requires host key verification for the -# r10k_remote host. When setting \$r10k_private_key, you must also provide -# \$r10k_known_hosts information in the form of an array of hashes with -# 'name', 'type' and 'key' information for hostname, key-type and public key. +# r10k_remote host when using ssh. When setting \$r10k_private_key, you must +# also provide \$r10k_known_hosts information in the form of an array of +# hashes with 'name', 'type' and 'key' information for hostname, key-type and +# public key. # # @param license_key_file # The license key to use with Puppet Enterprise. If this is a local file it @@ -132,20 +133,6 @@ # either be undef or else the key content to write. $r10k_private_key = peadm::file_or_content('r10k_private_key', $r10k_private_key_file, $r10k_private_key_content) - # Determine whether r10k_known_hosts is required and has been provided. - $is_pe_2023_3_or_greater = (versioncmp($version, '2023.3.0') >= 0) - if (($is_pe_2023_3_or_greater) and - ($r10k_private_key =~ NotUndef) and - ($r10k_known_hosts =~ Undef)) { - fail_plan("In Puppet Enterprise 2023.3+ r10k 4.0 requires host key verification for the r10k_remote host. When setting \$r10k_private_key, you must also provide \$r10k_known_hosts information in the form of an array of hashes with 'name', 'type' and 'key' information for hostname, key-type and public key. Puppet Enterprise version: ${version}, r10k_known_hosts: ${r10k_known_hosts}") - } - $r10k_known_hosts_config = $r10k_known_hosts ? { - undef => {}, - default => { - 'puppet_enterprise::profile::master::r10k_known_hosts' => $r10k_known_hosts, - }, - } - # Process user input for license key (same process as for r10k private key above). $license_key = peadm::file_or_content('license_key', $license_key_file, $license_key_content) @@ -191,7 +178,8 @@ undef => undef, default => '/etc/puppetlabs/puppetserver/ssh/id-control_repo.rsa', }, - } + $r10k_known_hosts_config + $puppetdb_database_temp_config + $pe_conf_data) + 'puppet_enterprise::profile::master::r10k_known_hosts' => $r10k_known_hosts, + } + $puppetdb_database_temp_config + $pe_conf_data) $primary_postgresql_pe_conf = peadm::generate_pe_conf({ 'console_admin_password' => 'not used', diff --git a/spec/plans/subplans/install_spec.rb b/spec/plans/subplans/install_spec.rb index 354f6d02..d4e2b159 100644 --- a/spec/plans/subplans/install_spec.rb +++ b/spec/plans/subplans/install_spec.rb @@ -59,21 +59,6 @@ expect(run_plan('peadm::subplans::install', params)).to be_ok end - it 'fails if 2023.3+ and r10k_private_key set but r10k_known_hosts not set' do - params = { - 'primary_host' => 'primary', - 'console_password' => 'puppetlabs', - 'version' => '2023.3.0', - 'r10k_remote' => 'git@github.com:puppetlabs/nothing', - 'r10k_private_key_content' => '-----BEGINfoo', - 'permit_unsafe_versions' => true, - } - - result = run_plan('peadm::subplans::install', params) - expect(result).not_to be_ok - expect(result.value.message).to match(%r{Puppet Enterprise 2023\.3\+ .*requires host key verification}) - end - it 'installs 2023.3+ with r10k_private_key and r10k_known_hosts' do params = { 'primary_host' => 'primary', From 9edf544b142ffd4c77bd6fd5fcc293af25fe9200 Mon Sep 17 00:00:00 2001 From: Josh Partlow Date: Thu, 14 Sep 2023 10:31:54 -0700 Subject: [PATCH 3/3] (PE-36580) Add note to review code manager docs. --- plans/subplans/install.pp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plans/subplans/install.pp b/plans/subplans/install.pp index de4fbabe..7eab79f4 100644 --- a/plans/subplans/install.pp +++ b/plans/subplans/install.pp @@ -16,7 +16,8 @@ # r10k_remote host when using ssh. When setting \$r10k_private_key, you must # also provide \$r10k_known_hosts information in the form of an array of # hashes with 'name', 'type' and 'key' information for hostname, key-type and -# public key. +# public key. Please refer to the Puppet Enterprise 2023.3+ Configure Code +# Manager documentation for further details. # # @param license_key_file # The license key to use with Puppet Enterprise. If this is a local file it