diff --git a/Gemfile b/Gemfile index 4639be0..f8fcf47 100644 --- a/Gemfile +++ b/Gemfile @@ -1,43 +1,42 @@ # This file is managed centrally by modulesync # https://github.com/theforeman/foreman-installer-modulesync source 'https://rubygems.org' gem 'puppet', ENV.key?('PUPPET_VERSION') ? "~> #{ENV['PUPPET_VERSION']}" : '>= 4.6' gem 'rake' gem 'rspec', '~> 3.0' gem 'rdoc', '~> 5.1.0', {"platforms"=>["ruby_21"]} gem 'rspec-puppet', '~> 2.3' gem 'rspec-puppet-facts', '>= 1.7' gem 'puppetlabs_spec_helper', '>= 2.1.1' gem 'puppet-lint', '>= 2' -gem 'puppet-lint-absolute_classname-check' gem 'puppet-lint-classes_and_types_beginning_with_digits-check' gem 'puppet-lint-empty_string-check' gem 'puppet-lint-file_ensure-check' gem 'puppet-lint-leading_zero-check' gem 'puppet-lint-param-docs', '>= 1.3.0' gem 'puppet-lint-spaceship_operator_without_tag-check' gem 'puppet-lint-strict_indent-check' gem 'puppet-lint-trailing_comma-check' gem 'puppet-lint-undef_in_function-check' gem 'puppet-lint-unquoted_string-check' gem 'puppet-lint-variable_contains_upcase' gem 'puppet-lint-version_comparison-check' gem 'simplecov' gem 'github_changelog_generator', {"git"=>"https://github.com/skywinder/github-changelog-generator", "ref"=>"20ee04ba1234e9e83eb2ffb5056e23d641c7a018", "groups"=>["development"]} gem 'puppet-blacksmith', '>= 4.1.0', {"groups"=>["development"]} gem 'beaker', '>= 4.0.0', {"groups"=>["system_tests"]} gem 'beaker-docker', {"groups"=>["system_tests"]} gem 'beaker-hostgenerator', '>= 1.1.10', {"groups"=>["system_tests"]} gem 'beaker-puppet', {"groups"=>["system_tests"]} gem 'beaker-rspec', {"groups"=>["system_tests"]} gem 'beaker-module_install_helper', {"groups"=>["system_tests"]} gem 'beaker-puppet_install_helper', {"groups"=>["system_tests"]} gem 'metadata-json-lint' gem 'kafo_module_lint' gem 'rgen' gem 'parallel_tests' # vim:ft=ruby diff --git a/manifests/server/config.pp b/manifests/server/config.pp index 889ee74..1c8aed9 100644 --- a/manifests/server/config.pp +++ b/manifests/server/config.pp @@ -1,315 +1,315 @@ # Set up the puppet server config class puppet::server::config inherits puppet::config { if $::puppet::server::passenger and $::puppet::server::implementation == 'master' { - contain 'puppet::server::passenger' # lint:ignore:relative_classname_inclusion (PUP-1597) + contain 'puppet::server::passenger' } if $::puppet::server::implementation == 'puppetserver' { - contain 'puppet::server::puppetserver' # lint:ignore:relative_classname_inclusion (PUP-1597) + contain 'puppet::server::puppetserver' unless empty($::puppet::server::puppetserver_vardir) { puppet::config::master { 'vardir': value => $::puppet::server::puppetserver_vardir; } } unless empty($::puppet::server::puppetserver_rundir) { puppet::config::master { 'rundir': value => $::puppet::server::puppetserver_rundir; } } unless empty($::puppet::server::puppetserver_logdir) { puppet::config::master { 'logdir': value => $::puppet::server::puppetserver_logdir; } } } # Mirror the relationship, as defined() is parse-order dependent # Ensures puppetmasters certs are generated before the proxy is needed if defined(Class['foreman_proxy::config']) and $foreman_proxy::ssl { Class['puppet::server::config'] ~> Class['foreman_proxy::config'] Class['puppet::server::config'] ~> Class['foreman_proxy::service'] } # And before Foreman's cert-using service needs it if defined(Class['foreman::service']) and $foreman::ssl { Class['puppet::server::config'] -> Class['foreman::service'] } ## General configuration $ca_server = $::puppet::ca_server $ca_port = $::puppet::ca_port $server_storeconfigs_backend = $::puppet::server::storeconfigs_backend $server_external_nodes = $::puppet::server::external_nodes $server_environment_timeout = $::puppet::server::environment_timeout if $server_external_nodes and $server_external_nodes != '' { class{ '::puppet::server::enc': enc_path => $server_external_nodes, } } $autosign = ($::puppet::server::autosign =~ Boolean)? { true => $::puppet::server::autosign, false => "${::puppet::server::autosign} { mode = ${::puppet::server::autosign_mode} }" } puppet::config::main { 'reports': value => $::puppet::server::reports; } if $::puppet::server::hiera_config and !empty($::puppet::server::hiera_config){ puppet::config::main { 'hiera_config': value => $::puppet::server::hiera_config; } } if $puppet::server::directory_environments { puppet::config::main { 'environmentpath': value => $puppet::server::envs_dir; } } if $puppet::server::common_modules_path and !empty($puppet::server::common_modules_path) { puppet::config::main { 'basemodulepath': value => $puppet::server::common_modules_path, joiner => ':'; } } if $puppet::server::default_manifest { puppet::config::main { 'default_manifest': value => $puppet::server::default_manifest_path; } } puppet::config::master { 'autosign': value => $autosign; 'ca': value => $::puppet::server::ca; 'certname': value => $::puppet::server::certname; 'parser': value => $::puppet::server::parser; 'strict_variables': value => $::puppet::server::strict_variables; } if $::puppet::server::ssl_dir_manage { puppet::config::master { 'ssldir': value => $::puppet::server::ssl_dir; } } if $server_environment_timeout { puppet::config::master { 'environment_timeout': value => $server_environment_timeout; } } if $server_storeconfigs_backend { puppet::config::master { 'storeconfigs': value => true; 'storeconfigs_backend': value => $server_storeconfigs_backend; } } if !$::puppet::server::directory_environments and ($::puppet::server::git_repo or $::puppet::server::dynamic_environments) { puppet::config::master { 'manifest': value => "${::puppet::server::envs_dir}/\$environment/manifests/site.pp"; 'modulepath': value => "${::puppet::server::envs_dir}/\$environment/modules"; } if $::puppet::server::config_version_cmd { puppet::config::master { 'config_version': value => $::puppet::server::config_version_cmd; } } } $::puppet::server_additional_settings.each |$key,$value| { puppet::config::master { $key: value => $value } } file { "${puppet::vardir}/reports": ensure => directory, owner => $::puppet::server::user, group => $::puppet::server::group, mode => '0750', } if '/usr/share/puppet/modules' in $puppet::server::common_modules_path { # Create Foreman share dir which does not depend on Puppet version exec { 'mkdir -p /usr/share/puppet/modules': creates => '/usr/share/puppet/modules', path => ['/usr/bin', '/bin'], } } ## SSL and CA configuration # Open read permissions to private keys to puppet group for foreman, proxy etc. file { "${::puppet::server::ssl_dir}/private_keys": ensure => directory, owner => $::puppet::server::user, group => $::puppet::server::group, mode => '0750', require => Exec['puppet_server_config-create_ssl_dir'], } if $puppet::server::ssl_key_manage { file { "${::puppet::server::ssl_dir}/private_keys/${::puppet::server::certname}.pem": owner => $::puppet::server::user, group => $::puppet::server::group, mode => '0640', } } # If the ssl dir is not the default dir, it needs to be created before running # the generate ca cert or it will fail. exec {'puppet_server_config-create_ssl_dir': creates => $::puppet::server::ssl_dir, command => "/bin/mkdir -p ${::puppet::server::ssl_dir}", umask => '0022', } # Generate a new CA and host cert if our host cert doesn't exist if $::puppet::server::ca { exec {'puppet_server_config-generate_ca_cert': creates => $::puppet::server::ssl_cert, command => "${::puppet::puppetca_cmd} --generate ${::puppet::server::certname} --allow-dns-alt-names", umask => '0022', require => [ Concat["${::puppet::server::dir}/puppet.conf"], Exec['puppet_server_config-create_ssl_dir'], ], } } elsif $::puppet::server::ca_crl_sync { # If not a ca AND sync the crl from the ca master if defined('$::servername') { file { $::puppet::server::ssl_ca_crl: ensure => file, owner => $::puppet::server::user, group => $::puppet::server::group, mode => '0644', content => file($::settings::cacrl, $::settings::hostcrl, '/dev/null'), } } } if $::puppet::server::passenger and $::puppet::server::implementation == 'master' and $::puppet::server::ca { Exec['puppet_server_config-generate_ca_cert'] ~> Service[$::puppet::server::httpd_service] } # autosign file if $::puppet::server_ca and !($puppet::server::autosign =~ Boolean) { if $::puppet::server::autosign_content or $::puppet::server::autosign_source { if !empty($::puppet::server::autosign_entries) { fail('Cannot set both autosign_content/autosign_source and autosign_entries') } $autosign_content = $::puppet::server::autosign_content } elsif !empty($::puppet::server::autosign_entries) { $autosign_content = template('puppet/server/autosign.conf.erb') } else { $autosign_content = undef } file { $::puppet::server::autosign: ensure => file, owner => $::puppet::server::user, group => $::puppet::server::group, mode => $::puppet::server::autosign_mode, content => $autosign_content, source => $::puppet::server::autosign_source, } } # only manage this file if we provide content if $::puppet::server::default_manifest and $::puppet::server::default_manifest_content != '' { file { $::puppet::server::default_manifest_path: ensure => file, owner => $puppet::user, group => $puppet::group, mode => '0644', content => $::puppet::server::default_manifest_content, } } ## Environments # location where our puppet environments are located if $::puppet::server::envs_target and $::puppet::server::envs_target != '' { $ensure = 'link' } else { $ensure = 'directory' } file { $::puppet::server::envs_dir: ensure => $ensure, owner => $::puppet::server::environments_owner, group => $::puppet::server::environments_group, mode => $::puppet::server::environments_mode, target => $::puppet::server::envs_target, force => true, } if $::puppet::server::git_repo { # need to chown the $vardir before puppet does it, or else # we can't write puppet.git/ on the first run include ::git git::repo { 'puppet_repo': bare => true, target => $::puppet::server::git_repo_path, mode => $::puppet::server::git_repo_mode, user => $::puppet::server::git_repo_user, group => $::puppet::server::git_repo_group, require => File[$::puppet::server::envs_dir], } $git_branch_map = $::puppet::server::git_branch_map # git post hook to auto generate an environment per branch file { "${::puppet::server::git_repo_path}/hooks/${::puppet::server::post_hook_name}": content => template($::puppet::server::post_hook_content), owner => $::puppet::server::git_repo_user, group => $::puppet::server::git_repo_group, mode => $::puppet::server::git_repo_mode, require => Git::Repo['puppet_repo'], } } elsif ! $::puppet::server::dynamic_environments { file { $puppet::sharedir: ensure => directory, } if $::puppet::server::common_modules_path and $::puppet::server::common_modules_path != '' { file { $::puppet::server::common_modules_path: ensure => directory, owner => $::puppet::server_environments_owner, group => $::puppet::server_environments_group, mode => $::puppet::server_environments_mode, } } # setup empty directories for our environments puppet::server::env {$::puppet::server::environments: } } ## Foreman if $::puppet::server::foreman { # Include foreman components for the puppetmaster # ENC script, reporting script etc. anchor { 'puppet::server::config_start': } -> class {'::foreman::puppetmaster': foreman_url => $::puppet::server::foreman_url, receive_facts => $::puppet::server::server_foreman_facts, puppet_home => $::puppet::server::puppetserver_vardir, puppet_basedir => $::puppet::server::puppet_basedir, puppet_etcdir => $puppet::dir, enc_api => $::puppet::server::enc_api, report_api => $::puppet::server::report_api, timeout => $::puppet::server::request_timeout, ssl_ca => pick($::puppet::server::foreman_ssl_ca, $::puppet::server::ssl_ca_cert), ssl_cert => pick($::puppet::server::foreman_ssl_cert, $::puppet::server::ssl_cert), ssl_key => pick($::puppet::server::foreman_ssl_key, $::puppet::server::ssl_cert_key), } ~> anchor { 'puppet::server::config_end': } } ## PuppetDB if $::puppet::server::puppetdb_host { class { '::puppetdb::master::config': puppetdb_server => $::puppet::server::puppetdb_host, puppetdb_port => $::puppet::server::puppetdb_port, puppetdb_soft_write_failure => $::puppet::server::puppetdb_swf, manage_storeconfigs => false, restart_puppet => false, } Class['puppetdb::master::puppetdb_conf'] ~> Class['puppet::server::service'] } } diff --git a/manifests/server/passenger.pp b/manifests/server/passenger.pp index 5c9ac96..d47f6f6 100644 --- a/manifests/server/passenger.pp +++ b/manifests/server/passenger.pp @@ -1,141 +1,141 @@ # == Class: puppet::server::passenger # # Set up the puppet server using passenger and apache. # class puppet::server::passenger ( $app_root = $::puppet::server::app_root, $passenger_min_instances = $::puppet::server::passenger_min_instances, $passenger_pre_start = $::puppet::server::passenger_pre_start, $passenger_ruby = $::puppet::server::passenger_ruby, $port = $::puppet::server::port, $ssl_ca_cert = $::puppet::server::ssl_ca_cert, $ssl_ca_crl = $::puppet::server::ssl_ca_crl, $ssl_cert = $::puppet::server::ssl_cert, $ssl_cert_key = $::puppet::server::ssl_cert_key, $ssl_chain = $::puppet::server::ssl_chain, $ssl_dir = $::puppet::server::ssl_dir, $ssl_protocol = 'ALL -SSLv2 -SSLv3', $ssl_cipher = 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA', $puppet_ca_proxy = $::puppet::server::ca_proxy, $user = $::puppet::server::user, $http = $::puppet::server::http, $http_port = $::puppet::server::http_port, $http_allow = $::puppet::server::http_allow, $confdir = $::puppet::server::dir, $rack_arguments = $::puppet::server::rack_arguments, $vardir = $::puppet::vardir, ) { include ::apache include ::apache::mod::passenger - contain 'puppet::server::rack' # lint:ignore:relative_classname_inclusion (PUP-1597) + contain 'puppet::server::rack' $directory = { 'path' => "${app_root}/public/", 'passenger_enabled' => 'On', } $directories = [ $directory, ] $http_pre_start = $passenger_pre_start ? { true => "http://${::fqdn}:${http_port}", false => undef, } $https_pre_start = $passenger_pre_start ? { true => "https://${::fqdn}:${port}", false => undef, } # The following client headers allow the same configuration to work with Pound. $request_headers = [ 'set X-SSL-Subject %{SSL_CLIENT_S_DN}e', 'set X-Client-DN %{SSL_CLIENT_S_DN}e', 'set X-Client-Verify %{SSL_CLIENT_VERIFY}e', 'unset X-Forwarded-For', ] if $puppet_ca_proxy and $puppet_ca_proxy != '' { include ::apache::mod::proxy include ::apache::mod::proxy_http $custom_fragment = "ProxyPassMatch ^/([^/]+/certificate.*)$ ${puppet_ca_proxy}/\$1" $ssl_proxyengine = true } else { $custom_fragment = undef $ssl_proxyengine = false } $ssl_crl_check = $ssl_ca_crl ? { false => undef, undef => undef, default => 'chain', } apache::vhost { 'puppet': docroot => "${app_root}/public/", directories => $directories, port => $port, ssl => true, ssl_cert => $ssl_cert, ssl_key => $ssl_cert_key, ssl_ca => $ssl_ca_cert, ssl_crl => $ssl_ca_crl, ssl_crl_check => $ssl_crl_check, ssl_chain => $ssl_chain, ssl_protocol => $ssl_protocol, ssl_cipher => $ssl_cipher, ssl_honorcipherorder => 'on', ssl_verify_client => 'optional', ssl_options => '+StdEnvVars +ExportCertData', ssl_verify_depth => '1', ssl_proxyengine => $ssl_proxyengine, custom_fragment => $custom_fragment, request_headers => $request_headers, options => ['None'], passenger_pre_start => $https_pre_start, passenger_min_instances => $passenger_min_instances, passenger_ruby => $passenger_ruby, require => Class['::puppet::server::rack'], } if $http { # Order, deny and allow cannot be configured for Apache >= 2.4 using the Puppetlabs/Apache # module, but they can be set to false. So, set to false and configure manually via custom fragments. # We can't get rid of the 'Order allow,deny' directive and we need to support all Apache versions. # Best we can do is reverse the Order directive and add our own 'Deny from all' for good measure. $directories_http = [ merge($directory, { 'order' => false, 'deny' => false, 'allow' => false, 'custom_fragment' => join([ 'Order deny,allow', 'Deny from all', inline_template("<%- if @http_allow and Array(@http_allow).join(' ') != '' -%>Allow from <%= @http_allow.join(' ') %><%- end -%>"), ], "\n") }), ] apache::vhost { 'puppet-http': docroot => "${app_root}/public/", directories => $directories_http, port => $http_port, ssl_proxyengine => $ssl_proxyengine, custom_fragment => join([ $custom_fragment ? { undef => '', default => $custom_fragment }, 'SetEnvIf X-Client-Verify "(.*)" SSL_CLIENT_VERIFY=$1', 'SetEnvIf X-SSL-Client-DN "(.*)" SSL_CLIENT_S_DN=$1', ], "\n"), options => ['None'], passenger_pre_start => $http_pre_start, passenger_min_instances => $passenger_min_instances, passenger_ruby => $passenger_ruby, require => Class['::puppet::server::rack'], } } }