diff --git a/manifests/client.pp b/manifests/client.pp index 080b90f..edf6c1f 100644 --- a/manifests/client.pp +++ b/manifests/client.pp @@ -1,64 +1,56 @@ # @summary # This class add ssh client management # # @example Puppet usage # class { 'ssh::client': # ensure => present, # storeconfigs_enabled => true, # use_augeas => false, # } # # @param ensure # Ensurable param to ssh client # # @param storeconfigs_enabled # Collected host keys from servers will be written to known_hosts unless storeconfigs_enabled is false # # @param options # Dynamic hash for openssh client options # # @param options_absent # Remove options (with augeas style) # -class ssh::client( +class ssh::client ( String $ensure = present, Boolean $storeconfigs_enabled = true, Hash $options = {}, Boolean $use_augeas = false, Array $options_absent = [], ) inherits ssh::params { - # Merge hashes from multiple layer of hierarchy in hiera $hiera_options = lookup("${module_name}::client::options", Optional[Hash], 'deep', {}) $fin_options = deep_merge($hiera_options, $options) if $use_augeas { $merged_options = sshclient_options_to_augeas_ssh_config($fin_options, $options_absent, { 'target' => $ssh::params::ssh_config }) } else { $merged_options = merge($fin_options, delete($ssh::params::ssh_default_options, keys($fin_options))) } include ssh::client::install include ssh::client::config - anchor { 'ssh::client::start': } - anchor { 'ssh::client::end': } - # Provide option to *not* use storeconfigs/puppetdb, which means not managing # hostkeys and knownhosts if ($storeconfigs_enabled) { include ssh::knownhosts - Anchor['ssh::client::start'] - -> Class['ssh::client::install'] + Class['ssh::client::install'] -> Class['ssh::client::config'] -> Class['ssh::knownhosts'] - -> Anchor['ssh::client::end'] } else { - Anchor['ssh::client::start'] - -> Class['ssh::client::install'] + Class['ssh::client::install'] -> Class['ssh::client::config'] - -> Anchor['ssh::client::end'] } } diff --git a/manifests/client/config.pp b/manifests/client/config.pp index 68885c8..e8a99a5 100644 --- a/manifests/client/config.pp +++ b/manifests/client/config.pp @@ -1,18 +1,17 @@ -class ssh::client::config -{ +class ssh::client::config { $options = $ssh::client::merged_options $use_augeas = $ssh::client::use_augeas if $use_augeas { create_resources('ssh_config', $options) } else { file { $ssh::params::ssh_config: - ensure => present, + ensure => file, owner => '0', group => '0', mode => '0644', content => template("${module_name}/ssh_config.erb"), require => Class['ssh::client::install'], } } } diff --git a/manifests/client/config/user.pp b/manifests/client/config/user.pp index 35ec937..d2f8150 100644 --- a/manifests/client/config/user.pp +++ b/manifests/client/config/user.pp @@ -1,56 +1,56 @@ # # Copyright (c) IN2P3 Computing Centre, IN2P3, CNRS # Contributor: Remi Ferrand (2015) # Contributor: Tim Meusel (2017) # -define ssh::client::config::user( +define ssh::client::config::user ( Enum['present', 'absent'] $ensure = present, Optional[Stdlib::Absolutepath] $target = undef, Optional[Stdlib::Absolutepath] $user_home_dir = undef, Boolean $manage_user_ssh_dir = true, Hash $options = {}, String[1] $user = $name, ) { include ssh::params # If a specific target file was specified, # it must have higher priority than any # other parameter. if ($target != undef) { $_target = $target } else { if ($user_home_dir == undef) { $_user_home_dir = "/home/${user}" } else { $_user_home_dir = $user_home_dir } $user_ssh_dir = "${_user_home_dir}/.ssh" $_target = "${user_ssh_dir}/config" if ($manage_user_ssh_dir == true) { unless defined(File[$user_ssh_dir]) { file { $user_ssh_dir: ensure => directory, owner => $user, mode => $ssh::params::user_ssh_directory_default_mode, before => Concat_file[$_target], } } } } unless defined(Concat_file[$_target]) { concat_file { $_target: ensure => $ensure, owner => $user, mode => $ssh::params::user_ssh_config_default_mode, tag => $name, } } concat_fragment { $name: tag => $name, content => template("${module_name}/ssh_config.erb"), target => $_target, } } diff --git a/manifests/client/install.pp b/manifests/client/install.pp index 11f0d2b..d3489ec 100644 --- a/manifests/client/install.pp +++ b/manifests/client/install.pp @@ -1,5 +1,9 @@ class ssh::client::install { if $ssh::params::client_package_name { - ensure_packages([$ssh::params::client_package_name], {'ensure' => $ssh::client::ensure}) + ensure_packages([ + $ssh::params::client_package_name, + ], { + 'ensure' => $ssh::client::ensure, + }) } } diff --git a/manifests/hostkeys.pp b/manifests/hostkeys.pp index 697b9f6..b5e45f6 100644 --- a/manifests/hostkeys.pp +++ b/manifests/hostkeys.pp @@ -1,59 +1,58 @@ # @summary # This class manages hostkeys # # @api private # -class ssh::hostkeys( +class ssh::hostkeys ( Boolean $export_ipaddresses = true, Optional[String] $storeconfigs_group = undef, Array $extra_aliases = [], Array $exclude_interfaces = [], Array $exclude_ipaddresses = [], Boolean $use_trusted_facts = false, ) { - if $use_trusted_facts { $fqdn_real = $trusted['certname'] $hostname_real = $trusted['hostname'] } else { # stick to legacy facts for older versions of facter - $fqdn_real = $facts['fqdn'] - $hostname_real = $facts['hostname'] + $fqdn_real = $facts['networking']['fqdn'] + $hostname_real = $facts['networking']['hostname'] } if $export_ipaddresses == true { $ipaddresses = ssh::ipaddresses($exclude_interfaces) $ipaddresses_real = $ipaddresses - $exclude_ipaddresses - $host_aliases = sort(unique(flatten([ $fqdn_real, $hostname_real, $extra_aliases, $ipaddresses_real ]))) + $host_aliases = sort(unique(flatten([$fqdn_real, $hostname_real, $extra_aliases, $ipaddresses_real]))) } else { - $host_aliases = sort(unique(flatten([ $fqdn_real, $hostname_real, $extra_aliases ]))) + $host_aliases = sort(unique(flatten([$fqdn_real, $hostname_real, $extra_aliases]))) } if $storeconfigs_group { tag 'hostkey_all', "hostkey_${storeconfigs_group}" } ['dsa', 'rsa', 'ecdsa', 'ed25519'].each |String $key_type| { # can be removed as soon as we drop support for puppet 4 # see https://tickets.puppetlabs.com/browse/FACT-1377?jql=project%20%3D%20FACT%20AND%20fixVersion%20%3D%20%22FACT%203.12.0%22 if $key_type == 'ecdsa' { $key_type_real = 'ecdsa-sha2-nistp256' } else { $key_type_real = $key_type } if $key_type in $facts['ssh'] { @@sshkey { "${fqdn_real}_${key_type}": ensure => present, host_aliases => $host_aliases, type => $key_type_real, key => $facts['ssh'][$key_type]['key'], } } else { @@sshkey { "${fqdn_real}_${key_type}": ensure => absent, type => $key_type_real, } } } } diff --git a/manifests/init.pp b/manifests/init.pp index 1f833e3..ca98a1a 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,153 +1,152 @@ # @summary # This class manages ssh client and server # # @example Puppet usage # class { 'ssh': # storeconfigs_enabled => false, # server_options => { # 'Match User www-data' => { # 'ChrootDirectory' => '%h', # 'ForceCommand' => 'internal-sftp', # 'PasswordAuthentication' => 'yes', # 'AllowTcpForwarding' => 'no', # 'X11Forwarding' => 'no', # }, # 'Port' => [22, 2222, 2288], # }, # client_options => { # 'Host *.amazonaws.com' => { # 'User' => 'ec2-user', # }, # }, # users_client_options => { # 'bob' => { # options => { # 'Host *.alice.fr' => { # 'User' => 'alice', # }, # }, # }, # }, # } # # @example hiera usage # ssh::storeconfigs_enabled: true # # ssh::server_options: # Protocol: '2' # ListenAddress: # - '127.0.0.0' # - '%{::hostname}' # PasswordAuthentication: 'yes' # SyslogFacility: 'AUTHPRIV' # UsePAM: 'yes' # X11Forwarding: 'yes' # # ssh::server::match_block: # filetransfer: # type: group # options: # ChrootDirectory: /home/sftp # ForceCommand: internal-sftp # # ssh::client_options: # 'Host *': # SendEnv: 'LANG LC_*' # ForwardX11Trusted: 'yes' # ServerAliveInterval: '10' # # ssh::users_client_options: # 'bob': # 'options': # 'Host *.alice.fr': # 'User': 'alice' # 'PasswordAuthentication': 'no' # # # @param server_options # Add dynamic options for ssh server config # # @param server_match_block # Add match block for ssh server config # # @param client_options # Add dynamic options for ssh client config # # @param users_client_options # Add users options for ssh client config # # @param version # Define package version (pacakge ressource) # # @param storeconfigs_enabled # Default value for storeconfigs_enabled (client and server) # # @param validate_sshd_file # Default value for validate_sshd_file (server) # # @param use_augeas # Default value to use augeas (client and server) # # @param server_options_absent # List of options to remove for server config (augeas only) # # @param client_options_absent # List of options to remove for client config (augeas only) # # @param use_issue_net # Use issue_net header # class ssh ( Hash $server_options = {}, Hash $server_match_block = {}, Hash $client_options = {}, Hash $users_client_options = {}, String $version = 'present', Boolean $storeconfigs_enabled = true, Boolean $validate_sshd_file = $ssh::params::validate_sshd_file, Boolean $use_augeas = false, Array $server_options_absent = [], Array $client_options_absent = [], Boolean $use_issue_net = false, Boolean $purge_unmanaged_sshkeys = true, ) inherits ssh::params { - # Merge hashes from multiple layer of hierarchy in hiera $hiera_server_options = lookup("${module_name}::server_options", Optional[Hash], 'deep', {}) $hiera_server_match_block = lookup("${module_name}::server_match_block", Optional[Hash], 'deep', {}) $hiera_client_options = lookup("${module_name}::client_options", Optional[Hash], 'deep', {}) $hiera_users_client_options = lookup("${module_name}::users_client_options", Optional[Hash], 'deep', {}) $fin_server_options = deep_merge($hiera_server_options, $server_options) $fin_server_match_block = deep_merge($hiera_server_match_block, $server_match_block) $fin_client_options = deep_merge($hiera_client_options, $client_options) $fin_users_client_options = deep_merge($hiera_users_client_options, $users_client_options) class { 'ssh::server': ensure => $version, storeconfigs_enabled => $storeconfigs_enabled, options => $fin_server_options, validate_sshd_file => $validate_sshd_file, use_augeas => $use_augeas, options_absent => $server_options_absent, use_issue_net => $use_issue_net, } class { 'ssh::client': ensure => $version, storeconfigs_enabled => $storeconfigs_enabled, options => $fin_client_options, use_augeas => $use_augeas, options_absent => $client_options_absent, } # If host keys are being managed, optionally purge unmanaged ones as well. if ($storeconfigs_enabled and $purge_unmanaged_sshkeys) { resources { 'sshkey': purge => true, } } create_resources('ssh::client::config::user', $fin_users_client_options) create_resources('ssh::server::match_block', $fin_server_match_block) } diff --git a/manifests/knownhosts.pp b/manifests/knownhosts.pp index 405a182..bd6b9d2 100644 --- a/manifests/knownhosts.pp +++ b/manifests/knownhosts.pp @@ -1,21 +1,21 @@ # @summary # This class manages knownhosts if collection is enabled. # # @param collect_enabled # Enable collection # # @param storeconfigs_group # Define the hostkeys group storage # -class ssh::knownhosts( +class ssh::knownhosts ( Boolean $collect_enabled = $ssh::params::collect_enabled, Optional[String] $storeconfigs_group = undef, ) inherits ssh::params { if ($collect_enabled) { if $storeconfigs_group { Sshkey <<| tag == "hostkey_${storeconfigs_group}" |>> } else { Sshkey <<| |>> } } } diff --git a/manifests/params.pp b/manifests/params.pp index 5b4b6c1..6925cfe 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -1,238 +1,238 @@ # @summary # Params class # # @api private # class ssh::params { - case $::osfamily { + case $facts['os']['family'] { 'Debian': { $server_package_name = 'openssh-server' $client_package_name = 'openssh-client' $sshd_dir = '/etc/ssh' $sshd_config = '/etc/ssh/sshd_config' $ssh_config = '/etc/ssh/ssh_config' $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' $service_name = 'ssh' $sftp_server_path = '/usr/lib/openssh/sftp-server' $host_priv_key_group = 0 } 'RedHat': { $server_package_name = 'openssh-server' $client_package_name = 'openssh-clients' $sshd_dir = '/etc/ssh' $sshd_config = '/etc/ssh/sshd_config' $ssh_config = '/etc/ssh/ssh_config' $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' $service_name = 'sshd' $sftp_server_path = '/usr/libexec/openssh/sftp-server' - if versioncmp($::operatingsystemmajrelease, '7') >= 0 { + if versioncmp($facts['os']['release']['major'], '7') >= 0 { $host_priv_key_group = 'ssh_keys' } else { $host_priv_key_group = 0 } } 'FreeBSD', 'DragonFly': { $server_package_name = undef $client_package_name = undef $sshd_dir = '/etc/ssh' $sshd_config = '/etc/ssh/sshd_config' $ssh_config = '/etc/ssh/ssh_config' $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' $service_name = 'sshd' $sftp_server_path = '/usr/libexec/sftp-server' $host_priv_key_group = 0 } 'OpenBSD': { $server_package_name = undef $client_package_name = undef $sshd_dir = '/etc/ssh' $sshd_config = '/etc/ssh/sshd_config' $ssh_config = '/etc/ssh/ssh_config' $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' $service_name = 'sshd' $sftp_server_path = '/usr/libexec/sftp-server' $host_priv_key_group = 0 } 'Darwin': { $server_package_name = undef $client_package_name = undef $sshd_dir = '/etc/ssh' $sshd_config = '/etc/ssh/sshd_config' $ssh_config = '/etc/ssh/ssh_config' $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' $service_name = 'com.openssh.sshd' $sftp_server_path = '/usr/libexec/sftp-server' $host_priv_key_group = 0 } 'ArchLinux': { $server_package_name = 'openssh' $client_package_name = 'openssh' $sshd_dir = '/etc/ssh' $sshd_config = '/etc/ssh/sshd_config' $ssh_config = '/etc/ssh/ssh_config' $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' $service_name = 'sshd.service' $sftp_server_path = '/usr/lib/ssh/sftp-server' $host_priv_key_group = 0 } 'Suse': { $server_package_name = 'openssh' $client_package_name = 'openssh' $sshd_dir = '/etc/ssh' $sshd_config = '/etc/ssh/sshd_config' $ssh_config = '/etc/ssh/ssh_config' $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' $host_priv_key_group = 0 - case $::operatingsystem { + case $facts['os']['name'] { 'SLES': { $service_name = 'sshd' - # $::operatingsystemmajrelease isn't available on e.g. SLES 10 - case $::operatingsystemrelease { + case $facts['os']['release']['full'] { /^10\./, /^11\./: { - if ($::architecture == 'x86_64') { + if ($facts['os']['architecture'] == 'x86_64') { $sftp_server_path = '/usr/lib64/ssh/sftp-server' } else { $sftp_server_path = '/usr/lib/ssh/sftp-server' } } default: { $sftp_server_path = '/usr/lib/ssh/sftp-server' } } } 'OpenSuse': { $service_name = 'sshd' $sftp_server_path = '/usr/lib/ssh/sftp-server' } default: { - fail("Unsupported platform: ${::osfamily}/${::operatingsystem}") + fail("Unsupported platform: ${facts['os']['family']}/${facts['os']['name']}") } } } 'Solaris': { - case $::operatingsystem { + case $facts['os']['name'] { 'SmartOS': { $server_package_name = undef $client_package_name = undef $sshd_dir = '/etc/ssh' $sshd_config = '/etc/ssh/sshd_config' $ssh_config = '/etc/ssh/ssh_config' $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' $service_name = 'svc:/network/ssh:default' $sftp_server_path = 'internal-sftp' $host_priv_key_group = 0 } default: { $sshd_dir = '/etc/ssh' $sshd_config = '/etc/ssh/sshd_config' $ssh_config = '/etc/ssh/ssh_config' $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' $service_name = 'svc:/network/ssh:default' $sftp_server_path = 'internal-sftp' $host_priv_key_group = 0 - case versioncmp($::kernelrelease, '5.10') { + case versioncmp($facts['kernelrelease'], '5.10') { 1: { # Solaris 11 and later $server_package_name = '/service/network/ssh' $client_package_name = '/network/ssh' } 0: { # Solaris 10 $server_package_name = 'SUNWsshdu' $client_package_name = 'SUNWsshu' } default: { # Solaris 9 and earlier not supported - fail("Unsupported platform: ${::osfamily}/${::kernelrelease}") + fail("Unsupported platform: ${facts['os']['family']}/${facts['kernelrelease']}") } } } } } default: { - case $::operatingsystem { + case $facts['os']['name'] { 'Gentoo': { $server_package_name = 'openssh' $client_package_name = 'openssh' $sshd_dir = '/etc/ssh' $sshd_config = '/etc/ssh/sshd_config' $ssh_config = '/etc/ssh/ssh_config' $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' $service_name = 'sshd' $sftp_server_path = '/usr/lib/misc/sftp-server' $host_priv_key_group = 0 } 'Amazon': { $server_package_name = 'openssh-server' $client_package_name = 'openssh-clients' $sshd_dir = '/etc/ssh' $sshd_config = '/etc/ssh/sshd_config' $ssh_config = '/etc/ssh/ssh_config' $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' $service_name = 'sshd' $sftp_server_path = '/usr/libexec/openssh/sftp-server' $host_priv_key_group = 0 } default: { - fail("Unsupported platform: ${::osfamily}/${::operatingsystem}") + fail("Unsupported platform: ${facts['os']['family']}/${facts['os']['name']}") } } } } # ssh & sshd default options: # - OpenBSD doesn't know about UsePAM # - Sun_SSH doesn't know about UsePAM & AcceptEnv; SendEnv & HashKnownHosts - case $::osfamily { + case $facts['os']['family'] { 'OpenBSD': { $sshd_default_options = { 'ChallengeResponseAuthentication' => 'no', 'X11Forwarding' => 'yes', 'PrintMotd' => 'no', 'AcceptEnv' => 'LANG LC_*', 'Subsystem' => "sftp ${sftp_server_path}", } $ssh_default_options = { 'Host *' => { 'SendEnv' => 'LANG LC_*', 'HashKnownHosts' => 'yes', }, } } 'Solaris': { $sshd_default_options = { 'ChallengeResponseAuthentication' => 'no', 'X11Forwarding' => 'yes', 'PrintMotd' => 'no', 'Subsystem' => "sftp ${sftp_server_path}", 'HostKey' => [ "${sshd_dir}/ssh_host_rsa_key", "${sshd_dir}/ssh_host_dsa_key", ], } - $ssh_default_options = { } + $ssh_default_options = { + } } default: { $sshd_default_options = { 'ChallengeResponseAuthentication' => 'no', 'X11Forwarding' => 'yes', 'PrintMotd' => 'no', 'AcceptEnv' => 'LANG LC_*', 'Subsystem' => "sftp ${sftp_server_path}", 'UsePAM' => 'yes', } $ssh_default_options = { 'Host *' => { 'SendEnv' => 'LANG LC_*', 'HashKnownHosts' => 'yes', }, } } } $validate_sshd_file = false $user_ssh_directory_default_mode = '0700' $user_ssh_config_default_mode = '0600' $collect_enabled = true # Collect sshkey resources $issue_net = '/etc/issue.net' } diff --git a/manifests/server.pp b/manifests/server.pp index 7b3d89b..e30a631 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -1,88 +1,80 @@ # @summary # This class managed ssh server # # @example Puppet usage # class { 'ssh::server': # ensure => present, # storeconfigs_enabled => true, # use_issue_net => false, # } # # @param ensure # Ensurable param to ssh server # # @param storeconfigs_enabled # Host keys will be collected and distributed unless storeconfigs_enabled is false. # # @param options # Dynamic hash for openssh server option # # @param validate_sshd_file # Add sshd file validate cmd # # @param use_augeas # Use augeas for configuration (default concat) # # @param options_absent # Remove options (with augeas style) # # @param match_block # Add sshd match_block (with concat) # # @use_issue_net # Add issue_net banner # -class ssh::server( +class ssh::server ( String $ensure = present, Boolean $storeconfigs_enabled = true, Hash $options = {}, Boolean $validate_sshd_file = false, Boolean $use_augeas = false, Array $options_absent = [], Hash $match_block = {}, Boolean $use_issue_net = false ) inherits ssh::params { - # Merge hashes from multiple layer of hierarchy in hiera $hiera_options = lookup("${module_name}::server::options", Optional[Hash], 'deep', {}) $hiera_match_block = lookup("${module_name}::server::match_block", Optional[Hash], 'deep', {}) $fin_options = deep_merge($hiera_options, $options) $fin_match_block = deep_merge($hiera_match_block, $match_block) if $use_augeas { $merged_options = sshserver_options_to_augeas_sshd_config($fin_options, $options_absent, { 'target' => $ssh::params::sshd_config }) } else { $merged_options = deep_merge($ssh::params::sshd_default_options, $fin_options) } include ssh::server::install include ssh::server::config include ssh::server::service - anchor { 'ssh::server::start': } - anchor { 'ssh::server::end': } - # Provide option to *not* use storeconfigs/puppetdb, which means not managing # hostkeys and knownhosts if ($storeconfigs_enabled) { include ssh::hostkeys include ssh::knownhosts - Anchor['ssh::server::start'] - -> Class['ssh::server::install'] + Class['ssh::server::install'] -> Class['ssh::server::config'] ~> Class['ssh::server::service'] -> Class['ssh::hostkeys'] -> Class['ssh::knownhosts'] - -> Anchor['ssh::server::end'] } else { - Anchor['ssh::server::start'] - -> Class['ssh::server::install'] + Class['ssh::server::install'] -> Class['ssh::server::config'] ~> Class['ssh::server::service'] - -> Anchor['ssh::server::end'] } create_resources('ssh::server::match_block', $fin_match_block) } diff --git a/manifests/server/config.pp b/manifests/server/config.pp index e539a95..ce1fa12 100644 --- a/manifests/server/config.pp +++ b/manifests/server/config.pp @@ -1,53 +1,53 @@ # @summary # Managed ssh server configuration # # @api private # class ssh::server::config { $options = $ssh::server::merged_options case $ssh::server::validate_sshd_file { true: { $sshd_validate_cmd = '/usr/sbin/sshd -tf %' } default: { $sshd_validate_cmd = undef } } if $ssh::server::use_augeas { create_resources('sshd_config', $options) } else { concat { $ssh::params::sshd_config: ensure => present, owner => 0, group => 0, mode => '0600', validate_cmd => $sshd_validate_cmd, notify => Service[$ssh::params::service_name], } concat::fragment { 'global config': target => $ssh::params::sshd_config, content => template("${module_name}/sshd_config.erb"), order => '00', } } if $ssh::server::use_issue_net { file { $ssh::params::issue_net: - ensure => present, + ensure => file, owner => 0, group => 0, mode => '0644', content => template("${module_name}/issue.net.erb"), notify => Service[$ssh::params::service_name], } concat::fragment { 'banner file': target => $ssh::params::sshd_config, content => "Banner ${ssh::params::issue_net}\n", order => '01', } } } diff --git a/manifests/server/config/setting.pp b/manifests/server/config/setting.pp index 912806b..20dafc6 100644 --- a/manifests/server/config/setting.pp +++ b/manifests/server/config/setting.pp @@ -1,33 +1,32 @@ # @summary # Internal define to managed ssh server param # # @api private # define ssh::server::config::setting ( $key, $value, $order = '10' ) { include ssh::params if is_bool($value) { $real_value = $value ? { true => 'yes', false => 'no', default => undef } } elsif is_array($value) { $real_value = join($value, ' ') } elsif is_hash($value) { fail('Hash values are not supported') } else { $real_value = $value } concat::fragment { "ssh_setting_${name}_${key}": target => $ssh::params::sshd_config, content => "\n# added by Ssh::Server::Config::Setting[${name}]\n${key} ${real_value}\n", order => $order, } - } diff --git a/manifests/server/host_key.pp b/manifests/server/host_key.pp index 65e8768..209f057 100644 --- a/manifests/server/host_key.pp +++ b/manifests/server/host_key.pp @@ -1,153 +1,152 @@ # == Define: ssh::server::host_key # # This module install a ssh host key in the server (basically, it is # a file resource but it also notifies to the ssh service) # # Important! This define does not modify any option in sshd_config, so # you have to manually define the HostKey option in the server options # if you haven't done yet. # # == Parameters # # [*ensure*] # Set to 'absent' to remove host_key files # # [*public_key_source*] # Sets the content of the source parameter for the public key file # Note public_key_source and public_key_content are mutually exclusive. # # [*public_key_content*] # Sets the content for the public key file. # Note public_key_source and public_key_content are mutually exclusive. # # [*private_key_source*] # Sets the content of the source parameter for the private key file # Note private_key_source and private_key_content are mutually exclusive. # # [*private_key_content*] # Sets the content for the private key file. # Note private_key_source and private_key_content are mutually exclusive. # # [*certificate_source*] # Sets the content of the source parameter for the host key certificate. # Note certificate_source and certificate_content are mutually exclusive. # # [*certificate_content*] # Sets the content for the host key certificate. # Note certificate_source and certificate_content are mutually exclusive. # define ssh::server::host_key ( $ensure = 'present', $public_key_source = '', $public_key_content = '', $private_key_source = '', $private_key_content = '', $certificate_source = '', $certificate_content = '', ) { - # Ensure the ssh::server class is included in the manifest include ssh::server if $public_key_source == '' and $public_key_content == '' and $ensure == 'present' { fail('You must provide either public_key_source or public_key_content parameter') } if $private_key_source == '' and $private_key_content == '' and $ensure == 'present' { fail('You must provide either private_key_source or private_key_content parameter') } $manage_pub_key_content = $public_key_source ? { '' => $public_key_content, default => undef, } $manage_pub_key_source = $public_key_source ? { '' => undef, default => $public_key_source, } $manage_priv_key_content = $private_key_source ? { '' => $private_key_content, default => undef, } $manage_priv_key_source = $private_key_source ? { '' => undef, default => $private_key_source, } $manage_cert_content = $certificate_source ? { '' => $certificate_content, default => undef, } $manage_cert_source = $certificate_source ? { '' => undef, default => $certificate_source, } if $ensure == 'present' { - file {"${name}_pub": + file { "${name}_pub": ensure => $ensure, owner => 0, group => 0, mode => '0644', path => "${ssh::params::sshd_dir}/${name}.pub", source => $manage_pub_key_source, content => $manage_pub_key_content, notify => Class['ssh::server::service'], } - file {"${name}_priv": + file { "${name}_priv": ensure => $ensure, owner => 0, group => $ssh::params::host_priv_key_group, mode => '0600', path => "${ssh::params::sshd_dir}/${name}", source => $manage_priv_key_source, content => $manage_priv_key_content, show_diff => false, notify => Class['ssh::server::service'], } } else { - file {"${name}_pub": + file { "${name}_pub": ensure => $ensure, owner => 0, group => 0, mode => '0644', path => "${ssh::params::sshd_dir}/${name}.pub", notify => Class['ssh::server::service'], } - file {"${name}_priv": + file { "${name}_priv": ensure => $ensure, owner => 0, group => $ssh::params::host_priv_key_group, mode => '0600', path => "${ssh::params::sshd_dir}/${name}", show_diff => false, notify => Class['ssh::server::service'], } } if !empty($certificate_source) or !empty($certificate_content) { if $ensure == 'present' { - file {"${name}_cert": + file { "${name}_cert": ensure => $ensure, owner => 0, group => 0, mode => '0644', path => "${ssh::params::sshd_dir}/${name}-cert.pub", source => $manage_cert_source, content => $manage_cert_content, notify => Class['ssh::server::service'], } } else { - file {"${name}_cert": + file { "${name}_cert": ensure => $ensure, owner => 0, group => 0, mode => '0644', path => "${ssh::params::sshd_dir}/${name}-cert.pub", notify => Class['ssh::server::service'], } } } } diff --git a/manifests/server/install.pp b/manifests/server/install.pp index 70b22aa..d6a4a46 100644 --- a/manifests/server/install.pp +++ b/manifests/server/install.pp @@ -1,14 +1,15 @@ # @summary # Install ssh server package # # @api private # class ssh::server::install { include ssh::params if $ssh::params::server_package_name { - ensure_packages( - [$ssh::params::server_package_name], - { 'ensure' => $ssh::server::ensure } - ) + ensure_packages ([ + $ssh::params::server_package_name, + ], { + 'ensure' => $ssh::server::ensure, + }) } } diff --git a/manifests/server/service.pp b/manifests/server/service.pp index ee80a6c..1aa0757 100644 --- a/manifests/server/service.pp +++ b/manifests/server/service.pp @@ -1,24 +1,24 @@ # @summary # This class managed ssh server service # # @param ensure # Ensurable service param # # @param enable # Define if service is enable # class ssh::server::service ( String $ensure = 'running', Boolean $enable = true -){ +) { include ssh::params include ssh::server service { $ssh::params::service_name: ensure => $ssh::server::service::ensure, hasstatus => true, hasrestart => true, enable => $ssh::server::service::enable, require => Class['ssh::server::config'], } } diff --git a/spec/classes/client_spec.rb b/spec/classes/client_spec.rb index 6dd1433..80115b3 100644 --- a/spec/classes/client_spec.rb +++ b/spec/classes/client_spec.rb @@ -1,31 +1,55 @@ require 'spec_helper' describe 'ssh::client', type: 'class' do context 'when on Debian with no other parameters' do let :facts do { - osfamily: 'Debian' + :os => { + 'family' => 'Debian' + }, + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1' + }, + 'eth1' => { + 'ip' => '10.0.1.1' + }, + } + } } end it do is_expected.to contain_package('openssh-client').with(ensure: 'present') end end context 'when on Debian with custom ensure' do let :facts do { - osfamily: 'Debian' + :os => { + 'family' => 'Debian' + }, + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1' + }, + 'eth1' => { + 'ip' => '10.0.1.1' + }, + } + } } end let :params do { ensure: 'latest' } end it do is_expected.to contain_package('openssh-client').with(ensure: 'latest') end end end diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index e2a36b5..09e1df8 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -1,62 +1,98 @@ require 'spec_helper' describe 'ssh', type: 'class' do context 'when on Debian with no other parameters' do let :facts do { - osfamily: 'Debian' + :os => { + 'family' => 'Debian' + }, + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1' + }, + 'eth1' => { + 'ip' => '10.0.1.1' + }, + } + } } end it do is_expected.to contain_class('ssh::client') end it do is_expected.to contain_class('ssh::server') end it do is_expected.to contain_concat('/etc/ssh/sshd_config').with_validate_cmd(nil) end it do is_expected.to contain_resources('sshkey').with_purge(true) end context 'when on Debian with the validate_sshd_file setting' do let :facts do { - osfamily: 'Debian' + :os => { + 'family' => 'Debian' + }, + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1' + }, + 'eth1' => { + 'ip' => '10.0.1.1' + }, + } + } } end let :params do { validate_sshd_file: true } end it do is_expected.to contain_class('ssh::client') end it do is_expected.to contain_concat('/etc/ssh/sshd_config').with_validate_cmd('/usr/sbin/sshd -tf %') end end end standard_facts = { - osfamily: 'Debian' + :os => { + 'family' => 'Debian' + }, + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1' + }, + 'eth1' => { + 'ip' => '10.0.1.1' + }, + } + } } context 'When on Debian without resource purging' do let :facts do standard_facts end let :params do { 'purge_unmanaged_sshkeys' => false } end it do is_expected.not_to contain_resources('sshkey') end end end diff --git a/spec/classes/server_spec.rb b/spec/classes/server_spec.rb index 09cae7b..54d977e 100644 --- a/spec/classes/server_spec.rb +++ b/spec/classes/server_spec.rb @@ -1,145 +1,181 @@ require 'spec_helper' describe 'ssh::server' do let :default_params do { ensure: 'present', storeconfigs_enabled: true } end describe 'providing options' do let :params do { options: { 'TestString' => '/usr/bin', 'TestBoolean' => true } } end let :facts do { - osfamily: 'RedHat', - operatingsystemmajrelease: '6' + :os => { + 'family' => 'RedHat', + 'release' => { + 'major' => '6' + } + }, + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1' + }, + 'eth1' => { + 'ip' => '10.0.1.1' + }, + } + } } end it do is_expected.to contain_concat__fragment('global config').with( target: '/etc/ssh/sshd_config', content: '# File is managed by Puppet AcceptEnv LANG LC_* ChallengeResponseAuthentication no PrintMotd no Subsystem sftp /usr/libexec/openssh/sftp-server TestBoolean yes TestString /usr/bin UsePAM yes X11Forwarding yes ' # rubocop:enable EmptyLinesAroundArguments ) end end [{}, { ensure: 'latest', storeconfigs_enabled: true }, { ensure: 'present', storeconfigs_enabled: false }].each do |param_set| describe "when #{param_set == {} ? 'using default' : 'specifying'} class parameters" do let :param_hash do default_params.merge(param_set) end let :params do param_set end ['Debian'].each do |osfamily| let :facts do { - osfamily: osfamily + :os => { + 'family' => osfamily + }, + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1' + }, + 'eth1' => { + 'ip' => '10.0.1.1' + }, + } + } } end describe "on supported osfamily: #{osfamily}" do it { is_expected.to contain_class('ssh::params') } it { is_expected.to contain_package('openssh-server').with_ensure(param_hash[:ensure]) } it do is_expected.to contain_service('ssh').with( 'ensure' => 'running', 'enable' => true, 'hasrestart' => true, 'hasstatus' => true ) end it { is_expected.to contain_concat('/etc/ssh/sshd_config') } it do is_expected.to contain_concat__fragment('global config').with( target: '/etc/ssh/sshd_config', content: '# File is managed by Puppet AcceptEnv LANG LC_* ChallengeResponseAuthentication no PrintMotd no Subsystem sftp /usr/lib/openssh/sftp-server UsePAM yes X11Forwarding yes ' ) end end describe 'on Arch' do let :facts do { - osfamily: 'Archlinux', - lsbdistdescription: 'Arch Linux', - lsbdistid: 'Arch' + :os => { + 'family' => 'Archlinux' + }, + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1' + }, + 'eth1' => { + 'ip' => '10.0.1.1' + }, + } + } } end it { is_expected.to contain_class('ssh::params') } it do is_expected.to contain_package('openssh').with( ensure: param_hash[:ensure], name: 'openssh' ) end it do is_expected.to contain_service('sshd.service').with( 'ensure' => 'running', 'enable' => true, 'hasrestart' => true, 'hasstatus' => true ) end it { is_expected.to contain_concat('/etc/ssh/sshd_config') } it do is_expected.to contain_concat__fragment('global config').with( target: '/etc/ssh/sshd_config', content: '# File is managed by Puppet AcceptEnv LANG LC_* ChallengeResponseAuthentication no PrintMotd no Subsystem sftp /usr/lib/ssh/sftp-server UsePAM yes X11Forwarding yes ' ) end end end end end end diff --git a/spec/defines/client/config/user_spec.rb b/spec/defines/client/config/user_spec.rb index 47a2f8e..e0f1034 100644 --- a/spec/defines/client/config/user_spec.rb +++ b/spec/defines/client/config/user_spec.rb @@ -1,170 +1,184 @@ require 'spec_helper' describe 'ssh::client::config::user', type: :define do let :title do 'riton' end let :ssh_options do { 'HashKnownHosts' => 'yes', 'Host *.in2p3.fr' => { 'User' => 'riton', 'GSSAPIAuthentication' => 'no' } } end let :facts do { - osfamily: 'RedHat', - operatingsystemmajrelease: '6' + :os => { + 'family' => 'RedHat', + 'release' => { + 'major' => '6' + } + }, + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1' + }, + 'eth1' => { + 'ip' => '10.0.1.1' + }, + } + } } end describe 'with invalid parameters' do params = { ensure: ['somestate', 'expects a match for Enum'], target: ['./somedir', 'Pattern'], user_home_dir: ['./somedir', 'Pattern'], manage_user_ssh_dir: ['maybe', 'expects a Boolean'], options: ['the_options', 'Hash value'] } params.each do |param, value| context "with invalid value for #{param}" do let :params do { param => value[0] } end it { is_expected.not_to compile } end end end # describe 'with invalid parameters' describe 'with correct values' do describe 'with a user provided target' do let :target do '/root/.ssh/config' end let :params do { target: target } end it do is_expected.to contain_concat_file(target).with( ensure: 'present', tag: title ) is_expected.to contain_concat_fragment(title).with( tag: title, target: target ) end end # describe 'with a user provided target' describe 'user_home_dir behavior' do context 'with a user provided user_home_dir' do let :user_home_dir do '/path/to/home' end context 'with manage_user_ssh_dir default value' do let :params do { user_home_dir: user_home_dir } end it 'contains ssh directory and ssh config' do is_expected.to contain_file("#{user_home_dir}/.ssh").with( ensure: 'directory', owner: title, mode: '0700' ).that_comes_before("Concat_file[#{user_home_dir}/.ssh/config]") is_expected.to contain_concat_file("#{user_home_dir}/.ssh/config").with( ensure: 'present', owner: title, mode: '0600' ) end end # context 'with manage_user_ssh_dir default value' context 'with manage_user_ssh_dir set to false' do let :params do { user_home_dir: user_home_dir, manage_user_ssh_dir: false } end it do is_expected.not_to contain_file("#{user_home_dir}/.ssh") end end # context 'with manage_user_ssh_dir set to false' end # context 'with a user provided user_home_dir' context 'with no user provided user_home_dir' do it 'with manage_user_ssh_dir default value' do is_expected.to contain_file("/home/#{title}/.ssh").that_comes_before("Concat_file[/home/#{title}/.ssh/config]") is_expected.to contain_concat_file("/home/#{title}/.ssh/config") end context 'with manage_user_ssh_dir set to false' do let :params do { manage_user_ssh_dir: false } end it do is_expected.not_to contain_file("/home/#{title}/.ssh") end it do is_expected.to contain_concat_file("/home/#{title}/.ssh/config") end end # context 'with manage_user_ssh_dir set to false' end # context 'with no user provided user_home_dir' end # describe 'user_home_dir behavior' describe 'ssh configuration content' do let :params do { options: ssh_options } end it 'has single value' do is_expected.to contain_concat_fragment(title).with( content: %r{HashKnownHosts\s+yes}, target: "/home/#{title}/.ssh/config" ) end it 'has Hash value' do is_expected.to contain_concat_fragment(title).with( content: %r{Host \*\.in2p3\.fr\s*\n\s+GSSAPIAuthentication\s+no\s*\n\s+User\s+riton}, target: "/home/#{title}/.ssh/config" ) end end end # describe 'with correct values' end # vim: tabstop=2 shiftwidth=2 softtabstop=2 diff --git a/spec/defines/server/config/setting_spec.rb b/spec/defines/server/config/setting_spec.rb index 4d95a29..cc4ebf8 100644 --- a/spec/defines/server/config/setting_spec.rb +++ b/spec/defines/server/config/setting_spec.rb @@ -1,72 +1,86 @@ require 'spec_helper' describe 'ssh::server::config::setting', type: :define do let :title do 'something' end let :facts do { - osfamily: 'RedHat', - operatingsystemmajrelease: '6' + :os => { + 'family' => 'RedHat', + 'release' => { + 'major' => '6' + }, + }, + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1' + }, + 'eth1' => { + 'ip' => '10.0.1.1' + }, + } + } } end describe 'with key => "AllowGroups", value => "group1 group2"' do let :params do { key: 'AllowGroups', value: 'group1 group2' } end it do is_expected.to contain_concat__fragment('ssh_setting_something_AllowGroups').with_content(%r{\nAllowGroups group1 group2\n}) end end describe 'with key => "Somesetting", value => true' do let :params do { key: 'Somesetting', value: true } end it do is_expected.to contain_concat__fragment('ssh_setting_something_Somesetting').with_content(%r{\nSomesetting yes\n}) end end describe 'with key => "Foo", value => [1, 2]' do let :params do { key: 'Foo', value: [1, 2] } end it do is_expected.to contain_concat__fragment('ssh_setting_something_Foo').with_content(%r{\nFoo 1 2\n}) end end describe 'with key => "Bar", value => {"a" => "b"}' do let :params do { key: 'Bar', value: { 'a' => 'b' } } end it 'fails' do expect do is_expected.to compile end.to raise_error(%r{Hash values are not supported}) end end end # vim: tabstop=2 shiftwidth=2 softtabstop=2 diff --git a/spec/defines/server/host_key_spec.rb b/spec/defines/server/host_key_spec.rb index a009c53..3be4d31 100644 --- a/spec/defines/server/host_key_spec.rb +++ b/spec/defines/server/host_key_spec.rb @@ -1,166 +1,180 @@ require 'spec_helper' describe 'ssh::server::host_key', type: :define do let :title do 'something' end let(:pre_condition) { 'class {"::ssh::params": }' } let :facts do { - osfamily: 'RedHat', - operatingsystemmajrelease: '6' + :os => { + 'family' => 'RedHat', + 'release' => { + 'major' => '6' + }, + }, + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1' + }, + 'eth1' => { + 'ip' => '10.0.1.1' + }, + } + } } end describe 'with public_key_content, private_key_content and certificate_content' do let :params do { public_key_content: 'abc', private_key_content: 'bcd', certificate_content: 'cde' } end it do is_expected.to contain_file('something_pub'). with_content('abc'). with_ensure('present'). with_owner(0). with_group(0). with_mode('0644'). with_path('/etc/ssh/something.pub') is_expected.to contain_file('something_priv'). with_content('bcd'). with_ensure('present'). with_owner(0). with_group(0). with_mode('0600'). with_path('/etc/ssh/something') is_expected.to contain_file('something_cert'). with_content('cde'). with_ensure('present'). with_owner(0). with_group(0). with_mode('0644'). with_path('/etc/ssh/something-cert.pub') end end describe 'with public_key_content and private_key_content' do let :params do { public_key_content: 'abc', private_key_content: 'bcd' } end it do is_expected.to contain_file('something_pub'). with_content('abc'). with_ensure('present'). with_owner(0). with_group(0). with_mode('0644'). with_path('/etc/ssh/something.pub') is_expected.to contain_file('something_priv'). with_content('bcd'). with_ensure('present'). with_owner(0). with_group(0). with_mode('0600'). with_path('/etc/ssh/something') is_expected.not_to contain_file('something_cert') end end describe 'with *_key_content and *_key_source, *_key_source takes precedence' do let :params do { public_key_content: 'abc', public_key_source: 'a', private_key_content: 'bcd', private_key_source: 'b' } end it do is_expected.to contain_file('something_pub'). without_content. with_source('a'). with_ensure('present'). with_owner(0). with_group(0). with_mode('0644'). with_path('/etc/ssh/something.pub') is_expected.to contain_file('something_priv'). without_content. with_source('b'). with_ensure('present'). with_owner(0). with_group(0). with_mode('0600'). with_path('/etc/ssh/something') is_expected.not_to contain_file('something_cert') end end describe 'with private_key_content and no public_key_content' do let :params do { private_key_content: 'bcd' } end it 'fails' do expect do is_expected.to compile end.to raise_error(%r{You must provide either public_key_source or public_key_content parameter}) end end describe 'with public_key_content and no private_key_content' do let :params do { public_key_content: 'abc' } end it 'fails' do expect do is_expected.to compile end.to raise_error(%r{You must provide either private_key_source or private_key_content parameter}) end end describe 'with private_key_source and no public_key_source' do let :params do { private_key_source: 'bcd' } end it 'fails' do expect do is_expected.to compile end.to raise_error(%r{You must provide either public_key_source or public_key_content parameter}) end end describe 'with public_key_source and no private_key_source' do let :params do { public_key_source: 'abc' } end it 'fails' do expect do is_expected.to compile end.to raise_error(%r{You must provide either private_key_source or private_key_content parameter}) end end end # vim: tabstop=2 shiftwidth=2 softtabstop=2 diff --git a/spec/unit/facter/util/fact_ssh_client_version_spec.rb b/spec/unit/facter/util/fact_ssh_client_version_spec.rb index 76f2c55..877419f 100644 --- a/spec/unit/facter/util/fact_ssh_client_version_spec.rb +++ b/spec/unit/facter/util/fact_ssh_client_version_spec.rb @@ -1,26 +1,27 @@ require 'spec_helper' describe 'ssh_client_version_full' do + before { Facter.clear } + after { Facter.clear } + context 'when on a Linux host' do before do - Facter.clear - Facter.fact(:kernel).stubs(:value).returns('linux') - Facter::Util::Resolution.stubs(:which).with('ssh').returns('/usr/bin/ssh') - Facter::Util::Resolution.stubs(:exec).with('ssh -V 2>&1').returns('OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.8, OpenSSL 1.0.1f 6 Jan 2014') + allow(Facter.fact(:kernel)).to receive(:value).and_return('linux') + allow(Facter::Util::Resolution).to receive(:which).with('ssh').and_return('/usr/bin/ssh') + allow(Facter::Util::Resolution).to receive(:exec).with('ssh -V 2>&1').and_return('OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.8, OpenSSL 1.0.1f 6 Jan 2014') end it 'execs ssh -V and returns full version number' do expect(Facter.fact(:ssh_client_version_full).value).to eq('6.6.1p1') end end context 'when on a SunOS host' do before do - Facter.clear - Facter.fact(:kernel).stubs(:value).returns('SunOS') - Facter::Util::Resolution.stubs(:which).with('ssh').returns('/usr/bin/ssh') - Facter::Util::Resolution.stubs(:exec).with('ssh -V 2>&1').returns('Sun_SSH_2.4, SSH protocols 1.5/2.0, OpenSSL 0x100020bf') + allow(Facter.fact(:kernel)).to receive(:value).and_return('SunOS') + allow(Facter::Util::Resolution).to receive(:which).with('ssh').and_return('/usr/bin/ssh') + allow(Facter::Util::Resolution).to receive(:exec).with('ssh -V 2>&1').and_return('Sun_SSH_2.4, SSH protocols 1.5/2.0, OpenSSL 0x100020bf') end it 'execs ssh -V and returns full version number' do expect(Facter.fact(:ssh_client_version_full).value).to eq('2.4') end end end diff --git a/spec/unit/facter/util/fact_ssh_server_version_major_spec.rb b/spec/unit/facter/util/fact_ssh_server_version_major_spec.rb index 55e91be..d2f18f5 100644 --- a/spec/unit/facter/util/fact_ssh_server_version_major_spec.rb +++ b/spec/unit/facter/util/fact_ssh_server_version_major_spec.rb @@ -1,41 +1,41 @@ require 'spec_helper' describe Facter::Util::Fact do before do Facter.clear - Facter.fact(:kernel).stubs(:value).returns('linux') + allow(Facter.fact(:kernel)).to receive(:value).and_return('linux') end describe 'ssh_server_version_major' do context 'with 3 point semver syntax (6.6.1p1)' do context 'with ssh_server_version_full fact present returns major version' do before do - Facter.fact(:ssh_server_version_full).stubs(:value).returns('6.6.1p1') + allow(Facter.fact(:ssh_server_version_full)).to receive(:value).and_return('6.6.1p1') end it do expect(Facter.fact(:ssh_server_version_major).value).to eq('6') end end end context 'with 2 point semver syntax (7.2p2)' do context 'with ssh_server_version_full fact present returns major version' do before do - Facter.fact(:ssh_server_version_full).stubs(:value).returns('7.2p2') + allow(Facter.fact(:ssh_server_version_full)).to receive(:value).and_return('7.2p2') end it do expect(Facter.fact(:ssh_server_version_major).value).to eq('7') end end end context 'without ssh_server_version_full fact present returns nil' do before do - Facter.fact(:ssh_server_version_full).stubs(:value).returns(nil) + allow(Facter.fact(:ssh_server_version_full)).to receive(:value).and_return(nil) end it do expect(Facter.fact(:ssh_server_version_major).value).to be_nil end end end end diff --git a/spec/unit/facter/util/fact_ssh_server_version_spec.rb b/spec/unit/facter/util/fact_ssh_server_version_spec.rb index d4030b3..96d9bab 100644 --- a/spec/unit/facter/util/fact_ssh_server_version_spec.rb +++ b/spec/unit/facter/util/fact_ssh_server_version_spec.rb @@ -1,26 +1,27 @@ require 'spec_helper' describe 'ssh_server_version_full' do + before { Facter.clear } + after { Facter.clear } + context 'when on a Linux host' do before do - Facter.clear - Facter.fact(:kernel).stubs(:value).returns('linux') - Facter::Util::Resolution.stubs(:which).with('sshd').returns('/usr/sbin/sshd') - Facter::Util::Resolution.stubs(:exec).with('sshd -V 2>&1').returns('OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.8, OpenSSL 1.0.1f 6 Jan 2014') + allow(Facter.fact(:kernel)).to receive(:value).and_return('linux') + allow(Facter::Util::Resolution).to receive(:which).with('sshd').and_return('/usr/bin/sshd') + allow(Facter::Util::Resolution).to receive(:exec).with('sshd -V 2>&1').and_return('OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.8, OpenSSL 1.0.1f 6 Jan 2014') end it 'execs sshd -V and returns full version number' do expect(Facter.fact(:ssh_server_version_full).value).to eq('6.6.1p1') end end context 'when on a SunOS host' do before do - Facter.clear - Facter.fact(:kernel).stubs(:value).returns('SunOS') - Facter::Util::Resolution.stubs(:which).with('sshd').returns('/usr/bin/sshd') - Facter::Util::Resolution.stubs(:exec).with('sshd -V 2>&1').returns('Sun_SSH_2.4, SSH protocols 1.5/2.0, OpenSSL 0x100020bf') + allow(Facter.fact(:kernel)).to receive(:value).and_return('SunOS') + allow(Facter::Util::Resolution).to receive(:which).with('sshd').and_return('/usr/bin/sshd') + allow(Facter::Util::Resolution).to receive(:exec).with('sshd -V 2>&1').and_return('Sun_SSH_2.4, SSH protocols 1.5/2.0, OpenSSL 0x100020bf') end it 'execs sshd -V and returns full version number' do expect(Facter.fact(:ssh_server_version_full).value).to eq('2.4') end end end diff --git a/tests/init.pp b/tests/init.pp deleted file mode 100644 index 6687c2c..0000000 --- a/tests/init.pp +++ /dev/null @@ -1 +0,0 @@ -class { '::ssh::server': } diff --git a/tests/server.pp b/tests/server.pp deleted file mode 100644 index 93a2381..0000000 --- a/tests/server.pp +++ /dev/null @@ -1 +0,0 @@ -include ::ssh::server