From 1cc9edea3a7401b458f22457af24b266ba2ee7b5 Mon Sep 17 00:00:00 2001 From: Phil Friderici Date: Thu, 21 Sep 2017 13:17:52 +0000 Subject: [PATCH] Add config_entries parameter Uses create_resources() to create ssh::config_entry resources for the given hash. Does respect hiera_merge parameter accordingly. --- README.md | 23 ++++- manifests/init.pp | 9 +- spec/classes/init_spec.rb | 84 +++++++++++++++++-- .../fqdn/hieramerge.example.com.yaml | 6 ++ .../hieradata/specific/test_hiera_merge.yaml | 6 ++ 5 files changed, 116 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3829376..0f6589f 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,9 @@ A value of `'USE_DEFAULTS'` will use the defaults specified by the module. hiera_merge ----------- -Boolean to merges all found instances of ssh::keys in Hiera. This is useful for specifying -SSH keys at different levels of the hierarchy and having them all included in the catalog. +Boolean to merges all found instances of ssh::keys and ssh::config_entries in Hiera. +This is useful for specifying SSH keys at different levels of the hierarchy and having +them all included in the catalog. This will default to 'true' in future versions. @@ -619,6 +620,24 @@ See `sshd_config(5)` for more details - *Default*: undefined +config_entries +-------------- +Hash of config entries for a specific user's ~/.ssh/config. Please check the docs for ssd::config_entry for a list and details of the parameters usable here. +Setting hiera_merge to true will activate merging entries through all levels of hiera. + +- *Hiera example*: + +``` yaml +ssh::config_entries: + 'root': + owner: 'root' + group: 'root' + path: '/root/.ssh/config' + host: 'host.example.local' +``` + +- *Default*: {} + keys ---- Hash of keys for user's ~/.ssh/authorized_keys diff --git a/manifests/init.pp b/manifests/init.pp index 5f6a972..eb1deeb 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -109,6 +109,7 @@ class ssh ( $ssh_config_global_known_hosts_group = 'root', $ssh_config_global_known_hosts_mode = '0644', $ssh_config_user_known_hosts_file = undef, + $config_entries = {}, $keys = undef, $manage_root_ssh_config = false, $root_ssh_config_content = "# This file is being maintained by Puppet.\n# DO NOT EDIT\n", @@ -802,18 +803,21 @@ class ssh ( $supported_loglevel_vals=['QUIET', 'FATAL', 'ERROR', 'INFO', 'VERBOSE'] validate_re($sshd_config_loglevel, $supported_loglevel_vals) - #enable hiera merging for groups and users + #enable hiera merging for groups, users, and config_entries if $hiera_merge_real == true { $sshd_config_allowgroups_real = hiera_array('ssh::sshd_config_allowgroups',[]) $sshd_config_allowusers_real = hiera_array('ssh::sshd_config_allowusers',[]) $sshd_config_denygroups_real = hiera_array('ssh::sshd_config_denygroups',[]) $sshd_config_denyusers_real = hiera_array('ssh::sshd_config_denyusers',[]) + $config_entries_real = hiera_hash('ssh::config_entries',{}) } else { $sshd_config_allowgroups_real = $sshd_config_allowgroups $sshd_config_allowusers_real = $sshd_config_allowusers $sshd_config_denygroups_real = $sshd_config_denygroups $sshd_config_denyusers_real = $sshd_config_denyusers + $config_entries_real = $config_entries } + validate_hash($config_entries_real) if $sshd_config_denyusers_real != [] { validate_array($sshd_config_denyusers_real) @@ -973,6 +977,9 @@ class ssh ( purge => $purge_keys_real, } + # manage users' ssh config entries if present + create_resources('ssh::config_entry',$config_entries_real) + # manage users' ssh authorized keys if present if $keys != undef { if $hiera_merge_real == true { diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index 256d52c..43563f0 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -295,6 +295,8 @@ describe 'ssh' do 'purge' => 'true', }) } + + it { should have_ssh__config_entry_resource_count(0) } end end @@ -1345,6 +1347,71 @@ describe 'sshd_config_print_last_log param' do } end + context 'with config_entries defined on valid osfamily' do + let(:params) do + { + :config_entries => { + 'root' => { + 'owner' => 'root', + 'group' => 'root', + 'path' => '/root/.ssh/config', + 'host' => 'test_host1', + }, + 'user' => { + 'owner' => 'user', + 'group' => 'group', + 'path' => '/home/user/.ssh/config', + 'host' => 'test_host2', + 'order' => '242', + 'lines' => [ 'ForwardX11 no', 'StrictHostKeyChecking no' ], + }, + } + } + end + + it { should compile.with_all_deps } + it { should have_ssh__config_entry_resource_count(2) } + it do + should contain_ssh__config_entry('root').with({ + 'owner' => 'root', + 'group' => 'root', + 'path' => '/root/.ssh/config', + 'host' => 'test_host1', + }) + end + it do + should contain_ssh__config_entry('user').with({ + 'owner' => 'user', + 'group' => 'group', + 'path' => '/home/user/.ssh/config', + 'host' => 'test_host2', + 'order' => '242', + 'lines' => [ 'ForwardX11 no', 'StrictHostKeyChecking no' ], + }) + end + end + + describe 'with hiera providing data from multiple levels' do + let(:facts) do + default_facts.merge({ + :fqdn => 'hieramerge.example.com', + :specific => 'test_hiera_merge', + }) + end + + context 'with defaults for all parameters' do + it { should have_ssh__config_entry_resource_count(1) } + it { should contain_ssh__config_entry('user_from_fqdn') } + end + + context 'with hiera_merge set to valid ' do + let(:params) { { :hiera_merge => true } } + it { should have_ssh__config_entry_resource_count(2) } + it { should contain_ssh__config_entry('user_from_fqdn') } + it { should contain_ssh__config_entry('user_from_fact') } + end + end + context 'with keys defined on valid osfamily' do let(:params) { { :keys => { 'root_for_userX' => { @@ -2514,14 +2581,15 @@ describe 'sshd_config_print_last_log param' do end describe 'variable type and content validations' do - # set needed custom facts and variables - let(:mandatory_params) do - { - #:param => 'value', - } - end + mandatory_params = {} if mandatory_params.nil? validations = { + 'hash' => { + :name => %w[config_entries], + :valid => [], # valid hashes are to complex to block test them here. types::mount should have its own spec tests anyway. + :invalid => ['string', %w[array], 3, 2.42, true], + :message => 'is not a Hash', + }, 'regex (yes|no|unset)' => { :name => %w(ssh_config_use_roaming), :valid => ['yes', 'no', 'unset'], @@ -2543,9 +2611,7 @@ describe 'sshd_config_print_last_log param' do var[:invalid].each do |invalid| context "when #{var_name} (#{type}) is set to invalid #{invalid} (as #{invalid.class})" do let(:params) { [mandatory_params, var[:params], { :"#{var_name}" => invalid, }].reduce(:merge) } - it 'should fail' do - expect { should contain_class(subject) }.to raise_error(Puppet::Error, /#{var[:message]}/) - end + it { is_expected.to compile.and_raise_error(/#{var[:message]}/) } end end end # var[:name].each diff --git a/spec/fixtures/hiera/hieradata/fqdn/hieramerge.example.com.yaml b/spec/fixtures/hiera/hieradata/fqdn/hieramerge.example.com.yaml index e8d0fc4..7748213 100644 --- a/spec/fixtures/hiera/hieradata/fqdn/hieramerge.example.com.yaml +++ b/spec/fixtures/hiera/hieradata/fqdn/hieramerge.example.com.yaml @@ -7,3 +7,9 @@ ssh::sshd_config_denygroups: - denygroup_from_fqdn ssh::sshd_config_denyusers: - denyuser_from_fqdn +ssh::config_entries: + 'user_from_fqdn': + owner: 'fqdn_user' + group: 'fqdn_user' + path: '/home/fqdn_user/.ssh/config' + host: 'fqdn_host.example.local' diff --git a/spec/fixtures/hiera/hieradata/specific/test_hiera_merge.yaml b/spec/fixtures/hiera/hieradata/specific/test_hiera_merge.yaml index 7f7b51f..ea22373 100644 --- a/spec/fixtures/hiera/hieradata/specific/test_hiera_merge.yaml +++ b/spec/fixtures/hiera/hieradata/specific/test_hiera_merge.yaml @@ -7,3 +7,9 @@ ssh::sshd_config_denygroups: - denygroup_from_fact ssh::sshd_config_denyusers: - denyuser_from_fact +ssh::config_entries: + 'user_from_fact': + owner: 'fact_user' + group: 'fact_user' + path: '/home/fact_user/.ssh/config' + host: 'fact_host.example.local'