From 1a3a13df91e8da7fe131d66d770b705dab879796 Mon Sep 17 00:00:00 2001 From: Tim Meusel Date: Wed, 5 Nov 2014 11:40:42 +0100 Subject: [PATCH 01/10] add nginx/unicorn support for puppet master on centos this is a huge commit which adds support to install nginx on a centos7 node with unicorn backend. You can run an all-in-one node with puppet master/ca on it, or use it to configure a central ssl offloading proxy with puppet ca on it and several master backends and backups. --- README.markdown | 8 ++ files/nginx.selmodule | Bin 0 -> 941 bytes manifests/agent.pp | 3 + manifests/master.pp | 140 +++++++++++------- manifests/params.pp | 23 ++- manifests/passenger.pp | 35 ++--- manifests/unicorn.pp | 150 ++++++++++++++++++++ spec/classes/puppet_passenger_spec.rb | 4 +- spec/classes/puppet_repo_puppetlabs_spec.rb | 11 ++ templates/puppetmaster | 104 ++++++++++++++ templates/unicorn-puppetmaster.service | 14 ++ templates/unicorn.conf | 26 ++++ templates/unicorn_selinux_template | 29 ++++ tests/dbterminus.pp | 4 +- tests/passenger.pp | 4 +- tests/storedconfigs.pp | 6 +- 16 files changed, 484 insertions(+), 77 deletions(-) create mode 100644 files/nginx.selmodule create mode 100644 manifests/unicorn.pp create mode 100644 templates/puppetmaster create mode 100644 templates/unicorn-puppetmaster.service create mode 100644 templates/unicorn.conf create mode 100644 templates/unicorn_selinux_template 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 0000000000000000000000000000000000000000..1374cf27c212a43812a19d92e77e77a9a3fee873 GIT binary patch literal 941 zcmb`FOHRW;5JXK7pB-?6oB+WMdc%&aIKU{x7BNDOHH@PyxB}w5te_uqDV?CKprmru z^k+VDe|)`t9#vHZFP-nczHoiGo8GtGu$j(Q_3+Y6Japxx?A!@XoZVB~ZI0dCUf-C@ zKD0F@Kx-7#Z9a8j`P$6$VyOZSQPJx0xmlEy&0~VexJIvVjB$C$`%sr}Knq&iMpP^TE)Mk+5Q9$~(K%JURpKi};~d#i4n*{!7y zs!mEwFgH*+{YPSg$+#Z!^pk_yOG->I8Q1^vVaq>R?#ugqX0ee>tEO}ka(Je0f3jjP NQ#MXg414q!z5&r}HXHx| literal 0 HcmV?d00001 diff --git a/manifests/agent.pp b/manifests/agent.pp index b9fe1e4dd..6b94f1a9a 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) @@ -454,3 +456,4 @@ } } } + diff --git a/manifests/master.pp b/manifests/master.pp index 894e0ae67..c69d3d4dd 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, @@ -99,7 +109,17 @@ $passenger_max_requests = 10000, $passenger_stat_throttle_rate = 30, $serialization_format = undef, - $serialization_package = 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, + $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 +155,49 @@ ensure => $version, } } + case $webserver { + nginx: { + Anchor['puppet::master::begin'] -> + class {'puppet::unicorn': + certname => $certname, + puppet_conf => $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_path => $unicorn_path, + 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 +211,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 +227,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 +241,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 +250,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 +264,7 @@ Ini_setting { path => $::puppet::params::puppet_conf, require => File[$::puppet::params::puppet_conf], - notify => Service['httpd'], + notify => Service[$webserver], section => 'master', } @@ -332,21 +373,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,18 +382,18 @@ 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'], } } @@ -378,5 +404,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..a7761bdf4 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,15 @@ $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 # Only used when environments == directory $environmentpath = "${confdir}/environments" @@ -90,6 +100,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..d14c417e9 --- /dev/null +++ b/manifests/unicorn.pp @@ -0,0 +1,150 @@ +# 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, +) inherits puppet::params { + class { '::nginx': + worker_processes => $::processorcount, + multi_accept => 'on', + } + # 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', 'rack']: + ensure => latest, + 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..0d46a863f --- /dev/null +++ b/templates/unicorn_selinux_template @@ -0,0 +1,29 @@ +module nginx 1.2; + require { + type httpd_t; + type puppet_var_run_t; + type init_t; + type var_t; + class process setrlimit; + 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' } From cf6b62df2ee84bb51eb7d68f48e2df2d2b6a1d1b Mon Sep 17 00:00:00 2001 From: Tim Meusel Date: Sat, 27 Jun 2015 03:05:47 +0200 Subject: [PATCH 02/10] remove whitespace, fix missing namespace --- manifests/master.pp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manifests/master.pp b/manifests/master.pp index c69d3d4dd..d12c81af6 100644 --- a/manifests/master.pp +++ b/manifests/master.pp @@ -109,7 +109,7 @@ $passenger_max_requests = 10000, $passenger_stat_throttle_rate = 30, $serialization_format = undef, - $serialization_package = undef, + $serialization_package = undef, $webserver = $::puppet::params::default_webserver, $listen_address = $::puppet::params::listen_address, $disable_ssl = $::puppet::params::disable_ssl, @@ -160,7 +160,7 @@ Anchor['puppet::master::begin'] -> class {'puppet::unicorn': certname => $certname, - puppet_conf => $puppet_conf, + puppet_conf => $::puppet::params::puppet_conf, puppet_ssldir => $puppet_ssldir, dns_alt_names => $dns_alt_names, listen_address => $listen_address, From 4fa6dc6ec2447295e019f882a48e0a3b6e51ea17 Mon Sep 17 00:00:00 2001 From: Tim Meusel Date: Thu, 23 Jul 2015 15:57:57 +0200 Subject: [PATCH 03/10] cleanup ols msgpack gems --- manifests/agent.pp | 4 ++++ manifests/master.pp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/manifests/agent.pp b/manifests/agent.pp index 6b94f1a9a..64a86a763 100644 --- a/manifests/agent.pp +++ b/manifests/agent.pp @@ -446,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, } } } diff --git a/manifests/master.pp b/manifests/master.pp index d12c81af6..296a296cc 100644 --- a/manifests/master.pp +++ b/manifests/master.pp @@ -395,6 +395,10 @@ ensure => latest, provider => gem, require => Package[$::puppet::params::ruby_dev, 'gcc'], + } ~> + exec{'cleanup_old_gems': + command => '/usr/bin/gem cleanup msgpack', + refreshonly => true, } } } From 2e543e91d5804c0ab1d171edd92ee3849416fc00 Mon Sep 17 00:00:00 2001 From: Paolo Cadiz Date: Tue, 2 Feb 2016 09:59:41 +0800 Subject: [PATCH 04/10] replaced nginx class declarations with include --- manifests/unicorn.pp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/manifests/unicorn.pp b/manifests/unicorn.pp index d14c417e9..a8c8e2b49 100644 --- a/manifests/unicorn.pp +++ b/manifests/unicorn.pp @@ -45,10 +45,7 @@ $upstream, $backend_process_number, ) inherits puppet::params { - class { '::nginx': - worker_processes => $::processorcount, - multi_accept => 'on', - } + 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: From 90dd1b63cbbaee4f351595e809428dde1957b1c9 Mon Sep 17 00:00:00 2001 From: Paolo Cadiz Date: Tue, 2 Feb 2016 10:07:32 +0800 Subject: [PATCH 05/10] moved configuration to nginx::config --- manifests/unicorn.pp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/manifests/unicorn.pp b/manifests/unicorn.pp index a8c8e2b49..d9639de9b 100644 --- a/manifests/unicorn.pp +++ b/manifests/unicorn.pp @@ -46,6 +46,10 @@ $backend_process_number, ) inherits puppet::params { include nginx + class { 'nginx::config': + worker_processes => $::processorcount, + multi_accept => 'on', + } # if this is provided we install the package from the repo, otherwise we build unicorn from scratch if $unicorn_package { package {$unicorn_package: From de0aa329d31916500616f402ab3b971e7b69de4d Mon Sep 17 00:00:00 2001 From: Paolo Cadiz Date: Tue, 2 Feb 2016 10:08:59 +0800 Subject: [PATCH 06/10] to keep things neat --- manifests/unicorn.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifests/unicorn.pp b/manifests/unicorn.pp index d9639de9b..498bd6046 100644 --- a/manifests/unicorn.pp +++ b/manifests/unicorn.pp @@ -48,7 +48,7 @@ include nginx class { 'nginx::config': worker_processes => $::processorcount, - multi_accept => 'on', + multi_accept => 'on', } # if this is provided we install the package from the repo, otherwise we build unicorn from scratch if $unicorn_package { From 6fe0acb37e2d3b324fc7b5efb4081ab8553a604f Mon Sep 17 00:00:00 2001 From: Paolo Cadiz Date: Tue, 2 Feb 2016 17:40:54 +0800 Subject: [PATCH 07/10] nginx::config first before nginx --- manifests/unicorn.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifests/unicorn.pp b/manifests/unicorn.pp index 498bd6046..ee71628ae 100644 --- a/manifests/unicorn.pp +++ b/manifests/unicorn.pp @@ -45,11 +45,11 @@ $upstream, $backend_process_number, ) inherits puppet::params { - include nginx class { 'nginx::config': worker_processes => $::processorcount, multi_accept => 'on', } + 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: From eef65c7fd0d5b8f440c71f9eb31f1d6ae50dc6a0 Mon Sep 17 00:00:00 2001 From: Paolo Cadiz Date: Tue, 2 Feb 2016 17:52:37 +0800 Subject: [PATCH 08/10] removed nginx::config --- manifests/unicorn.pp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/manifests/unicorn.pp b/manifests/unicorn.pp index ee71628ae..a8c8e2b49 100644 --- a/manifests/unicorn.pp +++ b/manifests/unicorn.pp @@ -45,10 +45,6 @@ $upstream, $backend_process_number, ) inherits puppet::params { - class { 'nginx::config': - worker_processes => $::processorcount, - multi_accept => 'on', - } include nginx # if this is provided we install the package from the repo, otherwise we build unicorn from scratch if $unicorn_package { From 1ee33146044251837c767c0d5d0ba46e4564d904 Mon Sep 17 00:00:00 2001 From: Paolo Cadiz Date: Tue, 9 Feb 2016 17:08:46 +0800 Subject: [PATCH 09/10] added missing classes --- templates/unicorn_selinux_template | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/unicorn_selinux_template b/templates/unicorn_selinux_template index 0d46a863f..22e05ecaa 100644 --- a/templates/unicorn_selinux_template +++ b/templates/unicorn_selinux_template @@ -5,6 +5,8 @@ module nginx 1.2; 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; From c4c274ee6faf43016d41b6c60f3ef346672e97a8 Mon Sep 17 00:00:00 2001 From: Paolo Cadiz Date: Thu, 21 Jul 2016 15:55:21 +0100 Subject: [PATCH 10/10] used paramaters for rack and unicorn versions --- manifests/master.pp | 4 ++++ manifests/params.pp | 2 ++ manifests/unicorn.pp | 11 +++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/manifests/master.pp b/manifests/master.pp index 296a296cc..5e451527b 100644 --- a/manifests/master.pp +++ b/manifests/master.pp @@ -116,6 +116,8 @@ $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, @@ -168,7 +170,9 @@ 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, diff --git a/manifests/params.pp b/manifests/params.pp index a7761bdf4..5b4c78013 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -44,6 +44,8 @@ $disable_master = false $upstream = [] $backend_process_number = $::processorcount + $unicorn_ensure = latest + $rack_ensure = latest # Only used when environments == directory $environmentpath = "${confdir}/environments" diff --git a/manifests/unicorn.pp b/manifests/unicorn.pp index a8c8e2b49..d12797d51 100644 --- a/manifests/unicorn.pp +++ b/manifests/unicorn.pp @@ -44,6 +44,8 @@ $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 @@ -63,8 +65,13 @@ ensure => latest, } } - package {['unicorn', 'rack']: - 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'], }