diff --git a/.fixtures.yml b/.fixtures.yml index 4f3f67b..e0c5303 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -4,6 +4,10 @@ fixtures: auditd: https://github.com/simp/pupmod-simp-auditd augeasproviders_core: https://github.com/simp/augeasproviders_core augeasproviders_grub: https://github.com/simp/augeasproviders_grub + # This needs to be in place for the rspec-puppet Hiera 5 hook to work + # No idea why, it may be because Puppet sees a custom backend and loads all + # of the global parts. + compliance_markup: https://github.com/simp/pupmod-simp-compliance_markup concat: # master is beyond 4.1.1, but has breaking changes to # how fragments are ordered (MODULES-6625) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 520e38c..bea2efa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -70,7 +70,7 @@ variables: #----------------------------------------------------------------------- .pup_4: &pup_4 - image: 'ruby:2.4' + image: 'ruby:2.1' variables: PUPPET_VERSION: '~> 4.0' MATRIX_RUBY_VERSION: '2.1' diff --git a/.travis.yml b/.travis.yml index a1fb500..c6c605c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,6 +38,7 @@ addons: before_install: - rm -f Gemfile.lock + - gem install -v '~> 1.16' bundler global: - STRICT_VARIABLES=yes diff --git a/CHANGELOG b/CHANGELOG index 0db64b9..7c9e99a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,12 @@ +* Mon Jan 21 2019 Trevor Vaughan - 6.4.0 +- Add ability for users to override stunnel::connection and stunnel::instance + options either globally or by specific identified instance. +- Fixed stunnel::connection and stunnel::instance template bugs + - sni is not applicable on EL6 + - retry is only applicable when exec is specified and + needs to be translated from a boolean to 'yes'/'no' + - session is only applicable on EL6 + * Thu Dec 06 2018 Chris Tessmer - 6.3.4 - Fix bug that broke `puppet describe ` diff --git a/manifests/connection.pp b/manifests/connection.pp index c22efc5..08edcbc 100644 --- a/manifests/connection.pp +++ b/manifests/connection.pp @@ -1,5 +1,19 @@ # Set up a stunnel connection for the service ``$name`` # +# NOTE: Since many of the parameters here may need to be modified on a +# case-by-base basis, this defined type uses capabilities presented by the +# ``simplib::dlookup`` function to allow for either global overrides or +# instance-specific overrides. +# +# Global overrides work the same way as classes +# (``stunnel::instance::ssl_version: 'TLSv1.2'``) but will affect **all** +# instances of the defined type that are not specifically overridden as shown +# below. +# +# Instance specific overrides preclude the need for a resource collector in +# that you can place the follwing in Hiera to affect a single instance named +# ``rsync``: ``Stunnel::Connection[rsync]::ssl_version: 'TLSv1.2'`` +# # @example Add an Rsync listener # stunnel::connection ('rsync': # accept => '873', @@ -69,8 +83,6 @@ # The ECDH curve name to use. To get a list of supported curves use: # ``openssl ecparam -list_curves`` on your *client* # -# * This option is only valid on EL 7+ -# # @param ssl_version # Dictate the SSL version that can be used on the system # @@ -132,8 +144,6 @@ # @param engine_num # The engine number from which to read the private key # -# * This option is only supported on RHEL/CentOS 7+ -# # @param pty # Reserve and assign a pty to a program that is run by stunnel inetd-style # using the ``exec`` option @@ -199,43 +209,43 @@ Stunnel::Connect $connect, Variant[Simplib::Port, Simplib::Host::Port] $accept, Boolean $client = true, - Enum['rr','prio'] $failover = 'rr', - Optional[String] $sni = undef, - Optional[Stdlib::Absolutepath] $app_pki_key = undef, - Optional[Stdlib::Absolutepath] $app_pki_cert = undef, - Stdlib::Absolutepath $app_pki_cacert = '/etc/pki/simp_apps/stunnel/x509/cacerts/cacerts.pem', - Stdlib::Absolutepath $app_pki_crl = '/etc/pki/simp_apps/stunnel/x509/crl', - Array[String] $openssl_cipher_suite = ['HIGH','-SSLv2'], - Optional[String] $curve = undef, - Optional[String] $ssl_version = undef, - Array[String] $options = [], - Integer $verify = 2, - Optional[Simplib::URI] $ocsp = undef, - Stunnel::OcspFlags $ocsp_flags = [], - Optional[String] $local = undef, - Optional[String] $protocol = undef, - Optional[Enum['basic','NTLM']] $protocol_authentication = undef, - Optional[String] $protocol_host = undef, - Optional[String] $protocol_username = undef, - Optional[String] $protocol_password = undef, - Boolean $delay = false, - Optional[Integer] $engine_num = undef, - Optional[String] $exec = undef, - Array[String] $execargs = [], - Boolean $pty = false, - Boolean $renegotiation = true, - Boolean $reset = true, - Boolean $retry = false, - Optional[Integer] $session_cache_size = undef, - Optional[Integer] $session_cache_timeout = undef, - Optional[Integer] $stack = undef, - Optional[Integer] $timeout_busy = undef, - Optional[Integer] $timeout_close = undef, - Optional[Integer] $timeout_connect = undef, - Optional[Integer] $timeout_idle = undef, - Simplib::Netlist $trusted_nets = simplib::lookup('simp_options::trusted_nets', { 'default_value' => ['127.0.0.1'] }), - Boolean $firewall = simplib::lookup('simp_options::firewall', { 'default_value' => false }), - Boolean $tcpwrappers = simplib::lookup('simp_options::tcpwrappers', { 'default_value' => false }) + Enum['rr','prio'] $failover = simplib::dlookup('stunnel::connection', 'failover', $name, { 'default_value' => 'rr' }), + Optional[String] $sni = simplib::dlookup('stunnel::connection', 'sni', $name, { 'default_value' => undef }), + Optional[Stdlib::Absolutepath] $app_pki_key = simplib::dlookup('stunnel::connection', 'app_pki_key', $name, { 'default_value' => undef }), + Optional[Stdlib::Absolutepath] $app_pki_cert = simplib::dlookup('stunnel::connection', 'app_pki_cert', $name, { 'default_value' => undef }), + Stdlib::Absolutepath $app_pki_cacert = simplib::dlookup('stunnel::connection', 'app_pki_cacert', $name, { 'default_value' => '/etc/pki/simp_apps/stunnel/x509/cacerts/cacerts.pem' }), + Stdlib::Absolutepath $app_pki_crl = simplib::dlookup('stunnel::connection', 'app_pki_crl', $name, { 'default_value' => '/etc/pki/simp_apps/stunnel/x509/crl' }), + Array[String] $openssl_cipher_suite = simplib::dlookup('stunnel::connection', 'openssl_cipher_suite', $name, { 'default_value' => ['HIGH','-SSLv2'] }), + Optional[String] $curve = simplib::dlookup('stunnel::connection', 'curve', $name, { 'default_value' => undef }), + Optional[String] $ssl_version = simplib::dlookup('stunnel::connection', 'ssl_version', $name, { 'default_value' => undef }), + Array[String] $options = simplib::dlookup('stunnel::connection', 'options', $name, { 'default_value' => [] }), + Integer $verify = simplib::dlookup('stunnel::connection', 'verify', $name, { 'default_value' => 2 }), + Optional[Simplib::URI] $ocsp = simplib::dlookup('stunnel::connection', 'ocsp', $name, { 'default_value' => undef }), + Stunnel::OcspFlags $ocsp_flags = simplib::dlookup('stunnel::connection', 'ocsp_flags', $name, { 'default_value' => [] }), + Optional[String] $local = simplib::dlookup('stunnel::connection', 'local', $name, { 'default_value' => undef }), + Optional[String] $protocol = simplib::dlookup('stunnel::connection', 'protocol', $name, { 'default_value' => undef }), + Optional[Enum['basic','NTLM']] $protocol_authentication = simplib::dlookup('stunnel::connection', 'protocol_authentication', $name, { 'default_value' => undef }), + Optional[String] $protocol_host = simplib::dlookup('stunnel::connection', 'protocol_host', $name, { 'default_value' => undef }), + Optional[String] $protocol_username = simplib::dlookup('stunnel::connection', 'protocol_username', $name, { 'default_value' => undef }), + Optional[String] $protocol_password = simplib::dlookup('stunnel::connection', 'protocol_password', $name, { 'default_value' => undef }), + Boolean $delay = simplib::dlookup('stunnel::connection', 'delay', $name, { 'default_value' => false }), + Optional[Integer] $engine_num = simplib::dlookup('stunnel::connection', 'engine_num', $name, { 'default_value' => undef }), + Optional[String] $exec = simplib::dlookup('stunnel::connection', 'exec', $name, { 'default_value' => undef }), + Array[String] $execargs = simplib::dlookup('stunnel::connection', 'execargs', $name, { 'default_value' => [] }), + Boolean $pty = simplib::dlookup('stunnel::connection', 'pty', $name, { 'default_value' => false }), + Boolean $renegotiation = simplib::dlookup('stunnel::connection', 'renegotiation', $name, { 'default_value' => true }), + Boolean $reset = simplib::dlookup('stunnel::connection', 'reset', $name, { 'default_value' => true }), + Boolean $retry = simplib::dlookup('stunnel::connection', 'retry', $name, { 'default_value' => false }), + Optional[Integer] $session_cache_size = simplib::dlookup('stunnel::connection', 'session_cache_size', $name, { 'default_value' => undef }), + Optional[Integer] $session_cache_timeout = simplib::dlookup('stunnel::connection', 'session_cache_timeout', $name, { 'default_value' => undef }), + Optional[Integer] $stack = simplib::dlookup('stunnel::connection', 'stack', $name, { 'default_value' => undef }), + Optional[Integer] $timeout_busy = simplib::dlookup('stunnel::connection', 'timeout_busy', $name, { 'default_value' => undef }), + Optional[Integer] $timeout_close = simplib::dlookup('stunnel::connection', 'timeout_close', $name, { 'default_value' => undef }), + Optional[Integer] $timeout_connect = simplib::dlookup('stunnel::connection', 'timeout_connect', $name, { 'default_value' => undef }), + Optional[Integer] $timeout_idle = simplib::dlookup('stunnel::connection', 'timeout_idle', $name, { 'default_value' => undef }), + Simplib::Netlist $trusted_nets = pick(simplib::dlookup('stunnel::connection', 'trusted_nets', $name, {'default_value' => undef }), simplib::lookup('simp_options::trusted_nets', { 'default_value' => ['127.0.0.1'] })), + Boolean $firewall = pick(simplib::dlookup('stunnel::connection', 'firewall', $name, {'default_value' => undef }), simplib::lookup('simp_options::firewall', { 'default_value' => false })), + Boolean $tcpwrappers = pick(simplib::dlookup('stunnel::connection', 'tcpwrappers', $name, {'default_value' => undef }), simplib::lookup('simp_options::tcpwrappers', { 'default_value' => false })) ) { $_dport = split(to_string($accept),':')[-1] diff --git a/manifests/instance.pp b/manifests/instance.pp index 564bcf4..073e445 100644 --- a/manifests/instance.pp +++ b/manifests/instance.pp @@ -1,5 +1,19 @@ # Set up a stunnel connection with a unique configuration and service # +# NOTE: Since many of the parameters here may need to be modified on a +# case-by-base basis, this defined type uses capabilities presented by the +# ``simplib::dlookup`` function to allow for either global overrides or +# instance-specific overrides. +# +# Global overrides work the same way as classes +# (``stunnel::instance::ssl_version: 'TLSv1.2'``) but will affect **all** +# instances of the defined type that are not specifically overridden as shown +# below. +# +# Instance specific overrides preclude the need for a resource collector in +# that you can place the follwing in Hiera to affect a single instance named +# ``rsync``: ``Stunnel::Instance[rsync]::ssl_version: 'TLSv1.2'`` +# # @example Add an Rsync listener # stunnel::instance {'rsync': # accept => 873, @@ -198,70 +212,70 @@ define stunnel::instance( Stunnel::Connect $connect, Variant[Simplib::Port, Simplib::Host::Port] $accept, - - Simplib::Netlist $trusted_nets = simplib::lookup('simp_options::trusted_nets', { 'default_value' => ['127.0.0.1'] }), - Boolean $firewall = simplib::lookup('simp_options::firewall', { 'default_value' => false }), - Boolean $haveged = simplib::lookup('simp_options::haveged', { 'default_value' => true }), - Boolean $tcpwrappers = simplib::lookup('simp_options::tcpwrappers', { 'default_value' => false }), - Variant[Enum['simp'],Boolean] $pki = simplib::lookup('simp_options::pki', { 'default_value' => false }), - Stdlib::Absolutepath $app_pki_dir = "/etc/pki/simp_apps/stunnel_${name}/x509", - String $app_pki_external_source = simplib::lookup('simp_options::pki::source', { 'default_value' => '/etc/pki/simp/x509' }), - Stdlib::Absolutepath $app_pki_key = "${app_pki_dir}/private/${facts['fqdn']}.pem", - Stdlib::Absolutepath $app_pki_cert = "${app_pki_dir}/public/${facts['fqdn']}.pub", - Stdlib::Absolutepath $app_pki_ca_dir = "${app_pki_dir}/cacerts", - Stdlib::Absolutepath $app_pki_cacert = "${app_pki_dir}/cacerts/cacerts.pem", - Stdlib::Absolutepath $app_pki_crl = "${app_pki_dir}/crl", - Optional[Stdlib::Absolutepath] $chroot = undef, Boolean $client = true, - Optional[Enum['zlib','rle']] $compression = undef, - Optional[String] $curve = undef, - Boolean $delay = false, - Optional[String] $egd = undef, - String $engine = 'auto', - Optional[String] $engine_ctrl = undef, - Optional[Integer] $engine_num = undef, - Optional[String] $exec = undef, - Array[String] $execargs = [], - Enum['rr','prio'] $failover = 'rr', - Boolean $fips = simplib::lookup('simp_options::fips', { 'default_value' => pick($facts['fips_enabled'], false) }), - Optional[String] $local = undef, - Optional[Simplib::URI] $ocsp = undef, - Stunnel::OcspFlags $ocsp_flags = [], - Array[String] $openssl_cipher_suite = ['HIGH','-SSLv2'], - Array[String] $options = [], - Optional[Stdlib::Absolutepath] $output = undef, - Optional[Stdlib::Absolutepath] $pid = undef, - Optional[String] $protocol = undef, - Optional[Enum['basic','NTLM']] $protocol_authentication = undef, - Optional[String] $protocol_host = undef, - Optional[String] $protocol_username = undef, - Optional[String] $protocol_password = undef, - Boolean $pty = false, - Boolean $renegotiation = true, - Boolean $reset = true, - Boolean $retry = false, - Optional[Integer] $rnd_bytes = undef, - Optional[Stdlib::Absolutepath] $rnd_file = undef, - Boolean $rnd_overwrite = false, - Optional[Integer] $session_cache_size = undef, - Optional[Integer] $session_cache_timeout = undef, - String $setuid = 'stunnel', - String $setgid = 'stunnel', - Integer $uid = 600, - Integer $gid = $uid, - Optional[String] $sni = undef, - Array[String] $socket_options = [], - Optional[String] $ssl_version = undef, - Optional[Integer] $stack = undef, - String $stunnel_debug = 'err', - Boolean $syslog = simplib::lookup('simp_options::syslog', { 'default_value' => false }), - Optional[Integer] $timeout_busy = undef, - Optional[Integer] $timeout_close = undef, - Optional[Integer] $timeout_connect = undef, - Optional[Integer] $timeout_idle = undef, - Integer $verify = 2, - Optional[Array[String]] $systemd_wantedby = undef, - Optional[Array[String]] $systemd_requiredby = undef, + + Simplib::Netlist $trusted_nets = simplib::dlookup('stunnel::instance', 'trusted_nets', $name, { 'default_value' => simplib::lookup('simp_options::trusted_nets', { 'default_value' => ['127.0.0.1'] }) }), + Boolean $firewall = simplib::dlookup('stunnel::instance', 'firewall', $name, { 'default_value' => simplib::lookup('simp_options::firewall', { 'default_value' => false }) }), + Boolean $haveged = simplib::dlookup('stunnel::instance', 'haveged', $name, { 'default_value' => simplib::lookup('simp_options::haveged', { 'default_value' => true }) }), + Boolean $tcpwrappers = simplib::dlookup('stunnel::instance', 'tcpwrappers', $name, { 'default_value' => simplib::lookup('simp_options::tcpwrappers', { 'default_value' => false }) }), + Variant[Enum['simp'],Boolean] $pki = simplib::dlookup('stunnel::instance', 'pki', $name, { 'default_value' => simplib::lookup('simp_options::pki', { 'default_value' => false }) }), + Stdlib::Absolutepath $app_pki_dir = simplib::dlookup('stunnel::instance', 'app_pki_dir', $name, { 'default_value' => "/etc/pki/simp_apps/stunnel_${name}/x509" }), + String $app_pki_external_source = simplib::dlookup('stunnel::instance', 'app_pki_external_source', $name, { 'default_value' => simplib::lookup('simp_options::pki::source', { 'default_value' => '/etc/pki/simp/x509' }) }), + Stdlib::Absolutepath $app_pki_key = simplib::dlookup('stunnel::instance', 'app_pki_key', $name, { 'default_value' => "${app_pki_dir}/private/${facts['fqdn']}.pem" }), + Stdlib::Absolutepath $app_pki_cert = simplib::dlookup('stunnel::instance', 'app_pki_cert', $name, { 'default_value' => "${app_pki_dir}/public/${facts['fqdn']}.pub" }), + Stdlib::Absolutepath $app_pki_ca_dir = simplib::dlookup('stunnel::instance', 'app_pki_ca_dir', $name, { 'default_value' => "${app_pki_dir}/cacerts" }), + Stdlib::Absolutepath $app_pki_cacert = simplib::dlookup('stunnel::instance', 'app_pki_cacert', $name, { 'default_value' => "${app_pki_dir}/cacerts/cacerts.pem" }), + Stdlib::Absolutepath $app_pki_crl = simplib::dlookup('stunnel::instance', 'app_pki_crl', $name, { 'default_value' => "${app_pki_dir}/crl" }), + Optional[Stdlib::Absolutepath] $chroot = simplib::dlookup('stunnel::instance', 'chroot', $name, { 'default_value' => undef }), + Optional[Enum['zlib','rle']] $compression = simplib::dlookup('stunnel::instance', 'compression', $name, { 'default_value' => undef }), + Optional[String] $curve = simplib::dlookup('stunnel::instance', 'curve', $name, { 'default_value' => undef }), + Boolean $delay = simplib::dlookup('stunnel::instance', 'delay', $name, { 'default_value' => false }), + Optional[String] $egd = simplib::dlookup('stunnel::instance', 'egd', $name, { 'default_value' => undef }), + String $engine = simplib::dlookup('stunnel::instance', 'engine', $name, { 'default_value' => 'auto' }), + Optional[String] $engine_ctrl = simplib::dlookup('stunnel::instance', 'engine_ctrl', $name, { 'default_value' => undef }), + Optional[Integer] $engine_num = simplib::dlookup('stunnel::instance', 'engine_num', $name, { 'default_value' => undef }), + Optional[String] $exec = simplib::dlookup('stunnel::instance', 'exec', $name, { 'default_value' => undef }), + Array[String] $execargs = simplib::dlookup('stunnel::instance', 'execargs', $name, { 'default_value' => [] }), + Enum['rr','prio'] $failover = simplib::dlookup('stunnel::instance', 'failover', $name, { 'default_value' => 'rr' }), + Boolean $fips = simplib::dlookup('stunnel::instance', 'fips', $name, { 'default_value' => simplib::lookup('simp_options::fips', { 'default_value' => pick($facts['fips_enabled'], false) }) }), + Optional[String] $local = simplib::dlookup('stunnel::instance', 'local', $name, { 'default_value' => undef }), + Optional[Simplib::URI] $ocsp = simplib::dlookup('stunnel::instance', 'ocsp', $name, { 'default_value' => undef }), + Stunnel::OcspFlags $ocsp_flags = simplib::dlookup('stunnel::instance', 'ocsp_flags', $name, { 'default_value' => [] }), + Array[String] $openssl_cipher_suite = simplib::dlookup('stunnel::instance', 'openssl_cipher_suite', $name, { 'default_value' => ['HIGH','-SSLv2'] }), + Array[String] $options = simplib::dlookup('stunnel::instance', 'options', $name, { 'default_value' => [] }), + Optional[Stdlib::Absolutepath] $output = simplib::dlookup('stunnel::instance', 'output', $name, { 'default_value' => undef }), + Optional[Stdlib::Absolutepath] $pid = simplib::dlookup('stunnel::instance', 'pid', $name, { 'default_value' => undef }), + Optional[String] $protocol = simplib::dlookup('stunnel::instance', 'protocol', $name, { 'default_value' => undef }), + Optional[Enum['basic','NTLM']] $protocol_authentication = simplib::dlookup('stunnel::instance', 'protocol_authentication', $name, { 'default_value' => undef }), + Optional[String] $protocol_host = simplib::dlookup('stunnel::instance', 'protocol_host', $name, { 'default_value' => undef }), + Optional[String] $protocol_username = simplib::dlookup('stunnel::instance', 'protocol_username', $name, { 'default_value' => undef }), + Optional[String] $protocol_password = simplib::dlookup('stunnel::instance', 'protocol_password', $name, { 'default_value' => undef }), + Boolean $pty = simplib::dlookup('stunnel::instance', 'pty', $name, { 'default_value' => false }), + Boolean $renegotiation = simplib::dlookup('stunnel::instance', 'renegotiation', $name, { 'default_value' => true }), + Boolean $reset = simplib::dlookup('stunnel::instance', 'reset', $name, { 'default_value' => true }), + Boolean $retry = simplib::dlookup('stunnel::instance', 'retry', $name, { 'default_value' => false }), + Optional[Integer] $rnd_bytes = simplib::dlookup('stunnel::instance', 'rnd_bytes', $name, { 'default_value' => undef }), + Optional[Stdlib::Absolutepath] $rnd_file = simplib::dlookup('stunnel::instance', 'rnd_file', $name, { 'default_value' => undef }), + Boolean $rnd_overwrite = simplib::dlookup('stunnel::instance', 'rnd_overwrite', $name, { 'default_value' => false }), + Optional[Integer] $session_cache_size = simplib::dlookup('stunnel::instance', 'session_cache_size', $name, { 'default_value' => undef }), + Optional[Integer] $session_cache_timeout = simplib::dlookup('stunnel::instance', 'session_cache_timeout', $name, { 'default_value' => undef }), + String $setuid = simplib::dlookup('stunnel::instance', 'setuid', $name, { 'default_value' => 'stunnel' }), + String $setgid = simplib::dlookup('stunnel::instance', 'setgid', $name, { 'default_value' => 'stunnel' }), + Integer $uid = simplib::dlookup('stunnel::instance', 'uid', $name, { 'default_value' => 600 }), + Integer $gid = simplib::dlookup('stunnel::instance', 'gid', $name, { 'default_value' => $uid }), + Optional[String] $sni = simplib::dlookup('stunnel::instance', 'sni', $name, { 'default_value' => undef }), + Array[String] $socket_options = simplib::dlookup('stunnel::instance', 'socket_options', $name, { 'default_value' => [] }), + Optional[String] $ssl_version = simplib::dlookup('stunnel::instance', 'ssl_version', $name, { 'default_value' => undef }), + Optional[Integer] $stack = simplib::dlookup('stunnel::instance', 'stack', $name, { 'default_value' => undef }), + String $stunnel_debug = simplib::dlookup('stunnel::instance', 'stunnel_debug', $name, { 'default_value' => 'err' }), + Boolean $syslog = simplib::dlookup('stunnel::instance', 'syslog', $name, { 'default_value' => simplib::lookup('simp_options::syslog', { 'default_value' => false }) }), + Optional[Integer] $timeout_busy = simplib::dlookup('stunnel::instance', 'timeout_busy', $name, { 'default_value' => undef }), + Optional[Integer] $timeout_close = simplib::dlookup('stunnel::instance', 'timeout_close', $name, { 'default_value' => undef }), + Optional[Integer] $timeout_connect = simplib::dlookup('stunnel::instance', 'timeout_connect', $name, { 'default_value' => undef }), + Optional[Integer] $timeout_idle = simplib::dlookup('stunnel::instance', 'timeout_idle', $name, { 'default_value' => undef }), + Integer $verify = simplib::dlookup('stunnel::instance', 'verify', $name, { 'default_value' => 2 }), + Optional[Array[String]] $systemd_wantedby = simplib::dlookup('stunnel::instance', 'systemd_wantedby', $name, { 'default_value' => undef }), + Optional[Array[String]] $systemd_requiredby = simplib::dlookup('stunnel::instance', 'systemd_requiredby', $name, { 'default_value' => undef }), ){ $_safe_name = regsubst($name, '(/|\s)', '__') $_dport = split(to_string($accept),':')[-1] diff --git a/metadata.json b/metadata.json index 241e730..888cbf4 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "simp-stunnel", - "version": "6.3.4", + "version": "6.4.0", "author": "SIMP Team", "summary": "manages stunnel with PKI support", "license": "Apache-2.0", @@ -38,7 +38,7 @@ }, { "name": "simp/simplib", - "version_requirement": ">= 3.1.0 < 4.0.0" + "version_requirement": ">= 3.12.0 < 4.0.0" }, { "name": "simp/tcpwrappers", @@ -71,7 +71,7 @@ "requirements": [ { "name": "puppet", - "version_requirement": ">= 4.7.0 < 6.0.0" + "version_requirement": ">= 4.10.4 < 6.0.0" } ] } diff --git a/spec/classes/config_spec.rb b/spec/classes/config_spec.rb index 226eaa3..1b8ef70 100644 --- a/spec/classes/config_spec.rb +++ b/spec/classes/config_spec.rb @@ -188,6 +188,11 @@ end context 'with pid specified' do + # Change a param to force a recompile and full hiera lookup + let(:params) {{ + fips: true + }} + # I have to go to hiera for this... # stunnel::config::pid: /var/opt/run/stunnel.pid let(:hieradata) { 'pid' } diff --git a/spec/defines/connection_spec.rb b/spec/defines/connection_spec.rb index 41bbdcc..4c99dfd 100644 --- a/spec/defines/connection_spec.rb +++ b/spec/defines/connection_spec.rb @@ -2,11 +2,45 @@ describe 'stunnel::connection' do context 'supported operating systems' do - on_supported_os.each do |os, facts| + on_supported_os.each do |os, os_facts| context "on #{os}" do - let(:facts){ facts } + let(:facts){ os_facts } - context "using iptables" do + context 'with default parameters' do + let(:title){ 'test_tunnel' } + let(:params){{ + :connect => [2048,2049], + :accept => '10.1.2.3:20490', + }} + + it { is_expected.to compile.with_all_deps } + it { is_expected.to create_stunnel__instance__reserve_port('20490') } + it { is_expected.to create_class('stunnel::monolithic') } + it do + expected = <<-EOM +[test_tunnel] +connect = 2048 +connect = 2049 +accept = 10.1.2.3:20490 +client = yes +failover = rr +key = /etc/pki/simp_apps/stunnel/x509/private/foo.example.com.pem +cert = /etc/pki/simp_apps/stunnel/x509/public/foo.example.com.pub +CAfile = /etc/pki/simp_apps/stunnel/x509/cacerts/cacerts.pem +CRLpath = /etc/pki/simp_apps/stunnel/x509/crl +ciphers = HIGH:-SSLv2 +verify = 2 +delay = no + EOM + unless facts[:os][:release][:major] < '7' + expected += "renegotiation = yes\nreset = yes\n" + end + is_expected.to create_concat__fragment("stunnel_connection_#{title}").with_content(expected) + end + + end + + context 'using iptables' do let(:title){ 'nfs' } let(:params){{ :client => false, @@ -16,6 +50,7 @@ :firewall => true }} it { is_expected.to compile.with_all_deps } + it { is_expected.to create_stunnel__instance__reserve_port('20490') } it { is_expected.to create_iptables__listen__tcp_stateful("allow_stunnel_#{title}").with({ :trusted_nets => ['any'], :dports => [params[:accept].to_s.split(':')[-1]] @@ -23,7 +58,7 @@ } end - context "using tcpwrappers" do + context 'using tcpwrappers' do let(:title){ 'nfs' } let(:params){{ :tcpwrappers => true, @@ -36,7 +71,7 @@ it { is_expected.to create_tcpwrappers__allow("allow_stunnel_#{title}").with_pattern(['any']) } end - context "setting ocsp options" do + context 'setting ocsp options' do let(:title){ 'nfs' } let(:params){{ :client => false, @@ -44,10 +79,194 @@ :accept => 20490, :trusted_nets => ['any'], :ocsp => 'http://foo.bar.baz', - :ocsp_flags => ['NOCERTS'] + :ocsp_flags => ['NOCERTS', 'NOCHAIN'] }} it { is_expected.to compile.with_all_deps } - it { is_expected.to create_concat__fragment("stunnel_connection_#{title}").with_content(/NOCERTS/) } + it { is_expected.to create_concat__fragment("stunnel_connection_#{title}").with_content(/OCSPFlag = NOCERTS/) } + it { is_expected.to create_concat__fragment("stunnel_connection_#{title}").with_content(/OCSPFlag = NOCHAIN/) } + end + + context 'with other parameters set' do + let(:title){ 'test_tunnel' } + let(:params){{ + :connect => [2048,2049], + :accept => '10.1.2.3:20490', + :curve => 'prime256v1', + :local => '1.2.3.4', + :options => ['SSL_OP_NETSCAPE_CHALLENGE_BUG', 'SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS'], + :protocol => 'connect', + :protocol_authentication => 'basic', + :protocol_host => '1.2.3.5:2050', + :protocol_password => 'some_password', + :protocol_username => 'some_user', + :engine_num => 1, + :exec => '/some/exec', + :execargs => ['arg1', 'arg2'], + :session_cache_timeout => 20, + :session_cache_size => 1000, + :sni => 'test.sni.server', + :ssl_version => 'TLSv1', + :stack => 1024, + :timeout_busy => 5, + :timeout_close => 10, + :timeout_connect => 15, + :timeout_idle => 20 + }} + + it { is_expected.to compile.with_all_deps } + + if os_facts[:os][:release][:major] < '7' + it { is_expected.to create_concat__fragment("stunnel_connection_#{title}").with_content(/session = 20/) } + else + [ /sni = test.sni.server/, + /sessionCacheTimeout = 20/, + /sessionCacheSize = 1000/, + /renegotiation = yes/, + /reset = yes/ + ].each do |exp_regex| + it { is_expected.to create_concat__fragment("stunnel_connection_#{title}").with_content(exp_regex) } + end + end + + [ /curve = prime256v1/, + /sslVersion = TLSv1/, + /options = SSL_OP_NETSCAPE_CHALLENGE_BUG/, + /options = SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS/, + /local = 1.2.3.4/, + /protocol = connect/, + /protocolAuthentication = basic/, + /protocolHost = 1\.2\.3\.5:2050/, + /protocolPassword = some_password/, + /protocolUsername = some_user/, + /engineNum = 1/, + /exec = \/some\/exec/, + /execargs = arg1 arg2/, + /pty = no/, + /retry = no/, + /stack = 1024/, + /TIMEOUTbusy = 5/, + /TIMEOUTclose = 10/, + /TIMEOUTconnect = 15/, + /TIMEOUTidle = 20/ + ].each do |exp_regex| + it { is_expected.to create_concat__fragment("stunnel_connection_#{title}").with_content(exp_regex) } + end + end + + context 'with Hiera overrides' do + let(:pre_condition) { <<-EOM + stunnel::connection{ 'nfs_client': + accept => '127.0.0.1:2049', + connect => ['my.nfs.host:20490'] + } + EOM + } + + let(:title){ 'nfs' } + let(:params){{ + :client => false, + :connect => [2049], + :accept => 20490, + :trusted_nets => ['any'], + # Needed to force a recompile in each context + :ocsp => ocsp, + :ocsp_flags => ['NOCERTS'] + }} + + context 'global override' do + let(:ocsp) { 'https://global.bar.baz' } + let(:hieradata){ 'defined_type_global_override' } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to create_stunnel__connection(title).with( + :app_pki_cacert => '/some/global/cacerts.pem', + :app_pki_cert => '/some/global/test.pub', + :app_pki_crl => '/some/global/crl', + :app_pki_key => '/some/global/test.pem', + :curve => 'prime256v1', + :delay => true, + :engine_num => 1, + :exec => '/some/exec', + :execargs => ['arg1', 'arg2'], + :failover => 'prio', + :firewall => true, + :local => '1.2.3.4', + :options => ['SSL_OP_NETSCAPE_CHALLENGE_BUG' ], + :ocsp => 'https://global.bar.baz', + :ocsp_flags => [ 'NOCERTS' ], + :openssl_cipher_suite => [ 'AES128-SHA256' ], + :protocol => 'connect', + :protocol_authentication => 'basic', + :protocol_host => '1.2.3.5:2050', + :protocol_password => 'some_password', + :protocol_username => 'some_user', + :pty => true, + :renegotiation => false, + :reset => false, + :retry => true, + :session_cache_size => 20, + :session_cache_timeout => 1000, + :sni => 'global.sni.server', + :ssl_version => 'TLSv1', + :stack => 1024, + :tcpwrappers => true, + :timeout_busy => 5, + :timeout_close => 10, + :timeout_connect => 15, + :timeout_idle => 20, + :trusted_nets => [ 'any' ], + :verify => 4, + ) } + + it { is_expected.to create_stunnel__connection("nfs_client").with( + :app_pki_cacert => '/some/global/cacerts.pem', + :app_pki_cert => '/some/global/test.pub', + :app_pki_crl => '/some/global/crl', + :app_pki_key => '/some/global/test.pem', + :curve => 'prime256v1', + :delay => true, + :engine_num => 1, + :exec => '/some/exec', + :execargs => ['arg1', 'arg2'], + :failover => 'prio', + :firewall => true, + :local => '1.2.3.4', + :ocsp => 'http://foo.bar.baz', + :ocsp_flags => [ 'NOCHAIN' ], + :openssl_cipher_suite => [ 'AES128-SHA256' ], + :options => ['SSL_OP_NETSCAPE_CHALLENGE_BUG' ], + :protocol => 'connect', + :protocol_authentication => 'basic', + :protocol_host => '1.2.3.5:2050', + :protocol_password => 'some_password', + :protocol_username => 'some_user', + :pty => true, + :renegotiation => false, + :reset => false, + :retry => true, + :session_cache_size => 20, + :session_cache_timeout => 1000, + :sni => 'global.sni.server', + :ssl_version => 'TLSv1', + :stack => 1024, + :tcpwrappers => true, + :timeout_busy => 5, + :timeout_close => 10, + :timeout_connect => 15, + :timeout_idle => 20, + :trusted_nets => [ '1.2.3.0/24' ], + :verify => 4, + ) } + end + + context 'specific override' do + let(:ocsp) { 'https://specific.bar.baz' } + let(:hieradata){ 'defined_type_specific_override' } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to create_stunnel__connection(title).with_ssl_version('all') } + it { is_expected.to create_stunnel__connection("nfs_client").with_ssl_version('TLSv1') } + end end end end diff --git a/spec/defines/instance_spec.rb b/spec/defines/instance_spec.rb index f1bdadc..c879b9c 100644 --- a/spec/defines/instance_spec.rb +++ b/spec/defines/instance_spec.rb @@ -14,9 +14,10 @@ context 'with default parameters' do let(:params) {{ connect: [2049], - accept: 20490, + accept: '10.1.2.3:20490', }} it { is_expected.to compile.with_all_deps } + it { is_expected.to create_stunnel__instance__reserve_port('20490') } it { is_expected.to contain_class('stunnel::install') } it { is_expected.to_not create_iptables__listen__tcp_stateful('allow_stunnel_nfs') } it { is_expected.to_not create_tcpwrappers__allow('allow_stunnel_nfs') } @@ -218,6 +219,249 @@ let(:facts) { os_facts.merge(init_systems: ['rc']) } it { is_expected.to compile.and_raise_error(/Init systems.*not supported/) } end + + context 'with other parameters set' do + let(:title){ 'test_tunnel' } + let(:conf_file){ '/etc/stunnel/stunnel_managed_by_puppet_test_tunnel.conf' } + let(:params){{ + :connect => [2048,2049], + :accept => '10.1.2.3:20490', + :compression => 'zlib', + :curve => 'prime256v1', + :egd => '/some/socket/path', + :engine_ctrl => 'LOAD', + :engine_num => 1, + :exec => '/some/exec', + :execargs => ['arg1', 'arg2'], + :local => '1.2.3.4', + :options => ['SSL_OP_NETSCAPE_CHALLENGE_BUG', 'SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS'], + :output => '/some/log', + :protocol => 'connect', + :protocol_authentication => 'basic', + :protocol_host => '1.2.3.5:2050', + :protocol_password => 'some_password', + :protocol_username => 'some_user', + :rnd_bytes => 2048, + :rnd_file => '/some/random', + :session_cache_timeout => 20, + :session_cache_size => 1000, + :sni => 'test.sni.server', + :socket_options => [ 'l:SO_LINGER=1:60', 'r:TCP_NODELAY=1' ], + :ssl_version => 'TLSv1', + :stack => 1024, + :timeout_busy => 5, + :timeout_close => 10, + :timeout_connect => 15, + :timeout_idle => 20 + }} + + it { is_expected.to compile.with_all_deps } + + if os_facts[:os][:release][:major] < '7' + it { is_expected.to create_file(conf_file).with_content(/session = 20/) } + else + [ /sni = test.sni.server/, + /sessionCacheTimeout = 20/, + /sessionCacheSize = 1000/, + /renegotiation = yes/, + /reset = yes/ + ].each do |exp_regex| + it { is_expected.to create_file(conf_file).with_content(exp_regex) } + end + end + + [ /compression = zlib/, + /curve = prime256v1/, + /EGD = \/some\/socket\/path/, + /engineCtrl = LOAD/, + /engineNum = 1/, + /exec = \/some\/exec/, + /execargs = arg1 arg2/, + /local = 1.2.3.4/, + /options = SSL_OP_NETSCAPE_CHALLENGE_BUG/, + /options = SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS/, + /output = \/some\/log/, + /protocol = connect/, + /protocolAuthentication = basic/, + /protocolHost = 1\.2\.3\.5:2050/, + /protocolPassword = some_password/, + /protocolUsername = some_user/, + /pty = no/, + /retry = no/, + /RNDbytes = 2048/, + /RNDfile = \/some\/random/, +# SIMP-6060 +# /RNDoverwrite = false/, + /socket = l:SO_LINGER=1:60/, + /socket = r:TCP_NODELAY=1/, + /sslVersion = TLSv1/, + /stack = 1024/, + /TIMEOUTbusy = 5/, + /TIMEOUTclose = 10/, + /TIMEOUTconnect = 15/, + /TIMEOUTidle = 20/ + ].each do |exp_regex| + it { is_expected.to create_file(conf_file).with_content(exp_regex) } + end + end + + context 'with Hiera overrides' do + let(:pre_condition) { <<-EOM + stunnel::instance{ 'nfs_client': + accept => '127.0.0.1:2049', + connect => ['my.nfs.host:20490'] + } + EOM + } + + let(:title){ 'nfs' } + let(:params){{ + :client => false, + :connect => [2049], + :accept => 20490, + :trusted_nets => ['any'], + # Needed to force a recompile in each context + :ocsp => ocsp, + :ocsp_flags => ['NOCERTS'] + }} + + context 'global override' do + let(:ocsp) { 'https://global.bar.baz' } + let(:hieradata){ 'defined_type_global_override' } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to create_stunnel__instance(title).with( + :app_pki_ca_dir => '/some/global/ca/dir', + :app_pki_cacert => '/some/global/cacerts.pem', + :app_pki_cert => '/some/global/test.pub', + :app_pki_crl => '/some/global/crl', + :app_pki_dir => '/some/global/dir', + :app_pki_external_source => '/some/global/ext', + :app_pki_key => '/some/global/test.pem', + :compression => 'zlib', + :curve => 'prime256v1', + :delay => true, + :egd => '/some/socket/path', + :engine => 'dynamic', + :engine_ctrl => 'LOAD', + :engine_num => 1, + :exec => '/some/exec', + :execargs => ['arg1', 'arg2'], + :failover => 'prio', + :fips => false, + :firewall => true, + :haveged => false, + :local => '1.2.3.4', + :ocsp => 'https://global.bar.baz', + :ocsp_flags => [ 'NOCERTS' ], + :openssl_cipher_suite => [ 'AES128-SHA256' ], + :options => ['SSL_OP_NETSCAPE_CHALLENGE_BUG' ], + :output => '/some/log', + :pki => true, + :protocol => 'connect', + :protocol_authentication => 'basic', + :protocol_host => '1.2.3.5:2050', + :protocol_password => 'some_password', + :protocol_username => 'some_user', + :pty => true, + :renegotiation => false, + :reset => false, + :retry => true, + :rnd_bytes => 2048, + :rnd_file => '/some/random', + :rnd_overwrite => true, + :session_cache_size => 20, + :session_cache_timeout => 1000, + :setuid => 'testuid', + :setgid => 'testid', + :sni => 'global.sni.server', + :socket_options => [ 'l:SO_LINGER=1:60', 'r:TCP_NODELAY=1' ], + :ssl_version => 'TLSv1', + :stack => 1024, + :stunnel_debug => 'info', + :syslog => true, + :systemd_wantedby => [ 'some.service' ], + :systemd_requiredby => [ 'someother.service' ], + :tcpwrappers => true, + :timeout_busy => 5, + :timeout_close => 10, + :timeout_connect => 15, + :timeout_idle => 20, + :trusted_nets => [ 'any' ], + :verify => 4, + ) } + + it { is_expected.to create_stunnel__instance('nfs_client').with( + :app_pki_ca_dir => '/some/global/ca/dir', + :app_pki_cacert => '/some/global/cacerts.pem', + :app_pki_cert => '/some/global/test.pub', + :app_pki_crl => '/some/global/crl', + :app_pki_dir => '/some/global/dir', + :app_pki_external_source => '/some/global/ext', + :app_pki_key => '/some/global/test.pem', + :compression => 'zlib', + :curve => 'prime256v1', + :delay => true, + :egd => '/some/socket/path', + :engine => 'dynamic', + :engine_ctrl => 'LOAD', + :engine_num => 1, + :exec => '/some/exec', + :execargs => ['arg1', 'arg2'], + :failover => 'prio', + :fips => false, + :firewall => true, + :haveged => false, + :local => '1.2.3.4', + :ocsp => 'http://foo.bar.baz', + :ocsp_flags => [ 'NOCHAIN' ], + :openssl_cipher_suite => [ 'AES128-SHA256' ], + :options => ['SSL_OP_NETSCAPE_CHALLENGE_BUG' ], + :output => '/some/log', + :pki => true, + :protocol => 'connect', + :protocol_authentication => 'basic', + :protocol_host => '1.2.3.5:2050', + :protocol_password => 'some_password', + :protocol_username => 'some_user', + :pty => true, + :renegotiation => false, + :reset => false, + :retry => true, + :rnd_bytes => 2048, + :rnd_file => '/some/random', + :rnd_overwrite => true, + :session_cache_size => 20, + :session_cache_timeout => 1000, + :setuid => 'testuid', + :setgid => 'testid', + :sni => 'global.sni.server', + :socket_options => [ 'l:SO_LINGER=1:60', 'r:TCP_NODELAY=1' ], + :ssl_version => 'TLSv1', + :stack => 1024, + :stunnel_debug => 'info', + :syslog => true, + :systemd_wantedby => [ 'some.service' ], + :systemd_requiredby => [ 'someother.service' ], + :tcpwrappers => true, + :timeout_busy => 5, + :timeout_close => 10, + :timeout_connect => 15, + :timeout_idle => 20, + :trusted_nets => [ '1.2.3.0/24' ], + :verify => 4, + ) } + end + + context 'specific override' do + let(:ocsp) { 'https://specific.bar.baz' } + let(:hieradata){ 'defined_type_specific_override' } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to create_stunnel__instance(title).with_ssl_version('all') } + it { is_expected.to create_stunnel__instance('nfs_client').with_ssl_version('TLSv1') } + end + end end end end diff --git a/spec/defines/vartest_add_spec.rb b/spec/defines/vartest_add_spec.rb index 932ecf4..296fb17 100644 --- a/spec/defines/vartest_add_spec.rb +++ b/spec/defines/vartest_add_spec.rb @@ -291,7 +291,8 @@ def variable_test(title,key,val,opts={}) { :params => { :connect => [2049], :client => false, - :accept => 20490 + :accept => 20490, + :exec => '/bin/foo', }, :val_str => 'yes' }) diff --git a/spec/expected/instance/non_chroot_el6_stunnel.conf.txt b/spec/expected/instance/non_chroot_el6_stunnel.conf.txt index 05f6012..cdc49b6 100644 --- a/spec/expected/instance/non_chroot_el6_stunnel.conf.txt +++ b/spec/expected/instance/non_chroot_el6_stunnel.conf.txt @@ -16,4 +16,3 @@ CRLpath = /etc/pki/simp_apps/stunnel_nfs/x509/crl ciphers = HIGH:-SSLv2 verify = 2 delay = no -retry = no diff --git a/spec/expected/instance/non_chroot_el7_stunnel.conf.txt b/spec/expected/instance/non_chroot_el7_stunnel.conf.txt index f8128fe..695e2fb 100644 --- a/spec/expected/instance/non_chroot_el7_stunnel.conf.txt +++ b/spec/expected/instance/non_chroot_el7_stunnel.conf.txt @@ -18,6 +18,5 @@ CRLpath = /etc/pki/simp_apps/stunnel_nfs/x509/crl ciphers = HIGH:-SSLv2 verify = 2 delay = no -retry = no renegotiation = yes reset = yes diff --git a/spec/fixtures/hieradata/defined_type_global_override.yaml b/spec/fixtures/hieradata/defined_type_global_override.yaml new file mode 100644 index 0000000..3437ad5 --- /dev/null +++ b/spec/fixtures/hieradata/defined_type_global_override.yaml @@ -0,0 +1,98 @@ +--- +stunnel::connection::app_pki_cacert: '/some/global/cacerts.pem' +stunnel::connection::app_pki_cert: '/some/global/test.pub' +stunnel::connection::app_pki_crl: '/some/global/crl' +stunnel::connection::app_pki_key: '/some/global/test.pem' +stunnel::connection::curve: 'prime256v1' +stunnel::connection::delay: true +stunnel::connection::engine_num: 1 +stunnel::connection::exec: '/some/exec' +stunnel::connection::execargs: ['arg1', 'arg2'] +stunnel::connection::failover: 'prio' +stunnel::connection::firewall: true +stunnel::connection::local: '1.2.3.4' +stunnel::connection::ocsp: 'http://foo.bar.baz' +stunnel::connection::ocsp_flags: [ 'NOCHAIN' ] +stunnel::connection::openssl_cipher_suite: [ 'AES128-SHA256' ] +stunnel::connection::options: ['SSL_OP_NETSCAPE_CHALLENGE_BUG' ] +stunnel::connection::protocol: 'connect' +stunnel::connection::protocol_authentication: 'basic' +stunnel::connection::protocol_host: '1.2.3.5:2050' +stunnel::connection::protocol_password: 'some_password' +stunnel::connection::protocol_username: 'some_user' +stunnel::connection::pty: true +stunnel::connection::renegotiation: false +stunnel::connection::reset: false +stunnel::connection::retry: true +stunnel::connection::session_cache_size: 20 +stunnel::connection::session_cache_timeout: 1000 +stunnel::connection::sni: 'global.sni.server' +stunnel::connection::ssl_version: 'TLSv1' +stunnel::connection::stack: 1024 +stunnel::connection::tcpwrappers: true +stunnel::connection::timeout_busy: 5 +stunnel::connection::timeout_close: 10 +stunnel::connection::timeout_connect: 15 +stunnel::connection::timeout_idle: 20 +stunnel::connection::trusted_nets: [ '1.2.3.0/24' ] +stunnel::connection::verify: 4 + + +stunnel::instance::app_pki_ca_dir: '/some/global/ca/dir' +stunnel::instance::app_pki_cacert: '/some/global/cacerts.pem' +stunnel::instance::app_pki_cert: '/some/global/test.pub' +stunnel::instance::app_pki_crl: '/some/global/crl' +stunnel::instance::app_pki_dir: '/some/global/dir' +stunnel::instance::app_pki_external_source: '/some/global/ext' +stunnel::instance::app_pki_key: '/some/global/test.pem' +stunnel::instance::compression: 'zlib' +stunnel::instance::curve: 'prime256v1' +stunnel::instance::delay: true +stunnel::instance::egd: '/some/socket/path' +stunnel::instance::engine: 'dynamic' +stunnel::instance::engine_ctrl: 'LOAD' +stunnel::instance::engine_num: 1 +stunnel::instance::exec: '/some/exec' +stunnel::instance::execargs: ['arg1', 'arg2'] +stunnel::instance::failover: 'prio' +stunnel::instance::fips: false +stunnel::instance::firewall: true +stunnel::instance::haveged: false +stunnel::instance::local: '1.2.3.4' +stunnel::instance::ocsp: 'http://foo.bar.baz' +stunnel::instance::ocsp_flags: [ 'NOCHAIN' ] +stunnel::instance::openssl_cipher_suite: [ 'AES128-SHA256' ] +stunnel::instance::options: ['SSL_OP_NETSCAPE_CHALLENGE_BUG' ] +stunnel::instance::output: '/some/log' +stunnel::instance::pki: true +stunnel::instance::protocol: 'connect' +stunnel::instance::protocol_authentication: 'basic' +stunnel::instance::protocol_host: '1.2.3.5:2050' +stunnel::instance::protocol_password: 'some_password' +stunnel::instance::protocol_username: 'some_user' +stunnel::instance::pty: true +stunnel::instance::renegotiation: false +stunnel::instance::reset: false +stunnel::instance::retry: true +stunnel::instance::rnd_bytes: 2048 +stunnel::instance::rnd_file: '/some/random' +stunnel::instance::rnd_overwrite: true +stunnel::instance::session_cache_size: 20 +stunnel::instance::session_cache_timeout: 1000 +stunnel::instance::setuid: 'testuid' +stunnel::instance::setgid: 'testid' +stunnel::instance::sni: 'global.sni.server' +stunnel::instance::socket_options: [ 'l:SO_LINGER=1:60', 'r:TCP_NODELAY=1' ] +stunnel::instance::ssl_version: 'TLSv1' +stunnel::instance::stack: 1024 +stunnel::instance::stunnel_debug: 'info' +stunnel::instance::syslog: true +stunnel::instance::systemd_wantedby: [ 'some.service' ] +stunnel::instance::systemd_requiredby: [ 'someother.service' ] +stunnel::instance::tcpwrappers: true +stunnel::instance::timeout_busy: 5 +stunnel::instance::timeout_close: 10 +stunnel::instance::timeout_connect: 15 +stunnel::instance::timeout_idle: 20 +stunnel::instance::trusted_nets: [ '1.2.3.0/24' ] +stunnel::instance::verify: 4 diff --git a/spec/fixtures/hieradata/defined_type_specific_override.yaml b/spec/fixtures/hieradata/defined_type_specific_override.yaml new file mode 100644 index 0000000..f010b5b --- /dev/null +++ b/spec/fixtures/hieradata/defined_type_specific_override.yaml @@ -0,0 +1,5 @@ +--- +stunnel::connection::ssl_version: 'TLSv1' +Stunnel::Connection[nfs]::ssl_version: 'all' +stunnel::instance::ssl_version: 'TLSv1' +Stunnel::Instance[nfs]::ssl_version: 'all' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d07707c..ca59379 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,17 +22,73 @@ ENV['TRUSTED_NODE_DATA']='yes' end -default_hiera_config =<<-EOM +# This can be used from inside your spec tests to load custom hieradata within +# any context. +# +# Example: +# +# describe 'some::class' do +# context 'with version 10' do +# let(:hieradata){ "#{class_name}_v10" } +# ... +# end +# end +# +# Then, create a YAML file at spec/fixtures/hieradata/some__class_v10.yaml. +# +# You can also create a YAML file that is named the same as your test +# description with all colons and spaces changed to underscores. +# +# Hiera will use this file as it's base of information stacked on top of +# 'default.yaml' and .yaml per the defaults below. +# +# Note: Any colons (:) are replaced with underscores (_) in the class name. +def hiera_config_template(hiera_version=5) + if hiera_version == 3 + hiera_template_content = <<-EOM --- :backends: + - "rspec" - "yaml" :yaml: - :datadir: "stub" + :datadir: "<%= hiera_datadir %>" :hierarchy: - - "%{custom_hiera}" +<% if custom_hieradata -%> + - "<%= custom_hieradata %>" +<% end -%> +<% if spec_title -%> + - "<%= spec_title %>" +<% end -%> - "%{module_name}" - "default" EOM + else + hiera_template_content = <<-EOM +--- +version: 5 +hierarchy: + - name: SIMP Compliance Engine + lookup_key: compliance_markup::enforcement +<% if custom_hieradata -%> + - name: Custom Test Hieradata + path: "<%= custom_hieradata %>.yaml" +<% end -%> +<% if spec_title -%> + - name: <%= spec_title %> + path: "<%= spec_title %>.yaml" +<% end -%> + - name: <%= module_name %> + path: "<%= module_name %>.yaml" + - name: Common + path: default.yaml +defaults: + data_hash: yaml_data + datadir: "<%= hiera_datadir %>" +EOM + end + + return hiera_template_content +end # This can be used from inside your spec tests to set the testable environment. # You can use this to stub out an ENC. @@ -48,33 +104,11 @@ def set_environment(environment = :production) RSpec.configure { |c| c.default_facts['environment'] = environment.to_s } end -# This can be used from inside your spec tests to load custom hieradata within -# any context. -# -# Example: -# -# describe 'some::class' do -# context 'with version 10' do -# let(:hieradata){ "#{class_name}_v10" } -# ... -# end -# end -# -# Then, create a YAML file at spec/fixtures/hieradata/some__class_v10.yaml. -# -# Hiera will use this file as it's base of information stacked on top of -# 'default.yaml' and .yaml per the defaults above. -# -# Note: Any colons (:) are replaced with underscores (_) in the class name. -def set_hieradata(hieradata) - RSpec.configure { |c| c.default_facts['custom_hiera'] = hieradata } -end - -if not File.directory?(File.join(fixture_path,'hieradata')) then +unless File.directory?(File.join(fixture_path,'hieradata')) FileUtils.mkdir_p(File.join(fixture_path,'hieradata')) end -if not File.directory?(File.join(fixture_path,'modules',module_name)) then +unless File.directory?(File.join(fixture_path,'modules',module_name)) FileUtils.mkdir_p(File.join(fixture_path,'modules',module_name)) end @@ -84,7 +118,7 @@ def set_hieradata(hieradata) :production => { #:fqdn => 'production.rspec.test.localdomain', :path => '/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin', - :concat_basedir => '/tmp', + :concat_basedir => '/tmp' } } @@ -108,15 +142,6 @@ def set_hieradata(hieradata) c.backtrace_clean_patterns = backtrace_exclusion_patterns end - c.before(:all) do - data = YAML.load(default_hiera_config) - data[:yaml][:datadir] = File.join(fixture_path, 'hieradata') - - File.open(c.hiera_config, 'w') do |f| - f.write data.to_yaml - end - end - c.before(:each) do @spec_global_env_temp = Dir.mktmpdir('simpspec') @@ -130,11 +155,32 @@ def set_hieradata(hieradata) Puppet[:user] = Etc.getpwuid(Process.uid).name Puppet[:group] = Etc.getgrgid(Process.gid).name + hiera_datadir = File.dirname(c.hiera_config) + # sanitize hieradata if defined?(hieradata) - set_hieradata(hieradata.gsub(':','_')) + custom_hieradata = hieradata.gsub(/(:|\s)/,'_') elsif defined?(class_name) - set_hieradata(class_name.gsub(':','_')) + custom_hieradata = class_name.gsub(/(:|\s)/,'_') + end + + unless File.exist?(File.join(hiera_datadir, "#{custom_hieradata}.yaml")) + custom_hieradata = nil + end + + if self.class.description && !self.class.description.empty? + spec_title = self.class.description.gsub(/(:|\s)/,'_') + + unless File.exist?(File.join(hiera_datadir, "#{spec_title}.yaml")) + spec_title = nil + end + end + + hiera_version ||= 5 + data = YAML.load(ERB.new(hiera_config_template(hiera_version.to_i), nil, '-').result(binding)) + + File.open(c.hiera_config, 'w') do |f| + f.write data.to_yaml end end @@ -152,3 +198,8 @@ def set_hieradata(hieradata) fail "ERROR: The module '#{dir}' is not installed. Tests cannot continue." end end + +if ENV['PUPPET_DEBUG'] + Puppet::Util::Log.level = :debug + Puppet::Util::Log.newdestination(:console) +end diff --git a/templates/connection_conf.erb b/templates/connection_conf.erb index d4dc8d7..c601c45 100644 --- a/templates/connection_conf.erb +++ b/templates/connection_conf.erb @@ -80,8 +80,11 @@ else stunnel_conf << "client = #{bool_translate[@client]}" stunnel_conf << "failover = #{@failover}" - if @sni - stunnel_conf << "sni = #{@sni}" + + if @facts['os']['release']['major'] > '6' + if @sni + stunnel_conf << "sni = #{@sni}" + end end stunnel_conf << "key = #{@_app_pki_key}" @@ -145,13 +148,13 @@ else stunnel_conf << "execargs = #{@execargs.join(' ')}" end stunnel_conf << "pty = #{bool_translate[@pty]}" - stunnel_conf << "retry = #{@retry}" + stunnel_conf << "retry = #{bool_translate[@retry]}" end - stunnel_conf << "retry = #{bool_translate[@retry]}" - - if @session_cache_timeout - stunnel_conf << "session = #{@session_cache_timeout}" + if @facts['os']['release']['major'] < '7' + if @session_cache_timeout + stunnel_conf << "session = #{@session_cache_timeout}" + end end if ['RedHat','CentOS','OracleLinux'].include?(@facts['operatingsystem']) && (@facts['operatingsystemmajrelease'] > '6') diff --git a/templates/instance_conf.erb b/templates/instance_conf.erb index 044d563..a640f97 100644 --- a/templates/instance_conf.erb +++ b/templates/instance_conf.erb @@ -76,8 +76,10 @@ stunnel_conf << "client = #{bool_translate[@client]}" stunnel_conf << "failover = #{@failover}" - if @sni - stunnel_conf << "sni = #{@sni}" + if @facts['os']['release']['major'] > '6' + if @sni + stunnel_conf << "sni = #{@sni}" + end end stunnel_conf << "key = #{@app_pki_key}" @@ -141,13 +143,13 @@ stunnel_conf << "execargs = #{@execargs.join(' ')}" end stunnel_conf << "pty = #{bool_translate[@pty]}" - stunnel_conf << "retry = #{@retry}" + stunnel_conf << "retry = #{bool_translate[@retry]}" end - stunnel_conf << "retry = #{bool_translate[@retry]}" - - if @session_cache_timeout - stunnel_conf << "session = #{@session_cache_timeout}" + if @facts['os']['release']['major'] < '7' + if @session_cache_timeout + stunnel_conf << "session = #{@session_cache_timeout}" + end end if ['RedHat','CentOS','OracleLinux'].include?(@facts['operatingsystem']) && (@facts['operatingsystemmajrelease'] > '6')