diff --git a/README.markdown b/README.markdown index cd3e9043d..ebb92584d 100644 --- a/README.markdown +++ b/README.markdown @@ -13,6 +13,7 @@ as this module requires the passenger apache module. Requires the following modules from puppetforge: [stdlib](https://forge.puppetlabs.com/puppetlabs/stdlib), [apache](https://forge.puppetlabs.com/puppetlabs/apache), [concat](https://forge.puppetlabs.com/puppetlabs/concat), [inifile](https://forge.puppetlabs.com/puppetlabs/inifile) + ## Usage Note ## If you are using this module to install a puppetmaster and serving the manifest of @@ -52,6 +53,13 @@ Puppet 3.5 introduced a new way of handling Puppet environments known as _Direct Optionally, an `environmentpath` parameter can be supplied to configure the base root of Puppet environments, this defaults to `$confdir/environments` +### Support for httpd and nginx ### + + class { 'puppet::master': + webserver => 'nginx' + } + +The default installed webserver is httpd with passenger, but via the webserver param you can switch to nginx with unicorn (nginx is currently only tested on centos7, testers are welcome). Note that if you have selinux enabled, you must have [this](https://github.com/gavinrogers/puppet-selinux) selinux module installed. ## Agent ## class { 'puppet::agent': diff --git a/files/nginx.selmodule b/files/nginx.selmodule new file mode 100644 index 000000000..1374cf27c Binary files /dev/null and b/files/nginx.selmodule differ diff --git a/manifests/agent.pp b/manifests/agent.pp index b9fe1e4dd..64a86a763 100644 --- a/manifests/agent.pp +++ b/manifests/agent.pp @@ -31,6 +31,8 @@ # ['templatedir'] - Template dir, if unset it will remove the setting. # ['configtimeout'] - How long the client should wait for the configuration to be retrieved before considering it a failure # ['stringify_facts'] - Wether puppet transforms structured facts in strings or no. Defaults to true in puppet < 4, deprecated in puppet >=4 (and will default to false) +# ['serialization_format'] - defaults to undef, otherwise it sets the preferred_serialization_format param (currently only msgpack is supported) +# ['serialization_package'] - defaults to undef, if provided, we install this package, otherwise we fall back to the gem from 'serialization_format' # ['cron_hour'] - What hour to run if puppet_run_style is cron # ['cron_minute'] - What minute to run if puppet_run_style is cron # ['serialization_format'] - defaults to undef, otherwise it sets the preferred_serialization_format param (currently only msgpack is supported) @@ -444,6 +446,10 @@ ensure => 'latest', provider => 'gem', require => Package[$::puppet::params::ruby_dev, 'gcc'], + } ~> + exec{'cleanup_old_gems': + command => '/usr/bin/gem cleanup msgpack', + refreshonly => true, } } } @@ -454,3 +460,4 @@ } } } + diff --git a/manifests/master.pp b/manifests/master.pp index 894e0ae67..5e451527b 100644 --- a/manifests/master.pp +++ b/manifests/master.pp @@ -22,7 +22,8 @@ # ['puppet_ssldir'] - Puppet sll directory # ['puppet_docroot'] - Doc root to be configured in apache vhost # ['puppet_vardir'] - Vardir used by puppet -# ['puppet_passenger_port'] - Port to configure passenger on default 8140 +# ['puppet_proxy_port'] - Port to configure the proxy on - default 8140 +# ['puppet_conf'] - Path to the puppet main/agent/master config # ['puppet_master_package'] - Puppet master package # ['puppet_master_service'] - Puppet master service # ['version'] - Version of the puppet master package to install @@ -37,6 +38,15 @@ # ['always_cache_features'] - if false (default), always try to load a feature even if a previous load failed # ['serialization_format'] - defaults to undef, otherwise it sets the preferred_serialization_format param (currently only msgpack is supported) # ['serialization_package'] - defaults to undef, if provided, we install this package, otherwise we fall back to the gem from 'serialization_format' +# ['webserver'] - install 'nginx' (with unicorn) or 'httpd' (with passenger) - httpd is default +# ['listen_address'] - IP for binding the webserver, defaults to * +# ['disable_ssl'] - Disables SSL on the webserver. usefull if you use this master behind a loadbalancer. currently only supported by nginx, defaults to undef +# ['backup_upstream'] - specify another puppet master as fallback. currently only supported by nginx +# ['unicorn_package'] - package name of a unicorn rpm. if provided we install it, otherwise we built it via gem/gcc +# ['unicorn_path'] - custom path to the unicorn binary +# ['disable_master'] - this disables the normal master, the server will only act as a CA, currently only supported by nginx +# ['upstream'] - define additional masters reachable via tcp as an array, currently only supported by nginx +# ['backend_process_number'] - number of processes to start on the backebd webserver (unicorn/passenger), currently only supported by unicorn # # Requires: # @@ -77,7 +87,7 @@ $puppet_ssldir = $::puppet::params::puppet_ssldir, $puppet_docroot = $::puppet::params::puppet_docroot, $puppet_vardir = $::puppet::params::puppet_vardir, - $puppet_passenger_port = $::puppet::params::puppet_passenger_port, + $puppet_proxy_port = $::puppet::params::puppet_proxy_port, $puppet_passenger_tempdir = false, $puppet_passenger_cfg_addon = '', $puppet_master_package = $::puppet::params::puppet_master_package, @@ -100,6 +110,18 @@ $passenger_stat_throttle_rate = 30, $serialization_format = undef, $serialization_package = undef, + $webserver = $::puppet::params::default_webserver, + $listen_address = $::puppet::params::listen_address, + $disable_ssl = $::puppet::params::disable_ssl, + $backup_upstream = $::puppet::params::backup_upstream, + $unicorn_path = $::puppet::params::unicorn_path, + $unicorn_package = $::puppet::params::unicorn_package, + $unicorn_ensure = $::puppet::params::unicorn_ensure, + $rack_ensure = $::puppet::params::rack_ensure, + $disable_master = $::puppet::params::disable_master, + $upstream = $::puppet::params::upstream, + $backend_process_number = $::puppet::params::backend_process_number, + ) inherits puppet::params { anchor { 'puppet::master::begin': } @@ -135,28 +157,51 @@ ensure => $version, } } + case $webserver { + nginx: { + Anchor['puppet::master::begin'] -> + class {'puppet::unicorn': + certname => $certname, + puppet_conf => $::puppet::params::puppet_conf, + puppet_ssldir => $puppet_ssldir, + dns_alt_names => $dns_alt_names, + listen_address => $listen_address, + puppet_proxy_port => $puppet_proxy_port, + disable_ssl => $disable_ssl, + backup_upstream => $backup_upstream, + unicorn_package => $unicorn_package, + unicorn_ensure => $unicorn_ensure, + unicorn_path => $unicorn_path, + rack_ensure => $rack_ensure, + disable_master => $disable_master, + upstream => $upstream, + backend_process_number => $backend_process_number, + } -> + Anchor['puppet::master::end'] + } + default: { + Anchor['puppet::master::begin'] -> + class {'puppet::passenger': + puppet_proxy_port => $puppet_proxy_port, + puppet_docroot => $puppet_docroot, + apache_serveradmin => $apache_serveradmin, + puppet_conf => $::puppet::params::puppet_conf, + puppet_ssldir => $puppet_ssldir, + certname => $certname, + conf_dir => $::puppet::params::confdir, + dns_alt_names => join($dns_alt_names,','), + generate_ssl_certs => $generate_ssl_certs, + puppet_passenger_tempdir => $puppet_passenger_tempdir, + config_addon => $puppet_passenger_cfg_addon, + passenger_max_pool_size => $passenger_max_pool_size, + passenger_high_performance => $passenger_high_performance, + passenger_max_requests => $passenger_max_requests, + passenger_stat_throttle_rate => $passenger_stat_throttle_rate, - Anchor['puppet::master::begin'] -> - class {'puppet::passenger': - puppet_passenger_port => $puppet_passenger_port, - puppet_docroot => $puppet_docroot, - apache_serveradmin => $apache_serveradmin, - puppet_conf => $::puppet::params::puppet_conf, - puppet_ssldir => $puppet_ssldir, - certname => $certname, - conf_dir => $::puppet::params::confdir, - dns_alt_names => join($dns_alt_names,','), - generate_ssl_certs => $generate_ssl_certs, - puppet_passenger_tempdir => $puppet_passenger_tempdir, - config_addon => $puppet_passenger_cfg_addon, - passenger_max_pool_size => $passenger_max_pool_size, - passenger_high_performance => $passenger_high_performance, - passenger_max_requests => $passenger_max_requests, - passenger_stat_throttle_rate => $passenger_stat_throttle_rate, - - } -> - Anchor['puppet::master::end'] - + } -> + Anchor['puppet::master::end'] + } + } service { $puppet_master_service: ensure => stopped, enable => false, @@ -170,12 +215,12 @@ require => File[$::puppet::params::confdir], owner => $::puppet::params::puppet_user, group => $::puppet::params::puppet_group, - notify => Service['httpd'], + notify => Service[$webserver], } } else { File<| title == $::puppet::params::puppet_conf |> { - notify => Service['httpd'], + notify => Service[$webserver], } } @@ -186,12 +231,12 @@ require => Package[$puppet_master_package], owner => $::puppet::params::puppet_user, group => $::puppet::params::puppet_group, - notify => Service['httpd'], + notify => Service[$webserver], } } else { File<| title == $::puppet::params::confdir |> { - notify +> Service['httpd'], + notify +> Service[$webserver], require +> Package[$puppet_master_package], } } @@ -200,7 +245,7 @@ ensure => directory, owner => $::puppet::params::puppet_user, group => $::puppet::params::puppet_group, - notify => Service['httpd'], + notify => Service[$webserver], require => Package[$puppet_master_package] } @@ -209,7 +254,7 @@ class { 'puppet::storeconfigs': dbserver => $storeconfigs_dbserver, dbport => $storeconfigs_dbport, - puppet_service => Service['httpd'], + puppet_service => Service[$webserver], puppet_confdir => $::puppet::params::confdir, puppet_conf => $::puppet::params::puppet_conf, puppet_master_package => $puppet_master_package, @@ -223,7 +268,7 @@ Ini_setting { path => $::puppet::params::puppet_conf, require => File[$::puppet::params::puppet_conf], - notify => Service['httpd'], + notify => Service[$webserver], section => 'master', } @@ -332,21 +377,6 @@ setting => 'digest_algorithm', value => $digest_algorithm, } - - if $strict_variables != undef { - validate_bool(str2bool($strict_variables)) - ini_setting {'puppetmasterstrictvariables': - ensure => present, - setting => 'strict_variables', - value => $strict_variables, - } - } - validate_bool(str2bool($always_cache_features)) - ini_setting { 'puppetmasteralwayscachefeatures': - ensure => present, - setting => 'always_cache_features', - value => $always_cache_features, - } if $serialization_format != undef { if $serialization_package != undef { package { $serialization_package: @@ -356,19 +386,23 @@ if $serialization_format == 'msgpack' { unless defined(Package[$::puppet::params::ruby_dev]) { package {$::puppet::params::ruby_dev: - ensure => 'latest', + ensure => latest, } } unless defined(Package['gcc']) { package {'gcc': - ensure => 'latest', + ensure => latest, } } unless defined(Package['msgpack']) { package {'msgpack': - ensure => 'latest', - provider => 'gem', + ensure => latest, + provider => gem, require => Package[$::puppet::params::ruby_dev, 'gcc'], + } ~> + exec{'cleanup_old_gems': + command => '/usr/bin/gem cleanup msgpack', + refreshonly => true, } } } @@ -378,5 +412,19 @@ value => $serialization_format, } } + if $strict_variables != undef { + validate_bool(str2bool($strict_variables)) + ini_setting {'puppetmasterstrictvariables': + ensure => present, + setting => 'strict_variables', + value => $strict_variables, + } + } + validate_bool(str2bool($always_cache_features)) + ini_setting { 'puppetmasteralwayscachefeatures': + ensure => present, + setting => 'always_cache_features', + value => $always_cache_features, + } anchor { 'puppet::master::end': } } diff --git a/manifests/params.pp b/manifests/params.pp index 240a1033d..5b4c78013 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -23,7 +23,8 @@ $manifest = '/etc/puppet/manifests/site.pp' $hiera_config = '/etc/puppet/hiera.yaml' $puppet_docroot = '/etc/puppet/rack/public/' - $puppet_passenger_port = '8140' + $puppet_proxy_port = '8140' + $puppet_passenger_tempdir = '/var/run/rubygem-passenger' $puppet_server_port = '8140' $puppet_agent_enabled = true $apache_serveradmin = 'root' @@ -34,6 +35,17 @@ $puppet_run_interval = 30 $classfile = '$statedir/classes.txt' $package_provider = undef # falls back to system default + $listen_address = '*' + $default_webserver = 'httpd' + $disable_ssl = undef + $backup_upstream = [] + $unicorn_package = undef + $unicorn_path = '/usr/local/bin/unicorn' + $disable_master = false + $upstream = [] + $backend_process_number = $::processorcount + $unicorn_ensure = latest + $rack_ensure = latest # Only used when environments == directory $environmentpath = "${confdir}/environments" @@ -90,6 +102,17 @@ $puppet_vardir = '/var/lib/puppet' $puppet_ssldir = '/etc/puppet/ssl' } + 'Archlinux': { + $puppet_master_package = 'puppet' + $puppet_agent_service = 'puppet.service' + $puppet_agent_package = 'puppet' + $puppet_conf = '/etc/puppet/puppet.conf' + $puppet_vardir = '/var/lib/puppet' + $puppet_ssldir = '/var/lib/puppet/ssl' + $passenger_package = 'passenger' + $rack_package = 'ruby-rack' + $ruby_dev = 'ruby' + } default: { err('The Puppet module does not support your os') } diff --git a/manifests/passenger.pp b/manifests/passenger.pp index bf2e3224b..0c7f0cd3d 100644 --- a/manifests/passenger.pp +++ b/manifests/passenger.pp @@ -3,14 +3,14 @@ # This class installs and configures the puppetdb terminus pacakge # # Parameters: -# ['generate_ssl_certs'] - Generate ssl certs (false to disable) -# ['puppet_passenger_port'] - The port for the virtual host -# ['puppet_docroot'] - Apache documnet root -# ['apache_serveradmin'] - The apache server admin -# ['puppet_conf'] - The puppet config dir -# ['puppet_ssldir'] - The pupet ssl dir -# ['certname'] - The puppet certname -# [conf_dir] - The configuration directory of the puppet install +# ['puppet_proxy_port'] - The port for the virtual host +# ['generate_ssl_certs'] - Generate ssl certs (false to disable) +# ['puppet_docroot'] - Apache documnet root +# ['apache_serveradmin'] - The apache server admin +# ['puppet_conf'] - The puppet config dir +# ['puppet_ssldir'] - The pupet ssl dir +# ['certname'] - The puppet certname +# [conf_dir] - The configuration directory of the puppet install # # Actions: # - Configures apache and passenger for puppet master use. @@ -22,18 +22,18 @@ # # Sample Usage: # class { 'puppet::passenger': -# puppet_passenger_port => 8140, -# puppet_docroot => '/etc/puppet/docroot', -# apache_serveradmin => 'wibble', -# puppet_conf => '/etc/puppet/puppet.conf', -# puppet_ssldir => '/var/lib/puppet/ssl', -# certname => 'puppet.example.com', -# conf_dir => '/etc/puppet', +# puppet_proxy_port => 8140, +# puppet_docroot => '/etc/puppet/docroot', +# apache_serveradmin => 'wibble', +# puppet_conf => '/etc/puppet/puppet.conf', +# puppet_ssldir => '/var/lib/puppet/ssl', +# certname => 'puppet.example.com', +# conf_dir => '/etc/puppet', # } # class puppet::passenger( $generate_ssl_certs = true, - $puppet_passenger_port, + $puppet_proxy_port, $puppet_passenger_tempdir = false, $puppet_docroot, $apache_serveradmin, @@ -110,7 +110,7 @@ } apache::vhost { "puppet-${certname}": - port => $puppet_passenger_port, + port => $puppet_proxy_port, priority => '40', docroot => $puppet_docroot, serveradmin => $apache_serveradmin, @@ -181,3 +181,4 @@ require => File[$puppet_conf], } } + diff --git a/manifests/unicorn.pp b/manifests/unicorn.pp new file mode 100644 index 000000000..d12797d51 --- /dev/null +++ b/manifests/unicorn.pp @@ -0,0 +1,154 @@ +# Class: puppet::unicorn +# +# Parameters: +# ['certname'] - +# ['puppet_conf'] - +# ['puppet_ssldir'] - +# ['dns_alt_names'] - +# ['listen_address'] - IP for binding the webserver, defaults to * +# ['puppet_proxy_port'] - The port for the virtual host +# ['disable_ssl'] - Disables SSL on the webserver. usefull if you use this master behind a loadbalancer. currently only supported by nginx, defaults to undef +# ['backup_upstream'] - specify several puppet master as fallback. currently only supported by nginx +# ['unicorn_package'] - package name of a unicorn rpm. if provided we install it, otherwise we built it via gem/gcc +# ['unicorn_path'] - custom path to the unicorn binary +# ['disable_master'] - this disables the normal master, the server will only act as a CA +# ['upstream'] - define additional masters reachable via tcp as an array +# +# Actions: +# - Configures nginx and unicorn for puppet master use. Tested only on CentOS 7 +# - server can act as a simple LB with multiple puppet master backends and backups +# +# Requires: +# - nginx +# +# Sample Usage: +# class {'puppet::unicorn': +# listen_address => '10.250.250.1', +# puppet_proxy_port => '8140', +# } +# +# written by Tim 'bastelfreak' Meusel +# with big help from Rob 'rnelson0' Nelson, the_scourge, Ben Fairless and Gavin Rogers + +class puppet::unicorn ( + $certname, + $puppet_conf, + $puppet_ssldir, + $dns_alt_names, + $listen_address, + $puppet_proxy_port, + $disable_ssl, + $backup_upstream, + $unicorn_package, + $unicorn_path, + $disable_master, + $upstream, + $backend_process_number, + $unicorn_ensure, + $rack_ensure, +) inherits puppet::params { + include nginx + # if this is provided we install the package from the repo, otherwise we build unicorn from scratch + if $unicorn_package { + package {$unicorn_package: + ensure => latest, + } + } else { + # install unicorn + unless defined(Package[$::puppet::params::ruby_dev]) { + package {$::puppet::params::ruby_dev: + ensure => latest, + } + } + unless defined(Package['gcc']) { + package {'gcc': + ensure => latest, + } + } + package {'unicorn': + ensure => $unicorn_ensure, + provider => gem, + require => Package[$::puppet::params::ruby_dev, 'gcc'], + } + package {'rack': + ensure => $rack_ensure, + provider => gem, + require => Package[$::puppet::params::ruby_dev, 'gcc'], + } + } + file {'unicorn-conf': + path => '/etc/puppet/unicorn.conf', + content => template('puppet/unicorn.conf'), + } -> + file {'copy-config': + path => '/etc/puppet/config.ru', + source => '/usr/share/puppet/ext/rack/config.ru', + } -> + + file {'unicorn-service': + path => '/usr/lib/systemd/system/unicorn-puppetmaster.service', + content => template('puppet/unicorn-puppetmaster.service'), + notify => Exec['systemd-reload'], + } -> + exec{'systemd-reload': + command => '/usr/bin/systemctl daemon-reload', + refreshonly => true, + notify => Service['unicorn-puppetmaster'], + } + unless defined(Service['unicorn-puppetmaster']) { + service{'unicorn-puppetmaster': + ensure => running, + enable => true, + } + } + # update SELinux + if $::selinux_config_mode == 'enforcing' { + class { '::selinux': + mode => 'enforcing', + } + selinux::module{ 'nginx': + ensure => present, + content => template('puppet/unicorn_selinux_template'), + } + } + + # first we need to generate the cert + # Clean the installed certs out first + $crt_clean_cmd = "puppet cert clean ${certname}" + # I would have preferred to use puppet cert generate, but it does not + # return the correct exit code on some versions of puppet + $crt_gen_cmd = "puppet certificate --ca-location=local --dns_alt_names=${dns_alt_names} generate ${certname}" + # I am using the sign command here b/c AFAICT, the sign command for certificate + # does not work + $crt_sign_cmd = "puppet cert sign --allow-dns-alt-names ${certname}" + # find is required to move the cert into the certs directory which is + # where it needs to be for puppetdb to find it + $cert_find_cmd = "puppet certificate --ca-location=local find ${certname}" + + exec { 'Certificate_Check': + command => "${crt_clean_cmd} ; ${crt_gen_cmd} && ${crt_sign_cmd} && ${cert_find_cmd}", + unless => "/bin/ls ${puppet_ssldir}/certs/${certname}.pem", + path => '/usr/bin:/usr/local/bin', + logoutput => on_failure, + require => File[$puppet_conf] + } + + # hacky vhost + file {'puppetmaster-vhost': + path => '/etc/nginx/sites-available/puppetmaster', + content => template('puppet/puppetmaster'), + } -> + file {'enable-puppetmaster-vhost': + ensure => link, + path => '/etc/nginx/sites-enabled/puppetmaster', + target => '/etc/nginx/sites-available/puppetmaster', + notify => Service['nginx'], + } + unless defined(Service['nginx']) { + service{'nginx': + ensure => running, + enable => true, + require => File['enable-puppetmaster-vhost'], + } + } +} diff --git a/spec/classes/puppet_passenger_spec.rb b/spec/classes/puppet_passenger_spec.rb index 34c5aff15..639058170 100644 --- a/spec/classes/puppet_passenger_spec.rb +++ b/spec/classes/puppet_passenger_spec.rb @@ -3,7 +3,7 @@ describe 'puppet::passenger', :type => :class do let (:params) do { - :puppet_passenger_port => '8140', + :puppet_proxy_port => '8140', :puppet_docroot => '/etc/puppet/rack/public/', :apache_serveradmin => 'root', :puppet_conf => '/etc/puppet/puppet.conf', @@ -107,7 +107,7 @@ end let (:params) do { - :puppet_passenger_port => '8140', + :puppet_proxy_port => '8140', :puppet_docroot => '/etc/puppet/rack/public/', :apache_serveradmin => 'root', :puppet_conf => '/etc/puppet/puppet.conf', diff --git a/spec/classes/puppet_repo_puppetlabs_spec.rb b/spec/classes/puppet_repo_puppetlabs_spec.rb index e182b27bf..616c45527 100644 --- a/spec/classes/puppet_repo_puppetlabs_spec.rb +++ b/spec/classes/puppet_repo_puppetlabs_spec.rb @@ -10,6 +10,11 @@ :lsbdistid => 'Ubuntu', } end + let :params do + { + :mirror => 'http://apt.puppetlabs.com', + } + end it 'should contain puppetlabs apt repos' do should contain_apt__source('puppetlabs').with( :repos => 'main', @@ -31,6 +36,12 @@ :operatingsystem => 'Redhat' } end + let :params do + { + :mirror => 'http://yum.puppetlabs.com', + :priority => '1', + } + end it 'should add the redhat specific repoos' do should contain_yumrepo('puppetlabs').with( :baseurl => 'http://yum.puppetlabs.com/el/$releasever/products/$basearch' diff --git a/templates/puppetmaster b/templates/puppetmaster new file mode 100644 index 000000000..464cc1de3 --- /dev/null +++ b/templates/puppetmaster @@ -0,0 +1,104 @@ +# define the new unicorn backend +upstream puppetmaster_unicorn { + <% unless @disable_master -%> + server unix:/var/run/puppet/puppetmaster_unicorn.sock fail_timeout=5; + <% end -%> + <% @upstream.each do |server| -%> + server <%= server %>; + <% end -%> + <% @backup_upstream.each do |server| -%> + server <%= server %> backup; + <% end -%> +} + +# define our CA server +upstream puppetca { + server unix:/var/run/puppet/puppetmaster_unicorn.sock; +} + +# define a custom log level for cache stats +log_format custom-cache '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" nocache:$no_cache'; + +# define our cache +proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=microcache:5m max_size=1000m; + +# define our proxy +server { + <% unless @disable_ssl -%> + ssl on; + listen <%= @listen_address %>:<%= @puppet_proxy_port %> ssl; + ssl_certificate /var/lib/puppet/ssl/certs/<%= @fqdn %>.pem; + ssl_certificate_key /var/lib/puppet/ssl/private_keys/<%= @fqdn %>.pem; + ssl_verify_client optional; + ssl_client_certificate /var/lib/puppet/ssl/ca/ca_crt.pem; + ssl_protocols TLSv1.2; + ssl_ciphers '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:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA'; + ssl_session_cache shared:SSL:100m; + ssl_session_tickets on; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Client-Verify $ssl_client_verify; + proxy_set_header X-Client-DN $ssl_client_s_dn; + proxy_set_header X-SSL-Subject $ssl_client_s_dn; + proxy_set_header X-SSL-Issuer $ssl_client_i_dn; + <% else -%> + listen <%= @listen_address %>:<%= @puppet_proxy_port %>; + <% end -%> + root /var/empty; + location / { + proxy_pass http://puppetmaster_unicorn; + proxy_redirect off; + # Setup var defaults + set $no_cache ""; + + # If non GET/HEAD, don't cache & mark user as uncacheable for 1 second via cookie + if ($request_method !~ ^(GET|HEAD)$) { + set $no_cache "1"; + } + + # Drop no cache cookie if need be + # (for some reason, add_header fails if included in prior if-block) + if ($no_cache = "1") { + add_header Set-Cookie "_mcnc=1; Max-Age=2; Path=/"; + add_header X-Microcachable "0"; + } + + # Bypass cache if no-cache cookie is set + if ($http_cookie ~* "_mcnc") { + set $no_cache "1"; + } + + # Bypass cache if flag is set + proxy_no_cache $no_cache; + proxy_cache_bypass $no_cache; + # Set cache zone + proxy_cache microcache; + + # Set cache key to include identifying components + proxy_cache_key $scheme$host$request_method$request_uri; + + # Only cache valid HTTP 200 responses for 1 second + proxy_cache_valid 200 1s; + + # Serve from cache if currently refreshing + proxy_cache_use_stale updating; + + # Set files larger than 1M to stream rather than cache + proxy_max_temp_file_size 1M; + + # activate our logging + access_log /var/log/nginx/puppetmaster-microcache.log custom-cache; + } + location ~ ^/([^/]+/certificate.*)$ { + proxy_pass http://puppetca; + proxy_redirect off; + } + access_log /var/log/nginx/puppetmaster-access.log; + error_log /var/log/nginx/puppetmaster-error.log; +} + + diff --git a/templates/unicorn-puppetmaster.service b/templates/unicorn-puppetmaster.service new file mode 100644 index 000000000..f510fa246 --- /dev/null +++ b/templates/unicorn-puppetmaster.service @@ -0,0 +1,14 @@ +[Unit] +Description=Puppet master served by Unicorn + +[Service] +ExecStart=<%= @unicorn_path %> -c /etc/puppet/unicorn.conf +ExecReload=/usr/bin/kill -s HUP $MAINPID +PrivateTmp=yes +# this would be cool, but then the puppetmaster can't reach the puppetdb +#PrivateNetwork=yes +User=puppet +Group=puppet + +[Install] +WantedBy=multi-user.target diff --git a/templates/unicorn.conf b/templates/unicorn.conf new file mode 100644 index 000000000..3b2cabbe0 --- /dev/null +++ b/templates/unicorn.conf @@ -0,0 +1,26 @@ +worker_processes <%= @backend_process_number %> +working_directory "/etc/puppet" +listen '/var/run/puppet/puppetmaster_unicorn.sock', :backlog => 512 +timeout 180 +pid "/var/run/puppet/puppetmaster_unicorn.pid" + +# prevent caching of puppetmaster. sucks for auto deployment +preload_app false +if GC.respond_to?(:copy_on_write_friendly=) + GC.copy_on_write_friendly = true +end + +before_fork do |server, worker| + old_pid = "#{server.config[:pid]}.oldbin" + if File.exists?(old_pid) && server.pid != old_pid + begin + Process.kill("QUIT", File.read(old_pid).to_i) + rescue Errno::ENOENT, Errno::ESRCH + # someone else did our job for us + end + end +end + +# disable default logging +stdout_path "/dev/null" +stderr_path "/dev/null" diff --git a/templates/unicorn_selinux_template b/templates/unicorn_selinux_template new file mode 100644 index 000000000..22e05ecaa --- /dev/null +++ b/templates/unicorn_selinux_template @@ -0,0 +1,31 @@ +module nginx 1.2; + require { + type httpd_t; + type puppet_var_run_t; + type init_t; + type var_t; + class process setrlimit; + class dir setattr; + class file { read getattr unlink }; + class sock_file write; + class dir search; + class unix_stream_socket connectto; + <% if @backup_upstream %> + type puppet_port_t; + type transproxy_port_t; + class tcp_socket name_connect; + class tcp_socket name_bind; + <% end %> +} + +#============= httpd_t ============== +allow httpd_t puppet_var_run_t:sock_file write; +allow httpd_t self:process setrlimit; +allow httpd_t var_t:dir setattr; +allow httpd_t var_t:file { read getattr unlink }; +allow httpd_t puppet_var_run_t:dir search; +allow httpd_t init_t:unix_stream_socket connectto; +<% if @backup_upstream %> +allow httpd_t transproxy_port_t:tcp_socket name_bind; +allow httpd_t puppet_port_t:tcp_socket name_connect; +<% end %> diff --git a/tests/dbterminus.pp b/tests/dbterminus.pp index 0ff14aa66..4bf7c9f55 100644 --- a/tests/dbterminus.pp +++ b/tests/dbterminus.pp @@ -1,6 +1,6 @@ class {'puppet::dbterminus': puppet_confdir => '/etc/puppet/puppet.conf', puppet_service => Service['httpd'], - dbport => '8081', - dbserver => 'test.example.com' + dbport => '8081', + dbserver => 'test.example.com' } diff --git a/tests/passenger.pp b/tests/passenger.pp index 4afd23748..e1ccefc4f 100644 --- a/tests/passenger.pp +++ b/tests/passenger.pp @@ -1,6 +1,6 @@ class{ 'puppet::passenger': - puppet_passenger_port => '8140', - puppet_docroot => '/etc/puppet/doc', + puppet_proxy_port => '8140', + puppet_docroot => '/etc/puppet/doc', apache_serveradmin => 'me@example.com', puppet_site => 'master.example.com', puppet_conf => '/etc/puppet/puppet.conf', diff --git a/tests/storedconfigs.pp b/tests/storedconfigs.pp index d17e1824a..b32ecb614 100644 --- a/tests/storedconfigs.pp +++ b/tests/storedconfigs.pp @@ -1,6 +1,6 @@ class {'puppet::storeconfigs': - dbserver => 'test.example.com', - dbport => '8081', - puppet_service => Service['httpd'], + dbserver => 'test.example.com', + dbport => '8081', + puppet_service => Service['httpd'], puppetdb_version => 'present' }