diff --git a/manifests/params.pp b/manifests/params.pp index 69c1873..ec7a0e4 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -85,42 +85,60 @@ } $default_value = { - agent_package => 'puppet', - agent_service => 'puppet', - agent_service_conf => '/etc/default/puppet', - default_method => 'cron', - master_package => 'puppetmaster', - master_service => 'puppetmaster', - puppet_cmd => '/usr/bin/puppet', - puppet_conf => '/etc/puppet/puppet.conf', - puppet_confdir => '/etc/puppet', - puppet_logdir => '/var/log/puppet', - puppet_rundir => '/var/run/puppet', - puppet_ssldir => '/var/lib/puppet/ssl', - puppet_user => 'puppet', - puppet_group => 'puppet', - puppet_vardir => '/var/lib/puppet', - report_dir => '/usr/lib/ruby/vendor_ruby/puppet/reports', + agent_package => 'puppet', + agent_service => 'puppet', + agent_service_conf => '/etc/default/puppet', + default_method => 'cron', + master_package => 'puppetmaster', + master_service => 'puppetmaster', + puppet_cmd => '/usr/bin/puppet', + puppet_conf => '/etc/puppet/puppet.conf', + puppet_confdir => '/etc/puppet', + puppet_group => 'puppet', + puppet_logdir => '/var/log/puppet', + puppet_rundir => '/var/run/puppet', + puppet_ssldir => '/var/lib/puppet/ssl', + puppet_user => 'puppet', + puppet_vardir => '/var/lib/puppet', + puppetserver_bootstrap_conf => '/etc/puppetserver/bootstrap.cfg', + puppetserver_config_dir => '/etc/puppetserver/conf.d', + puppetserver_install_dir => '/usr/share/puppetserver', + puppetserver_logback_conf => '/etc/puppetserver/logback.xml', + puppetserver_java => '/usr/bin/java', + puppetserver_gem_home => '/var/lib/puppet/jruby-gems', + report_dir => '/usr/lib/ruby/vendor_ruby/puppet/reports', + server_package => 'puppetserver', + server_service => 'puppetserver', + server_service_conf => '/etc/default/puppetserver', } $merged_values = merge($default_value, $os_specific) - $agent_package = $merged_values[agent_package] - $agent_service = $merged_values[agent_service] - $agent_service_conf = $merged_values[agent_service_conf] - $agent_use = $merged_values[agent_use] - $default_method = $merged_values[default_method] - $master_package = $merged_values[master_package] - $master_service = $merged_values[master_service] - $master_use = $merged_values[master_use] - $puppet_cmd = $merged_values[puppet_cmd] - $puppet_conf = $merged_values[puppet_conf] - $puppet_confdir = $merged_values[puppet_confdir] - $puppet_group = $merged_values[puppet_group] - $puppet_logdir = $merged_values[puppet_logdir] - $puppet_rundir = $merged_values[puppet_rundir] - $puppet_ssldir = $merged_values[puppet_ssldir] - $puppet_user = $merged_values[puppet_user] - $puppet_vardir = $merged_values[puppet_vardir] + $agent_package = $merged_values[agent_package] + $agent_service = $merged_values[agent_service] + $agent_service_conf = $merged_values[agent_service_conf] + $agent_use = $merged_values[agent_use] + $default_method = $merged_values[default_method] + $master_package = $merged_values[master_package] + $master_service = $merged_values[master_service] + $master_use = $merged_values[master_use] + $puppet_cmd = $merged_values[puppet_cmd] + $puppet_conf = $merged_values[puppet_conf] + $puppet_confdir = $merged_values[puppet_confdir] + $puppet_group = $merged_values[puppet_group] + $puppet_logdir = $merged_values[puppet_logdir] + $puppet_rundir = $merged_values[puppet_rundir] + $puppet_ssldir = $merged_values[puppet_ssldir] + $puppet_user = $merged_values[puppet_user] + $puppet_vardir = $merged_values[puppet_vardir] + $puppetserver_bootstrap_conf = $merged_values[puppetserver_bootstrap_conf] + $server_package = $merged_values[server_package] + $server_service = $merged_values[server_service] + $server_service_conf = $merged_values[server_service_conf] + $puppetserver_install_dir = $merged_values[puppetserver_install_dir] + $puppetserver_config_dir = $merged_values[puppetserver_config_dir] + $puppetserver_java = $merged_values[puppetserver_java] + $puppetserver_logback_conf = $merged_values[puppetserver_logback_conf] + $puppetserver_gem_home = $merged_values[puppetserver_gem_home] } diff --git a/manifests/server.pp b/manifests/server.pp index 820833d..92b9433 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -103,8 +103,11 @@ 'standalone': { include puppet::server::standalone } + 'puppetserver': { + include puppet::server::puppetserver + } default: { - err('Only "passenger", "thin", "unicorn" and "standalone" are valid options for servertype') + err('Only "puppetserver", "passenger", "thin", "unicorn" and "standalone" are valid options for servertype') fail('Servertype "$servertype" not implemented') } } diff --git a/manifests/server/puppetserver.pp b/manifests/server/puppetserver.pp new file mode 100644 index 0000000..c42b7f2 --- /dev/null +++ b/manifests/server/puppetserver.pp @@ -0,0 +1,193 @@ +# puppet::server::puppetserver configures the master using the new JVM puppet server +# Puppet Server is pre-release and not recommended for production use yet +# See https://github.com/puppetlabs/puppet-server/blob/master/documentation/install_from_packages.markdown for basic +# manual install documentation + +# This class should not normally be used directly. + +# TODO: Add support for external SSL termination +# https://github.com/puppetlabs/puppet-server/blob/master/documentation/external_ssl_termination.markdown + +# TODO: Add ability to configure stuff from: +# https://github.com/puppetlabs/puppet-server/blob/master/documentation/configuration.markdown +# - where JRuby will look for gems +# - path to puppet conf dir +# - path to puppet var dir +# - maximum number of JRuby instances to allow; defaults to +2 +# - enable/disable the CA service via trapperkeeper settings +# - configure logging via logback + +# Note that OpenBSD support is blocking on https://tickets.puppetlabs.com/browse/SERVER-14 + +# parameters +# descriptions largely copied from official docs at +# https://github.com/puppetlabs/puppet-server/blob/master/documentation/configuration.markdown +# [*memory*] - (optional) set JVM memory use; 2gb recommended by default +# format is "2gb", "512m", etc. +# [*max_active_instances*] - (optional) maximum number of JRuby instances to allow +# [*logging_config*] - (optional) Path to logback logging configuration file +# http://logback.qos.ch/manual/configuration.html +# [*gem_home*] - (optional) determines where JRuby will look for gems. Also +# used by the `puppetserver gem` command line tool. +# [*master_conf_dir*] - (optional) path to puppet conf dir +# [*master_var_dir*] - (optional) path to puppet var dir +# [*enable_profiler*] - (optional) enable or disable profiling for the Ruby code +# (true|false) +# [*allow_header_cert_info - (optional) Allows the "ssl_client_header" and +# (true|false) "ssl_client_verify_header" options set in +# puppet.conf to work. These headers will be +# ignored unless "allow-header-cert-info" is true + +# puppetserver.conf is in HOCON format, which is a superset of JSON: +# - https://github.com/puppetlabs/puppet-server/blob/master/documentation/configuration.markdown +# - https://github.com/typesafehub/config#using-hocon-the-json-superset +# puppet-puppet will use https://github.com/puppetlabs/puppetlabs-hocon to +# manage hocon settings because that appears to be the approach the puppetserver +# developers have chosen to support + +class puppet::server::puppetserver ( + # aside from memory (defaults to 2g), these are the puppetserver defaults + # Setting them here makes it easier to anticipate behavior + $enabled = true, + $memory_pct = 70, + $memory = undef, + $max_active_instances = $::processorcount + 2, + $logging_config = $puppet::params::puppetserver_logback_conf, + $gem_home = $puppet::params::puppetserver_gem_home, + $master_conf_dir = $puppet::params::puppet_confdir, + $master_var_dir = $puppet::params::puppet_vardir, + $enable_profiler = false, + $allow_header_cert_info = false, + $bootstrap_cfg = $puppet::params::puppetserver_bootstrap_conf, +) { + + include puppet + include puppet::server + + # Calculate JVM memory based on percentage if specified + # Should JVM settings be their own class? + if ($memory_pct != undef) and ($memory != undef) { + fail('memory and memory_pct cannot both be set at the same time') + } + if ($memory_pct != undef) and ($memory == undef) { + $rounded_mem = floor($::memorysize_mb * $memory_pct * 0.01) + $jvm_memory = "${rounded_mem}m" + } + if ($memory_pct == undef) and ($memory != undef) { + $jvm_memory = $memory + } + + $service_ensure = $enabled? { + true => 'running', + default => 'stopped', + } + + Ini_subsetting { + ensure => present, + section => '', + key_val_separator => '=', + quote_char => '"', + path => $puppet::params::server_service_conf, + setting => 'JAVA_ARGS', + notify => Service[$puppet::params::server_service], + } + + ini_subsetting {'puppetserver_xmx_memory': + subsetting => '-Xmx', + value => $jvm_memory, + } + ini_subsetting {'puppetserver_xms_memory': + subsetting => '-Xms', + value => $jvm_memory, + } + + # test for java_major_version fact, and assume we'll use defaults if it's not found + # this allows us to use puppetlabs-java's fact if available without adding a hard + # dependency on it + if $::java_major_version { + $perm = $::java_major_version ? { + 8 => '-XX:MaxMetaspaceSize=', + default => '-XX:MaxPermSize=', + } + } else { + $perm = '-XX:MaxPermSize=' + } + + ini_subsetting {'puppetserver_maxpermsize': + subsetting => $perm, + value => '256m', + } + # JAVA_ARGS="-Xms2776m -Xmx2776m -XX:MaxPermSize=256m" + Ini_setting { + ensure => present, + path => $puppet::params::server_service_conf, + key_val_separator => '=', + section => '', + } + ini_setting { "JAVA_BIN": + setting => 'JAVA_BIN', + value => "\"${puppet::params::puppetserver_java}\"", + } + ini_setting { "USER": + setting => 'USER', + value => "\"${puppet::params::puppet_user}\"", + } + ini_setting { "INSTALL_DIR": + setting => 'INSTALL_DIR', + value => "\"${puppet::params::puppetserver_install_dir}\"", + } + ini_setting { "CONFIG": + setting => 'CONFIG', + value => "\"${puppet::params::puppetserver_config_dir}\"", + } + ini_setting { "BOOTSTRAP_CONFIG": + setting => 'BOOTSTRAP_CONFIG', + value => "\"${puppet::params::puppetserver_bootstrap_conf}\"", + } + ini_setting { "SERVICE_STOP_RETRIES": + setting => 'SERVICE_STOP_RETRIES', + value => '60', + } + + # disable the trapperkeeper-based CA service entirely if this isn't a CA node + $ca_disable_ensure = $puppet::params::ca? { + false => 'present', + default => 'absent', + } + $ca_enable_ensure = $puppet::params::ca? { + false => 'absent', + default => 'present', + } + file_line { 'disable_puppetserver_ca': + ensure => $ca_disable_ensure, + path => $puppet::params::puppetserver_bootstrap_conf, + line => 'puppetlabs.services.ca.certificate-authority-disabled-service/certificate-authority-disabled-service', + require => Package[$puppet::params::server_package], + } + file_line { 'enable_puppetserver_ca': + ensure => $ca_enable_ensure, + path => $puppet::params::puppetserver_bootstrap_conf, + line => 'puppetlabs.services.ca.certificate-authority-service/certificate-authority-service', + require => Package[$puppet::params::server_package], + } + + service { $puppet::params::server_service: + ensure => $service_ensure, + enable => $enabled, + hasstatus => false, + pattern => 'puppet-server-release.jar', # yeah, this is embarassing + require => [Class['puppet::server::config'], + Class['puppet::server::standalone'], + Package[$puppet::params::server_package]], + } + + # stop regular puppet master to avoid conflicting binds on port 8140 + if $enabled == true { + package { $puppet::params::server_package: + ensure => $puppet::server::ensure; + } + class { 'puppet::server::standalone': + enabled => false + } + } +} diff --git a/spec/acceptance/puppetserver_server_spec.rb b/spec/acceptance/puppetserver_server_spec.rb new file mode 100644 index 0000000..12f2c22 --- /dev/null +++ b/spec/acceptance/puppetserver_server_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper_acceptance' + +describe 'server', :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + context 'running on puppetserver', :servertype => 'puppetserver', :webserver => 'puppetserver' do + it 'should run with no errors' do + pp = <<-EOS + class { 'puppet::server': + servertype => 'puppetserver', + ca => true, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + expect(apply_manifest(pp, :catch_failures => true).exit_code).to be_zero + end + + it_behaves_like "basic working puppetmaster" + it_behaves_like "puppetserver-based master" + + end +end diff --git a/spec/classes/server_spec.rb b/spec/classes/server_spec.rb index 4441e32..024262a 100644 --- a/spec/classes/server_spec.rb +++ b/spec/classes/server_spec.rb @@ -25,7 +25,7 @@ let(:facts) { facthash } context "running on #{name}" do - ['standalone','passenger','unicorn','thin'].each do |server_type| + ['standalone','passenger','unicorn','thin','puppetserver'].each do |server_type| context "servertype => #{server_type}" do let(:params) {{ :servertype => server_type, @@ -76,12 +76,20 @@ should contain_service('thin-puppetmaster').with({:ensure => "running"}) should contain_file('/etc/thin.d/puppetmaster.yml') } + when 'puppetserver' + it { + should contain_class('puppet::server::puppetserver') + should contain_service('puppetmaster').with({ :ensure => "stopped" }) + should contain_service('puppetserver').with({:ensure => "running"}) + should contain_package('puppetserver') + } end end end context "manage_package => false" do let(:params) {{ :manage_package => false }} + it { should_not contain_package('puppetserver') } case facthash['osfamily'] when 'RedHat' it { should_not contain_package('puppet-server') } diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 2eeeb1a..6f7bf32 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -99,3 +99,24 @@ it { should_not be_running } end end + +shared_examples_for "puppetserver-based master" do + describe package('puppetserver') do + it { should be_installed } + end + + describe service('nginx') do + it { should_not be_enabled } + it { should_not be_running } + end + + describe service('puppetmaster') do + it { should_not be_enabled } + it { should_not be_running } + end + + describe service('puppetserver') do + it { should be_enabled } + it { should be_running } + end +end diff --git a/tests/puppetserver.pp b/tests/puppetserver.pp new file mode 100644 index 0000000..8fb74a0 --- /dev/null +++ b/tests/puppetserver.pp @@ -0,0 +1,4 @@ +class { 'puppet::server': + servertype => 'puppetserver', + ca => true, +}