diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 97ddc62..911ee89 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,75 +1,75 @@ name: CI on: pull_request jobs: setup_matrix: name: 'Setup Test Matrix' runs-on: ubuntu-latest - timeout-minutes: 40 + timeout-minutes: 60 outputs: beaker_setfiles: ${{ steps.get-outputs.outputs.beaker_setfiles }} puppet_major_versions: ${{ steps.get-outputs.outputs.puppet_major_versions }} puppet_unit_test_matrix: ${{ steps.get-outputs.outputs.puppet_unit_test_matrix }} env: BUNDLE_WITHOUT: development:release steps: - uses: actions/checkout@v2 - name: Setup ruby uses: ruby/setup-ruby@v1 with: ruby-version: '2.7' bundler-cache: true - name: Run rake validate run: bundle exec rake validate - name: Run rake rubocop run: bundle exec rake rubocop - name: Setup Test Matrix id: get-outputs run: bundle exec metadata2gha --use-fqdn --pidfile-workaround false unit: needs: setup_matrix runs-on: ubuntu-latest - timeout-minutes: 40 + timeout-minutes: 60 strategy: fail-fast: false matrix: include: ${{fromJson(needs.setup_matrix.outputs.puppet_unit_test_matrix)}} env: BUNDLE_WITHOUT: development:system_tests:release PUPPET_VERSION: "~> ${{ matrix.puppet }}.0" name: Puppet ${{ matrix.puppet }} (Ruby ${{ matrix.ruby }}) steps: - uses: actions/checkout@v2 - name: Setup ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true - name: Run tests run: bundle exec rake acceptance: needs: setup_matrix runs-on: ubuntu-latest env: BUNDLE_WITHOUT: development:test:release strategy: fail-fast: false matrix: setfile: ${{fromJson(needs.setup_matrix.outputs.beaker_setfiles)}} puppet: ${{fromJson(needs.setup_matrix.outputs.puppet_major_versions)}} name: ${{ matrix.puppet.name }} - ${{ matrix.setfile.name }} steps: - uses: actions/checkout@v2 - name: Setup ruby uses: ruby/setup-ruby@v1 with: ruby-version: '2.7' bundler-cache: true - name: Run tests run: bundle exec rake beaker env: BEAKER_PUPPET_COLLECTION: ${{ matrix.puppet.collection }} BEAKER_setfile: ${{ matrix.setfile.value }} diff --git a/.sync.yml b/.sync.yml index db98567..20c949d 100644 --- a/.sync.yml +++ b/.sync.yml @@ -1,9 +1,3 @@ --- -.travis.yml: - secure: "SDpX6jzritODonEQBqy9g0NbOmk2a9dBfAtZLrvHwM8BTpM2W0Y1daqzIbpzxFiqlNX+6r2GSq9SV70N0A9Ko/uPV9aG/XZx7MsBR9DNVjgqjJSl7+aF88VJfRpOv4PAyTM33JMx91nLFxM/ql61YX+2DXGXrhUkBsMZcdBgQnk=" - docker_sets: - - set: ubuntu1604-64 - - set: ubuntu1804-64 - - set: centos7-64 - - set: debian9-64 - - set: debian10-64 +.github/workflows/ci.yml: + timeout_minutes: 60 diff --git a/manifests/resource/mailhost.pp b/manifests/resource/mailhost.pp index c6ec7ef..f34ed67 100644 --- a/manifests/resource/mailhost.pp +++ b/manifests/resource/mailhost.pp @@ -1,220 +1,220 @@ # @summary Define a mailhost # # @param ensure # Enables or disables the specified mailhost # @param listen_ip # Default IP Address for NGINX to listen with this server on. Defaults to all interfaces (*) # @param listen_port # Default IP Port for NGINX to listen with this server on. # @param listen_options # Extra options for listen directive like 'default' to catchall. # @param ipv6_enable # value to enable/disable IPv6 support (false|true). Module will check to see # if IPv6 support exists on your system before enabling. # @param ipv6_listen_ip # Default IPv6 Address for NGINX to listen with this server on. Defaults to # all interfaces (::) # @param ipv6_listen_port # Default IPv6 Port for NGINX to listen with this server on. # @param ipv6_listen_options # Extra options for listen directive like 'default' to catchall. Template # will allways add ipv6only=on. While issue jfryman/puppet-nginx#30 is # discussed, default value is 'default'. # @param ssl # Indicates whether to setup SSL bindings for this mailhost. # @param ssl_cert # Pre-generated SSL Certificate file to reference for SSL Support. This is # not generated by this module. # @param ssl_ciphers # Override default SSL ciphers. # @param ssl_client_cert # Pre-generated SSL Certificate file to reference for client verify SSL # Support. This is not generated by this module. # @param ssl_crl # String: Specifies CRL path in file system # @param ssl_dhparam # This directive specifies a file containing Diffie-Hellman key agreement # protocol cryptographic parameters, in PEM format, utilized for exchanging # session keys between server and client. # @param ssl_ecdh_curve # This directive specifies a curve for ECDHE ciphers. # @param ssl_key # Pre-generated SSL Key file to reference for SSL Support. This is not # generated by this module. # @param ssl_password_file # This directive specifies a file containing passphrases for secret keys. # @param ssl_port # Default IP Port for NGINX to listen with this SSL server on. # @param ssl_prefer_server_ciphers # Specifies that server ciphers should be preferred over client ciphers when # using the SSLv3 and TLS protocols. # @param ssl_protocols # SSL protocols enabled. # @param ssl_session_cache # Sets the type and size of the session cache. # @param ssl_session_ticket_key # This directive specifies a file containing secret key used to encrypt and # decrypt TLS session tickets. # @param ssl_session_tickets # Whether to enable or disable session resumption through TLS session tickets. # @param ssl_session_timeout # Specifies a time during which a client may reuse the session parameters # stored in a cache. # @param ssl_trusted_cert # Specifies a file with trusted CA certificates in the PEM format used to # verify client certificates and OCSP responses if ssl_stapling is enabled. # @param ssl_verify_depth # Sets the verification depth in the client certificates chain. # @param starttls # Enable STARTTLS support # @param protocol # Mail protocol to use # @param auth_http # With this directive you can set the URL to the external HTTP-like server # for authorization. # @param xclient # Whether to use xclient for smtp # @param imap_auth # Sets permitted methods of authentication for IMAP clients. # @param imap_capabilities # Sets the IMAP protocol extensions list that is passed to the client in # response to the CAPA command. # @param imap_client_buffer # Sets the IMAP commands read buffer size. # @param pop3_auth # Sets permitted methods of authentication for POP3 clients. # @param pop3_capabilities # Sets the POP3 protocol extensions list that is passed to the client in # response to the CAPA command. # @param smtp_auth # Sets permitted methods of SASL authentication for SMTP clients. # @param smtp_capabilities # Sets the SMTP protocol extensions list that is passed to the client in # response to the EHLO command. # @param proxy_pass_error_message # Indicates whether to pass the error message obtained during the # authentication on the backend to the client. # @param server_name # List of mailhostnames for which this mailhost will respond. # @param raw_prepend # A single string, or an array of strings to prepend to the server directive # (after mailhost_cfg_prepend directive). NOTE: YOU are responsible for a # semicolon on each line that requires one. # @param raw_append # A single string, or an array of strings to append to the server directive # (after mailhost_cfg_append directive). NOTE: YOU are responsible for a # semicolon on each line that requires one. # @param mailhost_cfg_append # It expects a hash with custom directives to put after everything else # inside server # @param mailhost_cfg_prepend # It expects a hash with custom directives to put before everything else # inside server # # @example SMTP server definition # nginx::resource::mailhost { 'domain1.example': # ensure => present, # auth_http => 'server2.example/cgi-bin/auth', # protocol => 'smtp', # listen_port => 587, # ssl_port => 465, # starttls => 'only', # xclient => 'off', # ssl => true, # ssl_cert => '/tmp/server.crt', # ssl_key => '/tmp/server.pem', # } # define nginx::resource::mailhost ( Stdlib::Port $listen_port, Enum['absent', 'present'] $ensure = 'present', Variant[Array[String], String] $listen_ip = '*', Optional[String] $listen_options = undef, Boolean $ipv6_enable = false, Variant[Array[String], String] $ipv6_listen_ip = '::', - Stdlib::Port $ipv6_listen_port = 80, + Stdlib::Port $ipv6_listen_port = $listen_port, String $ipv6_listen_options = 'default ipv6only=on', Boolean $ssl = false, Optional[String] $ssl_cert = undef, String $ssl_ciphers = $nginx::ssl_ciphers, Optional[String] $ssl_client_cert = undef, Optional[String] $ssl_crl = undef, Optional[String] $ssl_dhparam = $nginx::ssl_dhparam, Optional[String] $ssl_ecdh_curve = undef, Optional[String] $ssl_key = undef, Optional[String] $ssl_password_file = undef, Optional[Stdlib::Port] $ssl_port = undef, Enum['on', 'off'] $ssl_prefer_server_ciphers = $nginx::ssl_prefer_server_ciphers, String $ssl_protocols = $nginx::ssl_protocols, Optional[String] $ssl_session_cache = undef, Optional[String] $ssl_session_ticket_key = undef, Optional[String] $ssl_session_tickets = undef, String $ssl_session_timeout = '5m', Optional[String] $ssl_trusted_cert = undef, Optional[Integer] $ssl_verify_depth = undef, Enum['on', 'off', 'only'] $starttls = 'off', Optional[Enum['imap', 'pop3', 'smtp']] $protocol = undef, Optional[String] $auth_http = undef, Optional[String] $auth_http_header = undef, Enum['on', 'off'] $xclient = 'on', Optional[String] $imap_auth = undef, Optional[Array] $imap_capabilities = undef, Optional[String] $imap_client_buffer = undef, Optional[String] $pop3_auth = undef, Optional[Array] $pop3_capabilities = undef, Optional[String] $smtp_auth = undef, Optional[Array] $smtp_capabilities = undef, Optional[Variant[Array, String]] $raw_prepend = undef, Optional[Variant[Array, String]] $raw_append = undef, Optional[Hash] $mailhost_cfg_prepend = undef, Optional[Hash] $mailhost_cfg_append = undef, String $proxy_pass_error_message = 'off', Array $server_name = [$name] ) { if ! defined(Class['nginx']) { fail('You must include the nginx base class before using any defined resources') } # Add IPv6 Logic Check - Nginx service will not start if ipv6 is enabled # and support does not exist for it in the kernel. if ($ipv6_enable and !$facts['networking']['ip6']) { warning('nginx: IPv6 support is not enabled or configured properly') } # Check to see if SSL Certificates are properly defined. if ($ssl or $starttls == 'on' or $starttls == 'only') { if ($ssl_cert == undef) or ($ssl_key == undef) { fail('nginx: SSL certificate/key (ssl_cert/ssl_cert) and/or SSL Private must be defined and exist on the target system(s)') } } $config_dir = "${nginx::conf_dir}/conf.mail.d" $config_file = "${config_dir}/${name}.conf" concat { $config_file: ensure => $ensure, owner => 'root', group => $nginx::root_group, mode => $nginx::global_mode, notify => Class['nginx::service'], require => File[$config_dir], tag => 'nginx_config_file', } if $ssl_port == undef or $listen_port != $ssl_port { concat::fragment { "${name}-header": target => $config_file, content => template('nginx/mailhost/mailhost.erb'), order => '001', } } # Create SSL File Stubs if SSL is enabled if $ssl { concat::fragment { "${name}-ssl": target => $config_file, content => template('nginx/mailhost/mailhost_ssl.erb'), order => '700', } } } diff --git a/manifests/resource/server.pp b/manifests/resource/server.pp index 55a1dd1..1d59162 100644 --- a/manifests/resource/server.pp +++ b/manifests/resource/server.pp @@ -1,644 +1,644 @@ # @summary Create a virtual host # # @param ensure # Enables or disables the specified server # @param listen_ip # Default IP Address for NGINX to listen with this server on. Defaults to all # interfaces (*) # @param listen_port # Default TCP Port for NGINX to listen with this server on. # @param listen_options # Extra options for listen directive like 'default_server' to catchall. # @param listen_unix_socket_enable # value to enable/disable UNIX socket listening support. # @param listen_unix_socket # Default unix socket for NGINX to listen with this server on. # @param listen_unix_socket_options # Extra options for listen directive like 'default' to catchall. # @param location_satisfy # Allows access if all (all) or at least one (any) of the auth modules allow # access. # @param location_allow # Locations to allow connections from. # @param location_deny # Locations to deny connections from. # @param ipv6_enable # value to enable/disable IPv6 support (false|true). Module will check to see # if IPv6 support exists on your system before enabling. # @param ipv6_listen_ip # Default IPv6 Address for NGINX to listen with this server on. Defaults to all interfaces (::) # @param ipv6_listen_port # Default IPv6 Port for NGINX to listen with this server on. Defaults to TCP 80 # @param ipv6_listen_options # Extra options for listen directive like 'default' to catchall. Template # will allways add ipv6only=on. While issue jfryman/puppet-nginx#30 is # discussed, default value is 'default'. # @param add_header # Adds headers to the HTTP response when response code is equal to 200, 204, # 301, 302 or 304. # @param index_files # Default index files for NGINX to read when traversing a directory # @param autoindex # Set it on 'on' or 'off 'to activate/deactivate autoindex directory listing. # @param autoindex_exact_size # Set it on 'on' or 'off' to activate/deactivate autoindex displaying exact # filesize, or rounded to kilobytes, megabytes and gigabytes. # @param autoindex_format # Sets the format of a directory listing. # @param autoindex_localtime # Specifies whether times in the directory listing should be output in the # local time zone or UTC. # @param reset_timedout_connection # Enables or disables resetting timed out connections and connections closed # with the non-standard code 444. # @param proxy # Proxy server(s) for the root location to connect to. Accepts a single # value, can be used in conjunction with nginx::resource::upstream # @param proxy_read_timeout # Override the default proxy read timeout value of 90 seconds # @param proxy_send_timeout # Override the default proxy send timeout value of 90 seconds # @param proxy_redirect # Override the default proxy_redirect value of off. # @param proxy_buffering # If defined, sets the proxy_buffering to the passed value. # @param proxy_request_buffering # If defined, sets the proxy_request_buffering to the passed value. # @param proxy_max_temp_file_size # Sets the maximum size of the temporary buffer file. # @param proxy_busy_buffers_size # Sets the total size of buffers that can be busy sending a response to the # client while the response is not yet fully read. # @param resolver # Configures name servers used to resolve names of upstream servers into addresses. # @param fastcgi # location of fastcgi (host:port) # @param fastcgi_param # Set additional custom fastcgi_params # @param fastcgi_params # optional alternative fastcgi_params file to use # @param fastcgi_index # optional FastCGI index page # @param fastcgi_script # optional SCRIPT_FILE parameter # @param uwsgi_read_timeout # optional value for uwsgi_read_timeout # @param ssl # Indicates whether to setup SSL bindings for this server. # @param ssl_cert # Pre-generated SSL Certificate file to reference for SSL Support. This is # not generated by this module. Set to `false` to inherit from the http # section, which improves performance by conserving memory. # Use an array to add multiple SSL Certificates. # @param ssl_client_cert # Pre-generated SSL Certificate file to reference for client verify SSL # Support. This is not generated by this module. # @param ssl_verify_client # Enables verification of client certificates. # @param ssl_crl # Specifies CRL path in file system # @param ssl_dhparam # This directive specifies a file containing Diffie-Hellman key agreement # protocol cryptographic parameters, in PEM format, utilized for exchanging # session keys between server and client. # @param ssl_ecdh_curve # This directive specifies a curve for ECDHE ciphers. # @param ssl_prefer_server_ciphers # String: Specifies that server ciphers should be preferred over client # ciphers when using the SSLv3 and TLS protocols. # @param ssl_redirect # Adds a server directive and return statement to force ssl redirect. Will # honor ssl_port if it's set. # @param ssl_redirect_port # Overrides $ssl_port in the SSL redirect set by ssl_redirect # @param ssl_key # Pre-generated SSL Key file to reference for SSL Support. This is not # generated by this module. Set to `false` to inherit from the http section, # which improves performance by conserving memory. # Use an array to add multiple SSL Keys. # @param ssl_port # Default IP Port for NGINX to listen with this SSL server on. # @param ssl_protocols # SSL protocols enabled. Defaults to 'TLSv1 TLSv1.1 TLSv1.2'. # @param ssl_buffer_size # Sets the size of the buffer used for sending data. # @param ssl_ciphers # SSL ciphers enabled. # @param ssl_stapling # Enables or disables stapling of OCSP responses by the server. # @param ssl_stapling_file # When set, the stapled OCSP response will be taken from the specified file # instead of querying the OCSP responder specified in the server certificate. # @param ssl_stapling_responder # Overrides the URL of the OCSP responder specified in the Authority # Information Access certificate extension. # @param ssl_stapling_verify # Enables or disables verification of OCSP responses by the server. Defaults to false. # @param ssl_session_timeout # Specifies a time during which a client may reuse the session parameters stored in a cache. # Defaults to 5m. # @param ssl_session_tickets # Enables or disables session resumption through TLS session tickets. # @param ssl_session_ticket_key # Sets a file with the secret key used to encrypt and decrypt TLS session tickets. # @param ssl_trusted_cert # Specifies a file with trusted CA certificates in the PEM format used to verify client # certificates and OCSP responses if ssl_stapling is enabled. # @param ssl_verify_depth # Sets the verification depth in the client certificates chain. # @param ssl_password_file # File containing the password for the SSL Key file. # @param spdy # Toggles SPDY protocol. # @param http2 # Toggles HTTP/2 protocol. # @param server_name # List of servernames for which this server will respond. Default [$name]. # @param www_root # Specifies the location on disk for files to be read from. Cannot be set in conjunction with $proxy # @param rewrite_www_to_non_www # Adds a server directive and rewrite rule to rewrite www.domain.com to domain.com in order to avoid # duplicate content (SEO); # @param rewrite_non_www_to_www # Adds a server directive and rewrite rule to rewrite domain.com to www.domain.com in order to avoid # duplicate content (SEO); # @param try_files # Specifies the locations for files to be checked as an array. Cannot be used in conjuction with $proxy. # @param proxy_cache # This directive sets name of zone for caching. The same zone can be used in multiple places. # @param proxy_cache_key # Override the default proxy_cache_key of $scheme$proxy_host$request_uri # @param proxy_cache_use_stale # Override the default proxy_cache_use_stale value of off. # @param proxy_cache_valid # This directive sets the time for caching different replies. # @param proxy_cache_lock # This directive sets the locking mechanism for pouplating cache. # @param proxy_cache_bypass # Defines conditions which the response will not be cached # @param proxy_method # If defined, overrides the HTTP method of the request to be passed to the backend. # @param proxy_http_version # Sets the proxy http version # @param proxy_set_body # If defined, sets the body passed to the backend. # @param absolute_redirect # Enables or disables the absolute redirect functionality of nginx # @param auth_basic # This directive includes testing name and password with HTTP Basic Authentication. # @param auth_basic_user_file # This directive sets the htpasswd filename for the authentication realm. # @param auth_request # This allows you to specify a custom auth endpoint # @param client_max_body_size # This directive sets client_max_body_size. # @param client_body_timeout # Sets how long the server will wait for a client body. Default is 60s # @param client_header_timeout # Sets how long the server will wait for a client header. Default is 60s # @param raw_prepend # A single string, or an array of strings to prepend to the server directive # (after cfg prepend directives). NOTE: YOU are responsible for a semicolon # on each line that requires one. # @param raw_append # A single string, or an array of strings to append to the server directive # (after cfg append directives). NOTE: YOU are responsible for a semicolon on # each line that requires one. # @param location_raw_prepend # A single string, or an array of strings to prepend to the location # directive (after custom_cfg directives). NOTE: YOU are responsible for a # semicolon on each line that requires one. # @param location_raw_append # A single string, or an array of strings to append to the location directive # (after custom_cfg directives). NOTE: YOU are responsible for a semicolon on # each line that requires one. # @param server_cfg_append # It expects a hash with custom directives to put after everything else inside server # @param server_cfg_prepend # It expects a hash with custom directives to put before everything else inside server # @param server_cfg_ssl_append # It expects a hash with custom directives to put after everything else inside server ssl # @param server_cfg_ssl_prepend # It expects a hash with custom directives to put before everything else inside server ssl # @param include_files # Adds include files to server # @param access_log # Where to write access log (log format can be set with $format_log). This # can be either a string or an array; in the latter case, multiple lines will # be created. Additionally, unlike the earlier behavior, setting it to # 'absent' in the server context will remove this directive entirely from the # server stanza, rather than setting a default. Can also be disabled for this # server with the string 'off'. # @param error_log # Where to write error log. May add additional options like error level to # the end. May set to 'absent', in which case it will be omitted in this # server stanza (and default to nginx.conf setting) # @param passenger_cgi_param # Allows one to define additional CGI environment variables to pass to the backend application # @param passenger_set_header # Allows one to set headers to pass to the backend application (Passenger 5.0+) # @param passenger_env_var # Allows one to set environment variables to pass to the backend application (Passenger 5.0+) # @param passenger_pre_start # Allows setting a URL to pre-warm the host. Per Passenger docs, the "domain # part of the URL" must match a value of server_name. If this is an array, # multiple URLs can be specified. # @param log_by_lua # Run the Lua source code inlined as the at the log request # processing phase. This does not replace the current access logs, but runs # after. # @param log_by_lua_file # Equivalent to log_by_lua, except that the file specified by # contains the Lua code, or, as from the v0.5.0rc32 # release, the Lua/LuaJIT bytecode to be executed. # @param gzip_types # Defines gzip_types, nginx default is text/html # @param gzip_static # Defines gzip_static, nginx default is off # @param owner # Defines owner of the .conf file # @param group # Defines group of the .conf file # @param mode # Defines mode of the .conf file # @param maintenance # A boolean value to set a server in maintenance # @param maintenance_value # Value to return when maintenance is on. # @param error_pages # Setup errors pages, hash key is the http code and hash value the page # @param locations # Hash of location resources used by this server # @param locations_defaults # Hash of location default settings # # @example # nginx::resource::server { 'test2.local': # ensure => present, # www_root => '/var/www/nginx-default', # ssl => true, # ssl_cert => '/tmp/server.crt', # ssl_key => '/tmp/server.pem', # } # define nginx::resource::server ( Enum['absent', 'present'] $ensure = 'present', Variant[Array, String] $listen_ip = '*', - Integer $listen_port = 80, + Stdlib::Port $listen_port = 80, Optional[String] $listen_options = undef, Boolean $listen_unix_socket_enable = false, Variant[Array[Stdlib::Absolutepath], Stdlib::Absolutepath] $listen_unix_socket = '/var/run/nginx.sock', Optional[String] $listen_unix_socket_options = undef, Optional[Enum['any', 'all']] $location_satisfy = undef, Array $location_allow = [], Array $location_deny = [], Boolean $ipv6_enable = false, Variant[Array, String] $ipv6_listen_ip = '::', - Integer $ipv6_listen_port = 80, + Stdlib::Port $ipv6_listen_port = $listen_port, String $ipv6_listen_options = 'default ipv6only=on', Hash $add_header = {}, Boolean $ssl = false, Boolean $ssl_listen_option = true, Optional[Variant[String, Boolean, Array[String]]] $ssl_cert = undef, Optional[String] $ssl_client_cert = undef, String $ssl_verify_client = 'on', Optional[String] $ssl_dhparam = undef, Optional[String] $ssl_ecdh_curve = undef, Boolean $ssl_redirect = false, Optional[Integer] $ssl_redirect_port = undef, Optional[Variant[String, Boolean, Array[String]]] $ssl_key = undef, Integer $ssl_port = 443, Optional[Enum['on', 'off']] $ssl_prefer_server_ciphers = undef, Optional[String] $ssl_protocols = undef, Optional[String] $ssl_buffer_size = undef, Optional[String] $ssl_ciphers = undef, Optional[String] $ssl_cache = undef, Optional[String] $ssl_crl = undef, Boolean $ssl_stapling = false, Optional[String] $ssl_stapling_file = undef, Optional[String] $ssl_stapling_responder = undef, Boolean $ssl_stapling_verify = false, Optional[String] $ssl_session_timeout = undef, Optional[Enum['on', 'off']] $ssl_session_tickets = undef, Optional[String] $ssl_session_ticket_key = undef, Optional[String] $ssl_trusted_cert = undef, Optional[Integer] $ssl_verify_depth = undef, Optional[Stdlib::Absolutepath] $ssl_password_file = undef, Enum['on', 'off'] $spdy = $nginx::spdy, Enum['on', 'off'] $http2 = $nginx::http2, Optional[String] $proxy = undef, Optional[String] $proxy_redirect = undef, String $proxy_read_timeout = $nginx::proxy_read_timeout, String $proxy_send_timeout = $nginx::proxy_send_timeout, $proxy_connect_timeout = $nginx::proxy_connect_timeout, Array[String] $proxy_set_header = $nginx::proxy_set_header, Array[String] $proxy_hide_header = $nginx::proxy_hide_header, Array[String] $proxy_pass_header = $nginx::proxy_pass_header, Optional[String] $proxy_cache = undef, Optional[String] $proxy_cache_key = undef, Optional[String] $proxy_cache_use_stale = undef, Optional[Variant[Array[String], String]] $proxy_cache_valid = undef, Optional[Enum['on', 'off']] $proxy_cache_lock = undef, Optional[Variant[Array[String], String]] $proxy_cache_bypass = undef, Optional[String] $proxy_method = undef, Optional[String] $proxy_http_version = undef, Optional[String] $proxy_set_body = undef, Optional[String] $proxy_buffering = undef, Optional[String] $proxy_request_buffering = undef, Optional[Nginx::Size] $proxy_max_temp_file_size = undef, Optional[Nginx::Size] $proxy_busy_buffers_size = undef, Array $resolver = [], Optional[String] $fastcgi = undef, Optional[String] $fastcgi_index = undef, $fastcgi_param = undef, String $fastcgi_params = "${nginx::conf_dir}/fastcgi.conf", Optional[String] $fastcgi_script = undef, Optional[String] $uwsgi = undef, String $uwsgi_params = "${nginx::config::conf_dir}/uwsgi_params", Optional[String] $uwsgi_read_timeout = undef, Array $index_files = [ 'index.html', 'index.htm', 'index.php', ], Optional[String] $autoindex = undef, Optional[Enum['on', 'off']] $autoindex_exact_size = undef, Optional[Enum['html', 'xml', 'json', 'jsonp']] $autoindex_format = undef, Optional[Enum['on', 'off']] $autoindex_localtime = undef, Optional[Enum['on', 'off']] $reset_timedout_connection = undef, Array[String] $server_name = [$name], Optional[String] $www_root = undef, Boolean $rewrite_www_to_non_www = false, Boolean $rewrite_non_www_to_www = false, Optional[Hash] $location_custom_cfg = undef, Optional[Hash] $location_cfg_prepend = undef, Optional[Hash] $location_cfg_append = undef, Optional[Hash] $location_custom_cfg_prepend = undef, Optional[Hash] $location_custom_cfg_append = undef, Optional[Array[String]] $try_files = undef, Optional[Enum['on', 'off']] $absolute_redirect = undef, Optional[String] $auth_basic = undef, Optional[String] $auth_basic_user_file = undef, Optional[String] $auth_request = undef, Optional[String] $client_body_timeout = undef, Optional[String] $client_header_timeout = undef, $client_max_body_size = undef, Optional[Variant[Array[String], String]] $raw_prepend = undef, Optional[Variant[Array[String], String]] $raw_append = undef, Optional[Variant[Array[String], String]] $location_raw_prepend = undef, Optional[Variant[Array[String], String]] $location_raw_append = undef, Optional[Hash] $server_cfg_prepend = undef, Optional[Hash] $server_cfg_append = undef, Optional[Hash] $server_cfg_ssl_prepend = undef, Optional[Hash] $server_cfg_ssl_append = undef, Optional[Array[String]] $include_files = undef, Optional[Variant[String, Array]] $access_log = undef, Optional[Variant[String, Array]] $error_log = undef, Optional[String] $format_log = $nginx::http_format_log, Optional[Hash] $passenger_cgi_param = undef, Optional[Hash] $passenger_set_header = undef, Optional[Hash] $passenger_env_var = undef, Optional[Variant[Array[String], String]] $passenger_pre_start = undef, Optional[String] $log_by_lua = undef, Optional[String] $log_by_lua_file = undef, $use_default_location = true, $rewrite_rules = [], $string_mappings = {}, $geo_mappings = {}, Optional[String] $gzip_types = undef, Optional[String] $gzip_static = undef, String $owner = $nginx::global_owner, String $group = $nginx::global_group, String $mode = $nginx::global_mode, Boolean $maintenance = false, String $maintenance_value = 'return 503', $error_pages = undef, Hash $locations = {}, Hash $locations_defaults = {}, ) { if ! defined(Class['nginx']) { fail('You must include the nginx base class before using any defined resources') } if $rewrite_www_to_non_www == true and $rewrite_non_www_to_www == true { fail('You must not set both $rewrite_www_to_non_www and $rewrite_non_www_to_www to true') } # Variables if $nginx::confd_only { $server_dir = "${nginx::conf_dir}/conf.d" } else { $server_dir = "${nginx::conf_dir}/sites-available" $server_enable_dir = "${nginx::conf_dir}/sites-enabled" $server_symlink_ensure = $ensure ? { 'absent' => absent, default => 'link', } } $name_sanitized = regsubst($name, ' ', '_', 'G') $config_file = "${server_dir}/${name_sanitized}.conf" File { ensure => $ensure ? { 'absent' => absent, default => 'file', }, notify => Class['nginx::service'], owner => $owner, group => $group, mode => $mode, } # Add IPv6 Logic Check - Nginx service will not start if ipv6 is enabled # and support does not exist for it in the kernel. if $ipv6_enable and !$ipv6_listen_ip { warning('nginx: IPv6 support is not enabled or configured properly') } # Check to see if SSL Certificates are properly defined. if $ssl { if $ssl_cert == undef { fail('nginx: ssl_cert must be set to false or to a fully qualified path') } if $ssl_key == undef { fail('nginx: ssl_key must be set to false or to a fully qualified path') } } # Try to error in the case where the user sets ssl_port == listen_port but # doesn't set ssl = true if !$ssl and $ssl_port == $listen_port { warning('nginx: ssl must be true if listen_port is the same as ssl_port') } concat { $config_file: ensure => $ensure, owner => $owner, group => $group, mode => $mode, notify => Class['nginx::service'], require => File[$server_dir], tag => 'nginx_config_file', } # This deals with a situation where the listen directive for SSL doesn't match # the port we want to force the SSL redirect to. if $ssl_redirect_port { $_ssl_redirect_port = $ssl_redirect_port } elsif $ssl_port { $_ssl_redirect_port = $ssl_port } # Suppress unneeded stuff in non-SSL location block when certain conditions are # met. $ssl_only = ($ssl and $ssl_port == $listen_port) or $ssl_redirect # If we're redirecting to SSL, the default location block is useless, *unless* # SSL is enabled for this server # either and ssl -> true # ssl redirect and no ssl -> false if (!$ssl_redirect or $ssl) and $use_default_location { # Create the default location reference for the server nginx::resource::location { "${name_sanitized}-default": ensure => $ensure, server => $name_sanitized, ssl => $ssl, ssl_only => $ssl_only, location => '/', location_satisfy => $location_satisfy, location_allow => $location_allow, location_deny => $location_deny, proxy => $proxy, proxy_redirect => $proxy_redirect, proxy_read_timeout => $proxy_read_timeout, proxy_send_timeout => $proxy_send_timeout, proxy_connect_timeout => $proxy_connect_timeout, proxy_cache => $proxy_cache, proxy_cache_key => $proxy_cache_key, proxy_cache_use_stale => $proxy_cache_use_stale, proxy_cache_valid => $proxy_cache_valid, proxy_method => $proxy_method, proxy_http_version => $proxy_http_version, proxy_set_header => $proxy_set_header, proxy_hide_header => $proxy_hide_header, proxy_pass_header => $proxy_pass_header, proxy_cache_lock => $proxy_cache_lock, proxy_set_body => $proxy_set_body, proxy_cache_bypass => $proxy_cache_bypass, proxy_buffering => $proxy_buffering, proxy_request_buffering => $proxy_request_buffering, proxy_busy_buffers_size => $proxy_busy_buffers_size, proxy_max_temp_file_size => $proxy_max_temp_file_size, fastcgi => $fastcgi, fastcgi_index => $fastcgi_index, fastcgi_param => $fastcgi_param, fastcgi_params => $fastcgi_params, fastcgi_script => $fastcgi_script, uwsgi => $uwsgi, uwsgi_params => $uwsgi_params, uwsgi_read_timeout => $uwsgi_read_timeout, try_files => $try_files, www_root => $www_root, autoindex => $autoindex, autoindex_exact_size => $autoindex_exact_size, autoindex_format => $autoindex_format, autoindex_localtime => $autoindex_localtime, index_files => $index_files, location_custom_cfg => $location_custom_cfg, location_cfg_prepend => $location_cfg_prepend, location_cfg_append => $location_cfg_append, location_custom_cfg_prepend => $location_custom_cfg_prepend, location_custom_cfg_append => $location_custom_cfg_append, rewrite_rules => $rewrite_rules, raw_prepend => $location_raw_prepend, raw_append => $location_raw_append, notify => Class['nginx::service'], } $root = undef } else { $root = $www_root } # Only try to manage these files if they're the default one (as you presumably # usually don't want the default template if you're using a custom file. if $fastcgi != undef and !defined(File[$fastcgi_params]) and $fastcgi_params == "${nginx::conf_dir}/fastcgi.conf" { file { $fastcgi_params: ensure => file, mode => $nginx::global_mode, content => template($nginx::fastcgi_conf_template), } } if $uwsgi != undef and !defined(File[$uwsgi_params]) and $uwsgi_params == "${nginx::conf_dir}/uwsgi_params" { file { $uwsgi_params: ensure => file, mode => $nginx::global_mode, content => template($nginx::uwsgi_params_template), } } if $listen_port != $ssl_port { concat::fragment { "${name_sanitized}-header": target => $config_file, content => template('nginx/server/server_header.erb'), order => '001', } # Create a proper file close stub. concat::fragment { "${name_sanitized}-footer": target => $config_file, content => template('nginx/server/server_footer.erb'), order => '699', } } # Create SSL File Stubs if SSL is enabled if $ssl { # Access and error logs are named differently in ssl template if $ssl_key { $ssl_key_real = $ssl_key.flatten $ssl_key_real.each | $key | { File <| title == $key or path == $key |> -> Concat::Fragment["${name_sanitized}-ssl-header"] } } if $ssl_cert { $ssl_cert_real = $ssl_cert.flatten $ssl_cert_real.each | $cert | { File <| title == $cert or path == $cert |> -> Concat::Fragment["${name_sanitized}-ssl-header"] } } concat::fragment { "${name_sanitized}-ssl-header": target => $config_file, content => template('nginx/server/server_ssl_header.erb'), order => '700', } concat::fragment { "${name_sanitized}-ssl-footer": target => $config_file, content => template('nginx/server/server_ssl_footer.erb'), order => '999', } } unless $nginx::confd_only { file { "${name_sanitized}.conf symlink": ensure => $server_symlink_ensure, path => "${server_enable_dir}/${name_sanitized}.conf", target => $config_file, require => [File[$server_dir], Concat[$config_file]], notify => Class['nginx::service'], } } create_resources('::nginx::resource::map', $string_mappings) create_resources('::nginx::resource::geo', $geo_mappings) create_resources('::nginx::resource::location', $locations, { ensure => $ensure, server => $name_sanitized, ssl => $ssl, ssl_only => $ssl_only, www_root => $www_root, } + $locations_defaults) } diff --git a/manifests/resource/streamhost.pp b/manifests/resource/streamhost.pp index ddba8a9..d7797b0 100644 --- a/manifests/resource/streamhost.pp +++ b/manifests/resource/streamhost.pp @@ -1,124 +1,124 @@ # @summary Create a virtual steamhost # # @param ensure # Enables or disables the specified streamhost # @param listen_ip # Default IP Address for NGINX to listen with this streamhost on. Defaults to # all interfaces (*) # @param listen_port # Default TCP Port for NGINX to listen with this streamhost on. # @param listen_options # Extra options for listen directive like 'default' to catchall. # @param ipv6_enable # Value to enable/disable IPv6 support Module will check to see if IPv6 # support exists on your system before enabling. # @param ipv6_listen_ip # Default IPv6 Address for NGINX to listen with this streamhost on. Defaults # to all interfaces (::) # @param ipv6_listen_port # Default IPv6 Port for NGINX to listen with this streamhost on. # @param ipv6_listen_options # Extra options for listen directive like 'default' to catchall. Template # will allways add ipv6only=on. While issue jfryman/puppet-nginx#30 is # discussed, default value is 'default'. # @param proxy # Proxy server(s) for the root location to connect to. Accepts a single # value, can be used in conjunction with nginx::resource::upstream # @param proxy_read_timeout # Override the default the proxy read timeout value of 90 seconds # @param resolver # Configures name servers used to resolve names of upstream servers into # addresses. # @param raw_prepend # A single string, or an array of strings to prepend to the server directive # (after cfg prepend directives). NOTE: YOU are responsible for a semicolon # on each line that requires one. # @param raw_append # A single string, or an array of strings to append to the server directive # (after cfg append directives). NOTE: YOU are responsible for a semicolon on # each line that requires one. # @param owner # Defines owner of the .conf file # @param group # Defines group of the .conf file # @param mode # Defines mode of the .conf file Default to return 503 # # @example # nginx::resource::streamhost { 'test2.local': # ensure => present, # } # define nginx::resource::streamhost ( Enum['absent', 'present'] $ensure = 'present', Variant[Array, String] $listen_ip = '*', Integer $listen_port = 80, Optional[String] $listen_options = undef, Boolean $ipv6_enable = false, Variant[Array, String] $ipv6_listen_ip = '::', - Integer $ipv6_listen_port = 80, + Integer $ipv6_listen_port = $listen_port, String $ipv6_listen_options = 'default ipv6only=on', $proxy = undef, String $proxy_read_timeout = $nginx::proxy_read_timeout, $proxy_connect_timeout = $nginx::proxy_connect_timeout, Array $resolver = [], Variant[Array[String], String] $raw_prepend = [], Variant[Array[String], String] $raw_append = [], String $owner = $nginx::global_owner, String $group = $nginx::global_group, String $mode = $nginx::global_mode, ) { if ! defined(Class['nginx']) { fail('You must include the nginx base class before using any defined resources') } # Variables if $nginx::confd_only { $streamhost_dir = "${nginx::conf_dir}/conf.stream.d" } else { $streamhost_dir = "${nginx::conf_dir}/streams-available" $streamhost_enable_dir = "${nginx::conf_dir}/streams-enabled" $streamhost_symlink_ensure = $ensure ? { 'absent' => absent, default => 'link', } } $name_sanitized = regsubst($name, ' ', '_', 'G') $config_file = "${streamhost_dir}/${name_sanitized}.conf" # Add IPv6 Logic Check - Nginx service will not start if ipv6 is enabled # and support does not exist for it in the kernel. if $ipv6_enable and !$facts['networking']['ip6'] { warning('nginx: IPv6 support is not enabled or configured properly') } concat { $config_file: ensure => $ensure, owner => $owner, group => $group, mode => $mode, notify => Class['nginx::service'], require => File[$streamhost_dir], tag => 'nginx_config_file', } concat::fragment { "${name_sanitized}-header": target => $config_file, content => template('nginx/streamhost/streamhost.erb'), order => '001', } unless $nginx::confd_only { file { "${name_sanitized}.conf symlink": ensure => $streamhost_symlink_ensure, path => "${streamhost_enable_dir}/${name_sanitized}.conf", target => $config_file, owner => $owner, group => $group, mode => $mode, require => Concat[$config_file], notify => Class['nginx::service'], } } } diff --git a/spec/defines/resource_mailhost_spec.rb b/spec/defines/resource_mailhost_spec.rb index 4011a49..0ea9bd3 100644 --- a/spec/defines/resource_mailhost_spec.rb +++ b/spec/defines/resource_mailhost_spec.rb @@ -1,764 +1,764 @@ require 'spec_helper' describe 'nginx::resource::mailhost' do on_supported_os.each do |os, facts| context "on #{os} with Facter #{facts[:facterversion]} and Puppet #{facts[:puppetversion]}" do let(:facts) do facts end let(:title) { 'www.rspec.example.com' } let :default_params do { listen_port: 25, ipv6_enable: true } end let(:pre_condition) { ['include ::nginx'] } describe 'os-independent items' do describe 'basic assumptions' do let(:params) { default_params } it { is_expected.to contain_class('nginx') } it { is_expected.to contain_concat("/etc/nginx/conf.mail.d/#{title}.conf").that_requires('File[/etc/nginx/conf.mail.d]') } it do is_expected.to contain_concat("/etc/nginx/conf.mail.d/#{title}.conf").with('owner' => 'root', 'group' => 'root', 'mode' => '0644') end it { is_expected.to contain_concat__fragment("#{title}-header") } it { is_expected.not_to contain_concat__fragment("#{title}-ssl") } end describe 'absent assumption' do let(:params) { default_params.merge('ensure'.to_sym => 'absent') } it { is_expected.to contain_class('nginx') } it { is_expected.to contain_concat("/etc/nginx/conf.mail.d/#{title}.conf").with('ensure' => 'absent') } end describe 'mailhost template content' do [ { title: 'should set the IPv4 listen IP', attr: 'listen_ip', value: '127.0.0.1', match: ' listen 127.0.0.1:25;' }, { title: 'should set the IPv4 listen port', attr: 'listen_port', value: 45, match: ' listen *:45;' }, { title: 'should set the IPv4 listen options', attr: 'listen_options', value: 'spdy default', match: ' listen *:25 spdy default;' }, { title: 'should enable IPv6', attr: 'ipv6_enable', value: true, - match: ' listen [::]:80 default ipv6only=on;' + match: ' listen [::]:25 default ipv6only=on;' }, { title: 'should not enable IPv6', attr: 'ipv6_enable', value: false, - notmatch: %r{ listen \[::\]:80 default ipv6only=on;} + notmatch: %r{ listen \[::\]:25 default ipv6only=on;} }, { title: 'should set the IPv6 listen IP', attr: 'ipv6_listen_ip', value: '2001:0db8:85a3:0000:0000:8a2e:0370:7334', - match: ' listen [2001:0db8:85a3:0000:0000:8a2e:0370:7334]:80 default ipv6only=on;' + match: ' listen [2001:0db8:85a3:0000:0000:8a2e:0370:7334]:25 default ipv6only=on;' }, { title: 'should set the IPv6 listen port', attr: 'ipv6_listen_port', value: 45, match: ' listen [::]:45 default ipv6only=on;' }, { title: 'should set the IPv6 listen options', attr: 'ipv6_listen_options', value: 'spdy', - match: ' listen [::]:80 spdy;' + match: ' listen [::]:25 spdy;' }, { title: 'should set servername(s)', attr: 'server_name', value: %w[name1 name2], match: ' server_name name1 name2;' }, { title: 'should set protocol', attr: 'protocol', value: 'imap', match: ' protocol imap;' }, { title: 'should set xclient', attr: 'xclient', value: 'off', match: ' xclient off;' }, { title: 'should set auth_http', attr: 'auth_http', value: 'test-auth_http', match: ' auth_http test-auth_http;' }, { title: 'should set auth_http_header', attr: 'auth_http_header', value: 'X-Auth-Key "secret_string"', match: ' auth_http_header X-Auth-Key "secret_string";' }, { title: 'should set starttls', attr: 'starttls', value: 'on', match: ' starttls on;' }, { title: 'should set starttls', attr: 'starttls', value: 'only', match: ' starttls only;' }, { title: 'should not enable SSL', attr: 'starttls', value: 'off', notmatch: %r{ ssl_session_timeout 5m;} }, { title: 'should contain raw_prepend directives', attr: 'raw_prepend', value: [ 'if (a) {', ' b;', '}' ], match: %r{^\s+if \(a\) \{\n\s++b;\n\s+\}} }, { title: 'should contain raw_append directives', attr: 'raw_append', value: [ 'if (a) {', ' b;', '}' ], match: %r{^\s+if \(a\) \{\n\s++b;\n\s+\}} }, { title: 'should contain ordered prepended directives', attr: 'mailhost_cfg_prepend', value: { 'test1' => 'test value 1', 'test2' => ['test value 2a', 'test value 2b'], 'test3' => 'test value 3' }, match: [ ' test1 test value 1;', ' test2 test value 2a;', ' test2 test value 2b;', ' test3 test value 3;' ] }, { title: 'should contain ordered appended directives', attr: 'mailhost_cfg_append', value: { 'test1' => 'test value 1', 'test2' => ['test value 2a', 'test value 2b'], 'test3' => 'test value 3' }, match: [ ' test1 test value 1;', ' test2 test value 2a;', ' test2 test value 2b;', ' test3 test value 3;' ] } ].each do |param| context "when #{param[:attr]} is #{param[:value]}" do let :default_params do { listen_port: 25, ipv6_enable: true, ssl_cert: 'dummy.crt', ssl_key: 'dummy.key' } end let(:params) { default_params.merge(param[:attr].to_sym => param[:value]) } it { is_expected.to contain_concat__fragment("#{title}-header") } it param[:title] do matches = Array(param[:match]) if matches.all? { |m| m.is_a? Regexp } matches.each { |item| is_expected.to contain_concat__fragment("#{title}-header").with_content(item) } else lines = catalogue.resource('concat::fragment', "#{title}-header").send(:parameters)[:content].split("\n") expect(lines & Array(param[:match])).to eq(Array(param[:match])) end end end end end describe 'mailhost template content for imap' do [ { title: 'should set imap_auth', attr: 'imap_auth', value: 'login', match: ' imap_auth login;' }, { title: 'should set imap_capabilities', attr: 'imap_capabilities', value: ['"SIZE 52428800"', 'IMAP4rev1', 'UIDPLUS'], match: ' imap_capabilities "SIZE 52428800" IMAP4rev1 UIDPLUS;' }, { title: 'should set imap_client_buffer', attr: 'imap_client_buffer', value: '8k', match: ' imap_client_buffer 8k;' } ].each do |param| context "when #{param[:attr]} is #{param[:value]}" do let :default_params do { listen_port: 25, ipv6_enable: true, protocol: 'imap' } end let(:params) { default_params.merge(param[:attr].to_sym => param[:value]) } it { is_expected.to contain_concat__fragment("#{title}-header") } it param[:title] do matches = Array(param[:match]) if matches.all? { |m| m.is_a? Regexp } matches.each { |item| is_expected.to contain_concat__fragment("#{title}-header").with_content(item) } else lines = catalogue.resource('concat::fragment', "#{title}-header").send(:parameters)[:content].split("\n") expect(lines & Array(param[:match])).to eq(Array(param[:match])) end end end end end describe 'mailhost template content for pop3' do [ { title: 'should set pop3_auth', attr: 'pop3_auth', value: 'login', match: ' pop3_auth login;' }, { title: 'should set pop3_capabilities', attr: 'pop3_capabilities', value: %w[TOP USER UIDL], match: ' pop3_capabilities TOP USER UIDL;' } ].each do |param| context "when #{param[:attr]} is #{param[:value]}" do let :default_params do { listen_port: 25, ipv6_enable: true, protocol: 'pop3' } end let(:params) { default_params.merge(param[:attr].to_sym => param[:value]) } it { is_expected.to contain_concat__fragment("#{title}-header") } it param[:title] do matches = Array(param[:match]) if matches.all? { |m| m.is_a? Regexp } matches.each { |item| is_expected.to contain_concat__fragment("#{title}-header").with_content(item) } else lines = catalogue.resource('concat::fragment', "#{title}-header").send(:parameters)[:content].split("\n") expect(lines & Array(param[:match])).to eq(Array(param[:match])) end end end end end describe 'mailhost template content for smtp' do [ { title: 'should set smtp_auth', attr: 'smtp_auth', value: 'login', match: ' smtp_auth login;' }, { title: 'should set smtp_capabilities', attr: 'smtp_capabilities', value: %w[8BITMIME PIPELINING HELP], match: ' smtp_capabilities 8BITMIME PIPELINING HELP;' } ].each do |param| context "when #{param[:attr]} is #{param[:value]}" do let :default_params do { listen_port: 25, ipv6_enable: true, protocol: 'smtp' } end let(:params) { default_params.merge(param[:attr].to_sym => param[:value]) } it { is_expected.to contain_concat__fragment("#{title}-header") } it param[:title] do matches = Array(param[:match]) if matches.all? { |m| m.is_a? Regexp } matches.each { |item| is_expected.to contain_concat__fragment("#{title}-header").with_content(item) } else lines = catalogue.resource('concat::fragment', "#{title}-header").send(:parameters)[:content].split("\n") expect(lines & Array(param[:match])).to eq(Array(param[:match])) end end end end end describe 'mailhost template content (SSL enabled)' do [ { title: 'should set starttls', attr: 'starttls', value: 'on', match: ' starttls on;' }, { title: 'should set starttls', attr: 'starttls', value: 'only', match: ' starttls only;' }, { title: 'should not enable SSL', attr: 'starttls', value: 'off', notmatch: %r{ ssl_session_timeout 5m;} }, { title: 'should set ssl_certificate', attr: 'ssl_cert', value: 'test-ssl-cert', match: ' ssl_certificate test-ssl-cert;' }, { title: 'should set ssl_certificate_key', attr: 'ssl_key', value: 'test-ssl-cert-key', match: ' ssl_certificate_key test-ssl-cert-key;' }, { title: 'should set ssl_ciphers', attr: 'ssl_ciphers', value: 'ECDHE-ECDSA-CHACHA20-POLY1305', match: ' ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305;' }, { title: 'should set ssl_prefer_server_ciphers to on', attr: 'ssl_prefer_server_ciphers', value: 'on', match: ' ssl_prefer_server_ciphers on;' }, { title: 'should set ssl_prefer_server_ciphers to off', attr: 'ssl_prefer_server_ciphers', value: 'off', match: ' ssl_prefer_server_ciphers off;' }, { title: 'should set ssl_client_certificate', attr: 'ssl_client_cert', value: 'client-cert', match: ' ssl_client_certificate client-cert;' }, { title: 'should set ssl_crl', attr: 'ssl_crl', value: 'crl-file', match: ' ssl_crl crl-file;' }, { title: 'should set ssl_dhparam', attr: 'ssl_dhparam', value: 'dhparam-file', match: ' ssl_dhparam dhparam-file;' }, { title: 'should set ssl_ecdh_curve', attr: 'ssl_ecdh_curve', value: 'secp521r1', match: ' ssl_ecdh_curve secp521r1;' }, { title: 'should set ssl_client_certificate', attr: 'ssl_client_cert', value: 'client-cert', match: ' ssl_client_certificate client-cert;' }, { title: 'should set ssl_password_file', attr: 'ssl_password_file', value: 'password-file', match: ' ssl_password_file password-file;' }, { title: 'should set ssl_protocols', attr: 'ssl_protocols', value: 'TLSv1.2', match: ' ssl_protocols TLSv1.2;' }, { title: 'should set ssl_session_cache', attr: 'ssl_session_cache', value: 'none', match: ' ssl_session_cache none;' }, { title: 'should set ssl_session_ticket_key', attr: 'ssl_session_ticket_key', value: 'key-file', match: ' ssl_session_ticket_key key-file;' }, { title: 'should set ssl_session_tickets', attr: 'ssl_session_tickets', value: 'on', match: ' ssl_session_tickets on;' }, { title: 'should set ssl_session_timeout', attr: 'ssl_session_timeout', value: '20m', match: ' ssl_session_timeout 20m;' }, { title: 'should set ssl_trusted_certificate', attr: 'ssl_trusted_cert', value: 'trust-cert', match: ' ssl_trusted_certificate trust-cert;' }, { title: 'should set ssl_verify_depth', attr: 'ssl_verify_depth', value: 2, match: ' ssl_verify_depth 2;' } ].each do |param| context "when #{param[:attr]} is #{param[:value]}" do let :default_params do { listen_port: 25, starttls: 'on', ssl_cert: 'dummy.crt', ssl_key: 'dummy.key' } end let(:params) { default_params.merge(param[:attr].to_sym => param[:value]) } it { is_expected.to contain_concat__fragment("#{title}-header") } it param[:title] do matches = Array(param[:match]) if matches.all? { |m| m.is_a? Regexp } matches.each { |item| is_expected.to contain_concat__fragment("#{title}-header").with_content(item) } else lines = catalogue.resource('concat::fragment', "#{title}-header").send(:parameters)[:content].split("\n") expect(lines & Array(param[:match])).to eq(Array(param[:match])) end end end end end describe 'mailhost_ssl template content' do [ { title: 'should set the IPv4 SSL listen port', attr: 'ssl_port', value: 45, match: ' listen *:45;' }, { title: 'should enable IPv6', attr: 'ipv6_enable', value: true, match: ' listen [::]:587 default ipv6only=on;' }, { title: 'should not enable IPv6', attr: 'ipv6_enable', value: false, notmatch: %r{ listen\s+\[::\]:587 default ipv6only=on;} }, { title: 'should set the IPv6 listen IP', attr: 'ipv6_listen_ip', value: '2001:0db8:85a3:0000:0000:8a2e:0370:7334', match: ' listen [2001:0db8:85a3:0000:0000:8a2e:0370:7334]:587 default ipv6only=on;' }, { title: 'should set the IPv6 ssl port', attr: 'ssl_port', value: 45, match: ' listen [::]:45 default ipv6only=on;' }, { title: 'should set the IPv6 listen options', attr: 'ipv6_listen_options', value: 'spdy', match: ' listen [::]:587 spdy;' }, { title: 'should set servername(s)', attr: 'server_name', value: %w[name1 name2], match: ' server_name name1 name2;' }, { title: 'should set protocol', attr: 'protocol', value: 'imap', match: ' protocol imap;' }, { title: 'should set xclient', attr: 'xclient', value: 'off', match: ' xclient off;' }, { title: 'should set auth_http', attr: 'auth_http', value: 'test-auth_http', match: ' auth_http test-auth_http;' }, { title: 'should set auth_http_header', attr: 'auth_http_header', value: 'X-Auth-Key "secret_string"', match: ' auth_http_header X-Auth-Key "secret_string";' }, { title: 'should set ssl_protocols', attr: 'ssl_protocols', value: 'test-ssl-protocol', match: ' ssl_protocols test-ssl-protocol;' }, { title: 'should set ssl_ciphers', attr: 'ssl_ciphers', value: 'test-ssl-ciphers', match: ' ssl_ciphers test-ssl-ciphers;' }, { title: 'should set ssl_certificate', attr: 'ssl_cert', value: 'test-ssl-cert', match: ' ssl_certificate test-ssl-cert;' }, { title: 'should set ssl_certificate_key', attr: 'ssl_key', value: 'test-ssl-cert-key', match: ' ssl_certificate_key test-ssl-cert-key;' } ].each do |param| context "when #{param[:attr]} is #{param[:value]}" do let :default_params do { listen_port: 25, ssl_port: 587, ipv6_enable: true, ssl: true, ssl_protocols: 'default-protocols', ssl_ciphers: 'default-ciphers', ssl_cert: 'dummy.crt', ssl_key: 'dummy.key' } end let(:params) { default_params.merge(param[:attr].to_sym => param[:value]) } it { is_expected.to contain_concat__fragment("#{title}-ssl") } it param[:title] do matches = Array(param[:match]) if matches.all? { |m| m.is_a? Regexp } matches.each { |item| is_expected.to contain_concat__fragment("#{title}-ssl").with_content(item) } else lines = catalogue.resource('concat::fragment', "#{title}-ssl").send(:parameters)[:content].split("\n") expect(lines & Array(param[:match])).to eq(Array(param[:match])) end end end end context 'on nginx 1.16' do let(:params) do { listen_port: 25, ssl_port: 587, ipv6_enable: true, ssl: true, ssl_protocols: 'default-protocols', ssl_ciphers: 'default-ciphers', ssl_cert: 'dummy.crt', ssl_key: 'dummy.key' } end context 'when version comes from fact' do let(:facts) do facts.merge(nginx_version: '1.16.0') end let(:pre_condition) { ['include ::nginx'] } it 'has `ssl` at end of listen directive' do content = catalogue.resource('concat::fragment', "#{title}-ssl").send(:parameters)[:content] expect(content).to include('listen *:587 ssl;') end end context 'when version comes from parameter' do let(:pre_condition) { ['class { "nginx": nginx_version => "1.16.0"}'] } it 'also has `ssl` at end of listen directive' do content = catalogue.resource('concat::fragment', "#{title}-ssl").send(:parameters)[:content] expect(content).to include('listen *:587 ssl;') end end end end context 'attribute resources' do context 'SSL cert missing and ssl => true' do let(:params) do default_params.merge( ssl: true, ssl_key: 'key' ) end it { expect { is_expected.to contain_class('nginx::resource::server') }.to raise_error(Puppet::Error, %r{nginx: SSL certificate/key \(ssl_cert/ssl_cert\) and/or SSL Private must be defined and exist on the target system\(s\)}) } end context 'SSL key missing and ssl => true' do let :params do default_params.merge(ssl: true, ssl_cert: 'cert') end it { expect { is_expected.to contain_class('nginx::resource::server') }.to raise_error(Puppet::Error, %r{nginx: SSL certificate/key \(ssl_cert/ssl_cert\) and/or SSL Private must be defined and exist on the target system\(s\)}) } end context "SSL cert missing and starttls => 'on'" do let :params do default_params.merge(starttls: 'on', ssl_key: 'key') end it { expect { is_expected.to contain_class('nginx::resource::server') }.to raise_error(Puppet::Error, %r{nginx: SSL certificate/key \(ssl_cert/ssl_cert\) and/or SSL Private must be defined and exist on the target system\(s\)}) } end context "SSL key missing and starttls => 'on'" do let :params do default_params.merge(starttls: 'on', ssl_cert: 'cert') end it { expect { is_expected.to contain_class('nginx::resource::server') }.to raise_error(Puppet::Error, %r{nginx: SSL certificate/key \(ssl_cert/ssl_cert\) and/or SSL Private must be defined and exist on the target system\(s\)}) } end context "SSL cert missing and starttls => 'only'" do let :params do default_params.merge(starttls: 'only', ssl_key: 'key') end it { expect { is_expected.to contain_class('nginx::resource::server') }.to raise_error(Puppet::Error, %r{nginx: SSL certificate/key \(ssl_cert/ssl_cert\) and/or SSL Private must be defined and exist on the target system\(s\)}) } end context "SSL key missing and starttls => 'only'" do let :params do default_params.merge(starttls: 'only', ssl_cert: 'cert') end it { expect { is_expected.to contain_class('nginx::resource::server') }.to raise_error(Puppet::Error, %r{nginx: SSL certificate/key \(ssl_cert/ssl_cert\) and/or SSL Private must be defined and exist on the target system\(s\)}) } end context 'when listen_port != ssl_port' do let :params do default_params.merge(listen_port: 80, ssl_port: 443) end it { is_expected.to contain_concat__fragment("#{title}-header") } end context 'when listen_port != "ssl_port"' do let :params do default_params.merge(listen_port: 80, ssl_port: 443) end it { is_expected.to contain_concat__fragment("#{title}-header") } end context 'when listen_port == ssl_port' do let :params do default_params.merge(listen_port: 80, ssl_port: 80) end it { is_expected.not_to contain_concat__fragment("#{title}-header") } end context 'when listen_port == "ssl_port"' do let :params do default_params.merge(listen_port: 80, ssl_port: 80) end it { is_expected.not_to contain_concat__fragment("#{title}-header") } end context 'when ssl => true' do let :params do default_params.merge(ensure: 'absent', ssl: true, ssl_key: 'dummy.key', ssl_cert: 'dummy.cert') end it { is_expected.to contain_concat__fragment("#{title}-header") } it { is_expected.to contain_concat__fragment("#{title}-ssl") } end context 'when ssl => false' do let :params do default_params.merge(ensure: 'absent', ssl: false) end it { is_expected.to contain_concat__fragment("#{title}-header") } it { is_expected.not_to contain_concat__fragment("#{title}-ssl") } end end end end end end