diff --git a/Puppetfile b/Puppetfile index 91ffa9c9f..162a5f2a2 100644 --- a/Puppetfile +++ b/Puppetfile @@ -8,7 +8,12 @@ mod 'puppet-nginx', '0.5.0' mod 'puppet-staging', '2.0.1' mod 'puppetlabs-apache', '1.11.0' mod 'puppetlabs-apt', '2.3.0' -mod 'puppetlabs-concat', '2.2.0' + +# Upgrade to 2.2.0 when +# https://tickets.puppetlabs.com/browse/MODULES-3310 is fixed or +# all agents are on Puppet 4 +mod 'puppetlabs-concat', '1.2.5' mod 'puppetlabs-rabbitmq', '5.6.0' mod 'puppetlabs-stdlib', '4.14.0' +mod 'puppetlabs-tagmail', '2.1.1' mod 'puppetlabs-vcsrepo', '1.5.0' diff --git a/environment.conf b/environment.conf index 3ef2b30fd..7ecda13c7 100644 --- a/environment.conf +++ b/environment.conf @@ -1,2 +1 @@ modulepath = modules:vendor:$basemodulepath -parser = future diff --git a/hiera.yaml b/hiera.yaml index 7673fecc6..96cea79d9 100644 --- a/hiera.yaml +++ b/hiera.yaml @@ -10,7 +10,7 @@ - common :yaml: - :datadir: /opt/puppet/env/%{environment}/hieradata + :datadir: /etc/puppetlabs/code/environments/%{environment}/hieradata :puppet: :datasource: data diff --git a/hieradata/common.yaml b/hieradata/common.yaml index befdc4497..0d880968d 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -17,7 +17,7 @@ classes: - ocf::utils staff_only: true - +puppet_agent: false # Mesos/Marathon configuration # diff --git a/hieradata/nodes/dev-lightning.yaml b/hieradata/nodes/dev-lightning.yaml index 51362a2e4..cd0a34e9b 100644 --- a/hieradata/nodes/dev-lightning.yaml +++ b/hieradata/nodes/dev-lightning.yaml @@ -1,2 +1,4 @@ classes: - ocf_puppet + +puppet_agent: true diff --git a/modules/ocf/manifests/puppet.pp b/modules/ocf/manifests/puppet.pp index e1b75882c..f03f4e34f 100644 --- a/modules/ocf/manifests/puppet.pp +++ b/modules/ocf/manifests/puppet.pp @@ -1,59 +1,91 @@ class ocf::puppet($stage = 'first') { - package { ['facter', 'puppet']: } - - # configure puppet agent - # set environment to match server and disable cached catalog on failure - augeas { '/etc/puppet/puppet.conf': - context => '/files/etc/puppet/puppet.conf', - changes => [ - # These changes can change the puppetmaster config, which is - # defined separately in the ocf_puppet module, causing the - # puppet agent on the puppetmaster to restart twice. Make sure - # the changes made here are also made in that module. - "set agent/environment ${::environment}", - 'set agent/usecacheonfailure false', - 'set main/pluginsync true', - 'set main/stringify_facts false', - 'set main/rundir /run/puppet', - - # future parser breaks too many 3rd-party modules - 'rm main/parser', - - # templatedir is deprecated in 3.8+ and we don't use it - 'rm main/templatedir', - ], - require => Package['augeas-tools', 'libaugeas-ruby', 'puppet'], - notify => Service['puppet'], - } + if hiera('puppet_agent') { + package { 'puppet-agent':; } + + augeas { '/etc/puppetlabs/puppet/puppet.conf': + context => '/files/etc/puppetlabs/puppet/puppet.conf', + changes => [ + # These changes can change the puppetmaster config, which is + # defined separately in the ocf_puppet module, causing the + # puppet agent on the puppetmaster to restart twice. Make sure + # the changes made here are also made in that module. + "set agent/environment ${::environment}", + 'set agent/usecacheonfailure false', + + # TODO: Remove this after the puppetmaster upgrade is complete + 'set main/server dev-puppet', + + # Remove a bunch of old settings that are no longer needed + 'rm main/logdir', + 'rm main/vardir', + 'rm main/ssldir', + 'rm main/rundir', + 'rm main/templatedir', + 'rm main/factpath', + 'rm main/pluginsync', + 'rm main/stringify_facts', + 'rm main/prerun_command', + 'rm main/postrun_command', + 'rm agent/certname', + 'rm master/ssl_client_header', + 'rm master/ssl_client_verify_header', + ], + require => Package['puppet-agent'], + } + } else { + package { ['facter', 'puppet']: } - service { 'puppet': - require => Package['puppet'], + # configure puppet agent + # set environment to match server and disable cached catalog on failure + augeas { '/etc/puppet/puppet.conf': + context => '/files/etc/puppet/puppet.conf', + changes => [ + # These changes can change the puppetmaster config, which is + # defined separately in the ocf_puppet module, causing the + # puppet agent on the puppetmaster to restart twice. Make sure + # the changes made here are also made in that module. + "set agent/environment ${::environment}", + 'set agent/usecacheonfailure false', + 'set main/pluginsync true', + 'set main/stringify_facts false', + 'set main/rundir /run/puppet', + + # future parser breaks too many 3rd-party modules + 'rm main/parser', + + # templatedir is deprecated in 3.8+ and we don't use it + 'rm main/templatedir', + ], + require => Package['augeas-tools', 'libaugeas-ruby', 'puppet'], + notify => Service['puppet'], + } + + service { 'puppet': + require => Package['puppet'], + } } # create share directories file { '/opt/share': - ensure => directory, - ; + ensure => directory; + '/opt/share/puppet': ensure => directory, recurse => true, purge => true, force => true, - backup => false, - ; + backup => false; } # install augeas - package { [ 'augeas-tools', 'libaugeas-ruby', ]: } + package { [ 'augeas-tools', 'libaugeas-ruby']:; } # install custom scripts file { # trigger a puppet run by the agent '/usr/local/sbin/puppet-trigger': mode => '0755', - source => 'puppet:///modules/ocf/puppet-trigger', - require => Package['puppet'], - ; + source => 'puppet:///modules/ocf/puppet-trigger'; } } diff --git a/modules/ocf_backups/files/rsnapshot.conf b/modules/ocf_backups/files/rsnapshot.conf index 05efe8d1e..48b50b727 100644 --- a/modules/ocf_backups/files/rsnapshot.conf +++ b/modules/ocf_backups/files/rsnapshot.conf @@ -58,7 +58,8 @@ backup ocfbackups@ldap:/etc/ldap/ servers/ldap/ backup ocfbackups@ldap:/var/lib/ldap/ servers/ldap/ backup ocfbackups@ldap:/var/backups/ldap/ servers/ldap/ -backup ocfbackups@puppet:/var/lib/puppet/ servers/puppet/ +backup ocfbackups@puppet:/etc/puppetlabs/puppet/ servers/puppet/ +backup ocfbackups@puppet:/opt/puppetlabs/ servers/puppet/ backup ocfbackups@puppet:/opt/puppet/ servers/puppet/ backup ocfbackups@stats:/opt/stats/var/ servers/stats/ diff --git a/modules/ocf_puppet/files/ldap-enc b/modules/ocf_puppet/files/ldap-enc new file mode 100755 index 000000000..246cec735 --- /dev/null +++ b/modules/ocf_puppet/files/ldap-enc @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +"""LDAP External Node Classifier for Puppet + +Since Puppet Server uses JRuby, we can't use the same ruby-ldap package that +we have used with Puppet's LDAP node classifier in the past and instead must +either patch jruby-ldap to work with Puppet (fragile for the future and tough +if anything moves locations), or create an ENC for Puppet that will classify +nodes like the built-in LDAP classifier. + +This is that classifier! It takes in node FQDNs, and looks them up in LDAP +to get variables and classes to give to Puppet. +""" + +import argparse +import sys +import yaml + +from ocflib.infra.hosts import hosts_by_filter +from ocflib.infra.hosts import hostname_from_domain + +def main(): + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument('hostname', help='Hostname of LDAP node to classify.') + args = parser.parse_args() + + hostname = hostname_from_domain(args.hostname) + search = hosts_by_filter('(&(objectclass=puppetClient)(cn={}))'.format(hostname)) + + if len(search) == 1: + host = search[0] + else: + # Could not find a unique node to classify, exit + sys.exit(1) + + output = {'parameters': {}} + + for key, values in host.items(): + # The environment is a special parameter that needs some conversion to + # work correctly. + if key == 'environment': + output['environment'] = values[0] + + # Remove the value from its list only if it is a singular value + if len(values) == 1: + output['parameters'][key] = values[0] + else: + output['parameters'][key] = values + + print(yaml.dump(output, default_flow_style=False)) + +if __name__ == '__main__': + main() diff --git a/modules/ocf_puppet/files/tagmail.conf b/modules/ocf_puppet/files/tagmail.conf new file mode 100644 index 000000000..f1767867c --- /dev/null +++ b/modules/ocf_puppet/files/tagmail.conf @@ -0,0 +1,7 @@ +[transport] +reportfrom = puppet +sendmail = /usr/sbin/sendmail + +[tagmap] +warning, err, alert, emerg, crit: puppet + diff --git a/modules/ocf_puppet/manifests/init.pp b/modules/ocf_puppet/manifests/init.pp index 99b1f6b02..7b85e1d30 100644 --- a/modules/ocf_puppet/manifests/init.pp +++ b/modules/ocf_puppet/manifests/init.pp @@ -5,6 +5,6 @@ include ocf_puppet::puppetmaster file { '/etc/sudoers.d/ocfdeploy-puppet': - content => "ocfdeploy ALL=NOPASSWD: /opt/puppet/scripts/update-prod\n"; + content => "ocfdeploy ALL=NOPASSWD: /opt/puppetlabs/scripts/update-prod\n"; } } diff --git a/modules/ocf_puppet/manifests/puppetmaster.pp b/modules/ocf_puppet/manifests/puppetmaster.pp index e29f25bc6..719992790 100644 --- a/modules/ocf_puppet/manifests/puppetmaster.pp +++ b/modules/ocf_puppet/manifests/puppetmaster.pp @@ -1,52 +1,67 @@ class ocf_puppet::puppetmaster { package { - ['puppetmaster-passenger', 'puppet-lint']:; + ['puppetserver', 'puppet-lint']:; } - class { '::apache': - default_vhost => false; + service { 'puppetserver': + require => Package['puppetserver'], } - apache::vhost { 'puppetmaster': - docroot => '/usr/share/puppet/rack/puppetmasterd/public/', - port => 8140, - - ssl => true, - ssl_key => '/var/lib/puppet/ssl/private_keys/puppet.pem', - ssl_cert => '/var/lib/puppet/ssl/certs/puppet.pem', - ssl_chain => '/var/lib/puppet/ssl/certs/ca.pem', - ssl_ca => '/var/lib/puppet/ssl/certs/ca.pem', - ssl_crl => '/var/lib/puppet/ssl/ca/ca_crl.pem', - ssl_verify_client => 'optional', - ssl_verify_depth => 1, - ssl_options => ['+StdEnvVars', '+ExportCertData'], - - rack_base_uris => ['/']; + # Set correct memory limits on puppetserver so that it doesn't run out + augeas { '/etc/default/puppetserver': + context => '/files/etc/default/puppetserver', + changes => [ + "set JAVA_ARGS '\"-Xms512m -Xmx512m -XX:MaxPermSize=256m\"'", + ], + require => Package['puppetserver'], + notify => Service['puppetserver'], } $docker_private_hosts = union(keys(hiera('mesos_masters')), hiera('mesos_slaves')) file { - '/etc/puppet/fileserver.conf': - content => template('ocf_puppet/fileserver.conf.erb'); + '/etc/puppetlabs/puppet/fileserver.conf': + content => template('ocf_puppet/fileserver.conf.erb'), + require => Package['puppetserver']; - '/etc/puppet/puppet.conf': - content => template('ocf_puppet/puppet.conf.erb'); + '/etc/puppetlabs/puppet/tagmail.conf': + source => 'puppet:///modules/ocf_puppet/tagmail.conf', + require => Package['puppetserver']; - '/etc/puppet/tagmail.conf': - content => "warning, err, alert, emerg, crit: puppet\n"; + '/opt/share/puppet/ldap-enc': + mode => '0755', + source => 'puppet:///modules/ocf_puppet/ldap-enc', + require => File['/opt/share/puppet']; - ['/opt/puppet', '/opt/puppet/env', '/opt/puppet/scripts', '/opt/puppet/shares', '/opt/puppet/shares/contrib']: - ensure => directory; + '/etc/puppetlabs/puppet/puppet.conf': + content => template('ocf_puppet/puppet.conf.erb'), + require => Package['puppet-agent']; - '/opt/puppet/shares/private': + ['/opt/puppetlabs/scripts', '/opt/puppetlabs/shares', '/opt/puppetlabs/shares/contrib']: + ensure => directory, + require => Package['puppetserver']; + + '/opt/puppetlabs/shares/private': mode => '0400', owner => puppet, group => puppet, - recurse => true; + recurse => true, + require => File['/opt/puppetlabs/shares']; - '/opt/puppet/scripts/update-prod': + '/opt/puppetlabs/scripts/update-prod': source => 'puppet:///modules/ocf_puppet/update-prod', mode => '0755'; + + # TODO: Remove old puppet directories after the upgrade is fully done + # (for now they are just links to the new locations) + '/opt/puppet/env': + ensure => symlink, + target => '/etc/puppetlabs/code/environments', + require => Package['puppetserver']; + + '/opt/puppet/shares': + ensure => symlink, + target => '/opt/puppetlabs/shares', + require => Package['puppetserver']; } } diff --git a/modules/ocf_puppet/templates/puppet.conf.erb b/modules/ocf_puppet/templates/puppet.conf.erb index 8b13e0a41..9f1835156 100644 --- a/modules/ocf_puppet/templates/puppet.conf.erb +++ b/modules/ocf_puppet/templates/puppet.conf.erb @@ -7,43 +7,27 @@ [main] -environmentpath = /opt/puppet/env -hiera_config = /opt/puppet/env/<%= @environment %>/hiera.yaml +hiera_config = <%= @puppet_environmentpath %>/<%= @environment %>/hiera.yaml -# debian paths -logdir = /var/log/puppet -vardir = /var/lib/puppet -ssldir = /var/lib/puppet/ssl -rundir = /run/puppet -factpath = $vardir/lib/facter - -# plugin sync (used by concat) -pluginsync = true - -stringify_facts = false +# TODO: Remove this after ths upgrade +server = dev-puppet [agent] -certname = <%= @clientcert %> environment = <%= @environment %> usecacheonfailure = false [master] -# puppetmaster ssl certificate name -certname = puppet - -# ssl support for apache passenger -ssl_client_header = SSL_CLIENT_S_DN -ssl_client_verify_header = SSL_CLIENT_VERIFY +vardir = /opt/puppetlabs/server/data/puppetserver +logdir = /var/log/puppetlabs/puppetserver +rundir = /var/run/puppetlabs/puppetserver +pidfile = /var/run/puppetlabs/puppetserver/puppetserver.pid +codedir = /etc/puppetlabs/code -# use external node classifer -node_terminus = ldap -ldapserver = ldap.ocf.berkeley.edu -ldapport = 636 -ldapssl = true -ldapbase = ou=Hosts,dc=OCF,dc=Berkeley,dc=EDU +# Use custom LDAP external node classifer (ENC) +node_terminus = exec +external_nodes = /opt/share/puppet/ldap-enc -# log and mail reports from clients +# log and mail reports from failed clients reports = log, tagmail -reportfrom = puppet