diff --git a/9781430230571.jpg b/9781430230571.jpg new file mode 100644 index 0000000..545b36e Binary files /dev/null and b/9781430230571.jpg differ diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..af6b72b --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,27 @@ +Freeware License, some rights reserved + +Copyright (c) 2011 James Turnbull and Jeffrey McCune + +Permission is hereby granted, free of charge, to anyone obtaining a copy +of this software and associated documentation files (the "Software"), +to work with the Software within the limits of freeware distribution and fair use. +This includes the rights to use, copy, and modify the Software for personal use. +Users are also allowed and encouraged to submit corrections and modifications +to the Software for the benefit of other users. + +It is not allowed to reuse, modify, or redistribute the Software for +commercial use in any way, or for a user’s educational materials such as books +or blog articles without prior permission from the copyright holder. + +The above copyright notice and this permission notice need to be included +in all copies or substantial portions of the software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/40_puppetmaster_worker_18140.conf b/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/40_puppetmaster_worker_18140.conf new file mode 100644 index 0000000..7f3107b --- /dev/null +++ b/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/40_puppetmaster_worker_18140.conf @@ -0,0 +1,15 @@ +Listen 18140 + + SSLEngine off + # Obtain Authentication Information from Client Request Headers + SetEnvIf X-Client-Verify "(.*)" SSL_CLIENT_VERIFY=$1 + SetEnvIf X-SSL-Client-DN "(.*)" SSL_CLIENT_S_DN=$1 + RackAutoDetect On + DocumentRoot /etc/puppet/rack/puppetmaster_18140/public/ + + Options None + AllowOverride None + Order allow,deny + allow from all + + diff --git a/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/41_puppetmaster_worker_18141.conf b/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/41_puppetmaster_worker_18141.conf new file mode 100644 index 0000000..e0d527c --- /dev/null +++ b/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/41_puppetmaster_worker_18141.conf @@ -0,0 +1,15 @@ +Listen 18141 + + SSLEngine off + # Obtain Authentication Information from Client Request Headers + SetEnvIf X-Client-Verify "(.*)" SSL_CLIENT_VERIFY=$1 + SetEnvIf X-SSL-Client-DN "(.*)" SSL_CLIENT_S_DN=$1 + RackAutoDetect On + DocumentRoot /etc/puppet/rack/puppetmaster_18141/public/ + + Options None + AllowOverride None + Order allow,deny + allow from all + + diff --git a/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/42_puppetmasterca_primary_18142.conf b/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/42_puppetmasterca_primary_18142.conf new file mode 100644 index 0000000..6a3276b --- /dev/null +++ b/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/42_puppetmasterca_primary_18142.conf @@ -0,0 +1,15 @@ +Listen 18142 + + SSLEngine off + # Obtain Authentication Information from Client Request Headers + SetEnvIf X-Client-Verify "(.*)" SSL_CLIENT_VERIFY=$1 + SetEnvIf X-SSL-Client-DN "(.*)" SSL_CLIENT_S_DN=$1 + RackAutoDetect On + DocumentRoot /etc/puppet/rack/puppetmaster_18142/public/ + + Options None + AllowOverride None + Order allow,deny + allow from all + + diff --git a/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/43_puppetmasterca_standby_18143.conf b/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/43_puppetmasterca_standby_18143.conf new file mode 100644 index 0000000..b948f5d --- /dev/null +++ b/Pro Puppet/03_load_balanced_apache_configuration_with_centralized_ca/43_puppetmasterca_standby_18143.conf @@ -0,0 +1,15 @@ +Listen 18143 + + SSLEngine off + # Obtain Authentication Information from Client Request Headers + SetEnvIf X-Client-Verify "(.*)" SSL_CLIENT_VERIFY=$1 + SetEnvIf X-SSL-Client-DN "(.*)" SSL_CLIENT_S_DN=$1 + RackAutoDetect On + DocumentRoot /etc/puppet/rack/puppetmaster_18143/public/ + + Options None + AllowOverride None + Order allow,deny + allow from all + + diff --git a/Pro Puppet/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/30_puppetmaster_frontend.conf b/Pro Puppet/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/30_puppetmaster_frontend.conf new file mode 100644 index 0000000..3fb1766 --- /dev/null +++ b/Pro Puppet/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/30_puppetmaster_frontend.conf @@ -0,0 +1,56 @@ +# Available back-end worker virtual hosts +# NOTE the use of cleartext unencrypted HTTP. + +# vim 30_puppetmaster_frontend_8140.conf + + BalancerMember http://127.0.0.1:18140 + BalancerMember http://127.0.0.1:18141 + + + + # Puppet CA Active Worker + BalancerMember http://127.0.0.1:18142 + # Puppet CA Hot Standby + BalancerMember http://127.0.0.1:18143 status=+H + + +Listen 8140 + + SSLEngine on + # SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA + SSLProtocol -ALL +SSLv3 +TLSv1 + SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP + # Puppet master should generate initial CA certificate. + # ensure certs are located in /var/lib/puppet/ssl + SSLCertificateFile /var/lib/puppet/ssl/certs/puppet.example.com.pem + SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/puppet.example.com.pem + SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem + SSLCACertificateFile /var/lib/puppet/ssl/ca/ca_crt.pem + # CRL checking should be enabled + # disable next line if Apache complains about CRL + SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem + # This is optional to allow CSR request, required if certificates distributed to client during provisioning. + SSLVerifyClient optional + SSLVerifyDepth 1 + SSLOptions +StdEnvVars + # The following client headers record authentication information for down stream workers. + RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e + RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e + RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e + + SetHandler balancer-manager + Order allow,deny + Allow from all + + + # Ordering of ProxyPass directives is important + # Direct all Puppet agent CA requests to a specific set of workers. + ProxyPassMatch ^(/.*?)/(certificate.*?)/(.*)$ balancer://puppetmasterca + ProxyPassReverse ^(/.*?)/(certificate.*?)/(.*)$ balancer://puppetmasterca + # Direct all other Puppet agent requests to the default set of workers. + ProxyPass / balancer://puppetmaster/ + ProxyPassReverse / balancer://puppetmaster/ + ProxyPreserveHost On + + + diff --git a/Pro Puppet/source/chapter02/apache/.DS_Store b/Pro Puppet/source/chapter02/apache/.DS_Store new file mode 100644 index 0000000..7dbe717 Binary files /dev/null and b/Pro Puppet/source/chapter02/apache/.DS_Store differ diff --git a/Pro Puppet/source/chapter02/apache/._.DS_Store b/Pro Puppet/source/chapter02/apache/._.DS_Store new file mode 100644 index 0000000..321346b Binary files /dev/null and b/Pro Puppet/source/chapter02/apache/._.DS_Store differ diff --git a/Pro Puppet/source/chapter02/apache/manifests/init.pp b/Pro Puppet/source/chapter02/apache/manifests/init.pp new file mode 100644 index 0000000..25d9797 --- /dev/null +++ b/Pro Puppet/source/chapter02/apache/manifests/init.pp @@ -0,0 +1,3 @@ +class apache { + include apache::install, apache::service +} diff --git a/Pro Puppet/source/chapter02/apache/manifests/install.pp b/Pro Puppet/source/chapter02/apache/manifests/install.pp new file mode 100644 index 0000000..68d84d4 --- /dev/null +++ b/Pro Puppet/source/chapter02/apache/manifests/install.pp @@ -0,0 +1,5 @@ +class apache::install { + package { [ "apache2" ]: + ensure => present, + } +} diff --git a/Pro Puppet/source/chapter02/apache/manifests/service.pp b/Pro Puppet/source/chapter02/apache/manifests/service.pp new file mode 100644 index 0000000..14abeb2 --- /dev/null +++ b/Pro Puppet/source/chapter02/apache/manifests/service.pp @@ -0,0 +1,9 @@ +class apache::service { + service { "apache2": + ensure => running, + hasstatus => true, + hasrestart => true, + enable => true, + require => Class["apache::install"], + } +} diff --git a/Pro Puppet/source/chapter02/apache/manifests/vhost.pp b/Pro Puppet/source/chapter02/apache/manifests/vhost.pp new file mode 100644 index 0000000..19e9a7b --- /dev/null +++ b/Pro Puppet/source/chapter02/apache/manifests/vhost.pp @@ -0,0 +1,13 @@ +define apache::vhost( $port, $docroot, $ssl=true, $template='apache/vhost.conf.erb', $priority, $serveraliases = '' ) { + + include apache + + file {"/etc/apache2/sites-enabled/${priority}-${name}": + content => template($template), + owner => 'root', + group => 'root', + mode => '777', + require => Class["apache::install"], + notify => Class["apache::service"], + } +} diff --git a/Pro Puppet/source/chapter02/apache/templates/vhost.conf.erb b/Pro Puppet/source/chapter02/apache/templates/vhost.conf.erb new file mode 100644 index 0000000..3aaf945 --- /dev/null +++ b/Pro Puppet/source/chapter02/apache/templates/vhost.conf.erb @@ -0,0 +1,20 @@ +NameVirtualHost *:<%= port %> +> + ServerName <%= name %> +<%if serveraliases.is_a? Array -%> +<% serveraliases.each do |name| -%><%= " ServerAlias #{name}\n" %><% end -%> +<% elsif serveraliases != '' -%> +<%= " ServerAlias #{serveraliases}" -%> +<% end -%> + DocumentRoot <%= docroot %> + > + Options Indexes FollowSymLinks MultiViews + AllowOverride None + Order allow,deny + allow from all + + ErrorLog /var/log/apache2/<%= name %>_error.log + LogLevel warn + CustomLog /var/log/apache2/<%= name %>_access.log combined + ServerSignature On + diff --git a/Pro Puppet/source/chapter02/mysql/manifests/config.pp b/Pro Puppet/source/chapter02/mysql/manifests/config.pp new file mode 100644 index 0000000..fb2ea8b --- /dev/null +++ b/Pro Puppet/source/chapter02/mysql/manifests/config.pp @@ -0,0 +1,17 @@ +class mysql::config { + file { "/opt/csw/mysql5/my.cnf": + ensure = > present, + source => "puppet:///modules/mysql/my.cnf", + owner => "mysql", + group => "mysql", + require => Class["mysql::install"], + notify => Class["mysql::service"], + } + + file { "/opt/csw/mysql5/var": + group => "mysql", + owner => "mysql", + recurse => true, + require => File["/opt/csw/mysql5/my.cnf"], + } +} diff --git a/Pro Puppet/source/chapter02/mysql/manifests/init.pp b/Pro Puppet/source/chapter02/mysql/manifests/init.pp new file mode 100644 index 0000000..71b1840 --- /dev/null +++ b/Pro Puppet/source/chapter02/mysql/manifests/init.pp @@ -0,0 +1,3 @@ +class mysql { + include mysql::install, mysql::config, mysql::service +} diff --git a/Pro Puppet/source/chapter02/mysql/manifests/install.pp b/Pro Puppet/source/chapter02/mysql/manifests/install.pp new file mode 100644 index 0000000..d69cba8 --- /dev/null +++ b/Pro Puppet/source/chapter02/mysql/manifests/install.pp @@ -0,0 +1,18 @@ +class mysql::install { + package { [ "mysql5", "mysql5client", "mysql5rt", "mysql5test", "mysql5devel" ]: + ensure => present, + require => User["mysql"], +} + + user { "mysql": + ensure => present, + comment => "MySQL user", + gid => "mysql", + shell => "/bin/false", + require => Group["mysql"], +} + + group { "mysql": + ensure => present, + } +} diff --git a/Pro Puppet/source/chapter02/mysql/manifests/service.pp b/Pro Puppet/source/chapter02/mysql/manifests/service.pp new file mode 100644 index 0000000..4e2c1cd --- /dev/null +++ b/Pro Puppet/source/chapter02/mysql/manifests/service.pp @@ -0,0 +1,9 @@ +class mysql::service { + service { "cswmysql5": + ensure => running, + hasstatus => true, + hasrestart => true, + enabled => true, + require => Class["mysql::config"], + } +} diff --git a/Pro Puppet/source/chapter02/nodes.pp b/Pro Puppet/source/chapter02/nodes.pp new file mode 100644 index 0000000..60f7022 --- /dev/null +++ b/Pro Puppet/source/chapter02/nodes.pp @@ -0,0 +1,28 @@ +class base { + include sudo, ssh, puppet +} + +node puppet.example.com { + include base + include puppet::master +} + +node web.example.com { + include base, apache + + apache::vhost { 'www.example.com': + port => 80, + docroot => '/var/www/www.example.com', + ssl => false, + priority => 10, + serveraliases => 'home.example.com', + } +} + +node db.example.com { + include base, mysql +} + +node mail.example.com { + include base, postfix +} diff --git a/Pro Puppet/source/chapter02/postfix/.DS_Store b/Pro Puppet/source/chapter02/postfix/.DS_Store new file mode 100644 index 0000000..c191a5a Binary files /dev/null and b/Pro Puppet/source/chapter02/postfix/.DS_Store differ diff --git a/Pro Puppet/source/chapter02/postfix/._.DS_Store b/Pro Puppet/source/chapter02/postfix/._.DS_Store new file mode 100644 index 0000000..460d887 Binary files /dev/null and b/Pro Puppet/source/chapter02/postfix/._.DS_Store differ diff --git a/Pro Puppet/source/chapter02/postfix/files/master.cf b/Pro Puppet/source/chapter02/postfix/files/master.cf new file mode 100644 index 0000000..280f3da --- /dev/null +++ b/Pro Puppet/source/chapter02/postfix/files/master.cf @@ -0,0 +1,89 @@ +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master"). +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== +smtp inet n - n - - smtpd +submission inet n - n - - smtpd + -o smtpd_enforce_tls=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject +smtps inet n - n - - smtpd + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject +#628 inet n - n - - qmqpd +pickup fifo n - n 60 1 pickup +cleanup unix n - n - 0 cleanup +qmgr fifo n - n 300 1 qmgr +#qmgr fifo n - n 300 1 oqmgr +tlsmgr unix - - n 1000? 1 tlsmgr +rewrite unix - - n - - trivial-rewrite +bounce unix - - n - 0 bounce +defer unix - - n - 0 bounce +trace unix - - n - 0 bounce +verify unix - - n - 1 verify +flush unix n - n 1000? 0 flush +proxymap unix - - n - - proxymap +smtp unix - - n - - smtp +# When relaying mail as backup MX, disable fallback_relay to avoid MX loops +relay unix - - n - - smtp + -o fallback_relay= +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - n - - showq +error unix - - n - - error +retry unix - - n - - error +discard unix - - n - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - n - - lmtp +anvil unix - - n - 1 anvil +scache unix - - n - 1 scache +# +# ==================================================================== +# Interfaces to non-Postfix software. Be sure to examine the manual +# pages of the non-Postfix software to find out what options it wants. +# +# Many of the following services use the Postfix pipe(8) delivery +# agent. See the pipe(8) man page for information about ${recipient} +# and other message envelope options. +# ==================================================================== +# +# maildrop. See the Postfix MAILDROP_README file for details. +# Also specify in main.cf: maildrop_destination_recipient_limit=1 +# +#maildrop unix - n n - - pipe +# flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient} +# +# The Cyrus deliver program has changed incompatibly, multiple times. +# +#old-cyrus unix - n n - - pipe +# flags=R user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -m ${extension} ${user} +# Cyrus 2.1.5 (Amos Gouaux) +# Also specify in main.cf: cyrus_destination_recipient_limit=1 +#cyrus unix - n n - - pipe +# user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -r ${sender} -m ${extension} ${user} +# +# See the Postfix UUCP_README file for configuration details. +# +#uucp unix - n n - - pipe +# flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) +# +# Other external delivery methods. +# +#ifmail unix - n n - - pipe +# flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) +#bsmtp unix - n n - - pipe +# flags=Fq. user=foo argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient +# +#scalemail-backend unix - n n - 2 pipe +# flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store +# ${nexthop} ${user} ${extension} +# +#mailman unix - n n - - pipe +# flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py +# ${nexthop} ${user} +proxywrite unix - - n - 1 proxymap \ No newline at end of file diff --git a/Pro Puppet/source/chapter02/postfix/manifests/config.pp b/Pro Puppet/source/chapter02/postfix/manifests/config.pp new file mode 100644 index 0000000..15cb126 --- /dev/null +++ b/Pro Puppet/source/chapter02/postfix/manifests/config.pp @@ -0,0 +1,21 @@ +class postfix::config { + File { + owner => "postfix", + group => "postfix", + mode => 0644, + } + + file { "/etc/postfix/master.cf": + ensure = > present, + source => "puppet:///modules/postfix/master.cf", + require => Class["postfix::install"], + notify => Class["postfix::service"], + } + + file { "/etc/postfix/main.cf": + ensure = > present, + content => template("postfix/main.cf.erb"), + require => Class["postfix::install"], + notify => Class["postfix::service"], + } +} diff --git a/Pro Puppet/source/chapter02/postfix/manifests/init.pp b/Pro Puppet/source/chapter02/postfix/manifests/init.pp new file mode 100644 index 0000000..cf9459f --- /dev/null +++ b/Pro Puppet/source/chapter02/postfix/manifests/init.pp @@ -0,0 +1,3 @@ +class postfix { + include postfix::install, postfix::config, postfix::service +} diff --git a/Pro Puppet/source/chapter02/postfix/manifests/install.pp b/Pro Puppet/source/chapter02/postfix/manifests/install.pp new file mode 100644 index 0000000..ca8be7d --- /dev/null +++ b/Pro Puppet/source/chapter02/postfix/manifests/install.pp @@ -0,0 +1,5 @@ +class postfix::install { + package { [ "postfix", "mailx" ]: + ensure => present, + } +} diff --git a/Pro Puppet/source/chapter02/postfix/manifests/service.pp b/Pro Puppet/source/chapter02/postfix/manifests/service.pp new file mode 100644 index 0000000..373d6d0 --- /dev/null +++ b/Pro Puppet/source/chapter02/postfix/manifests/service.pp @@ -0,0 +1,9 @@ +class postfix::service { + service { "postfix": + ensure => running, + hasstatus => true, + hasrestart => true, + enable => true, + require => Class["postfix::config"], + } +} diff --git a/Pro Puppet/source/chapter02/postfix/templates/main.cf.erb b/Pro Puppet/source/chapter02/postfix/templates/main.cf.erb new file mode 100644 index 0000000..3331237 --- /dev/null +++ b/Pro Puppet/source/chapter02/postfix/templates/main.cf.erb @@ -0,0 +1,14 @@ +soft_bounce = no +command_directory = /usr/sbin +daemon_directory = /usr/libexec/postfix +mail_owner = postfix +myhostname = <%= hostname %> +mydomain = <%= domain %> +myorigin = $mydomain +mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain +unknown_local_recipient_reject_code = 550 +relay_domains = $mydestination +smtpd_reject_unlisted_recipient = yes +unverified_recipient_reject_code = 550 +smtpd_banner = $myhostname ESMTP +setgid_group = postdrop \ No newline at end of file diff --git a/Pro Puppet/source/chapter02/puppet/manifests/config.pp b/Pro Puppet/source/chapter02/puppet/manifests/config.pp new file mode 100644 index 0000000..e0694b9 --- /dev/null +++ b/Pro Puppet/source/chapter02/puppet/manifests/config.pp @@ -0,0 +1,13 @@ +class puppet::config { + +include puppet::params + + file { "/etc/puppet/puppet.conf": + ensure = > present, + content => template("puppet/puppet.conf.erb"), + owner => "puppet", + group => "puppet", + require => Class["puppet::install"], + notify => Class["puppet::service"], + } +} diff --git a/Pro Puppet/source/chapter02/puppet/manifests/init.pp b/Pro Puppet/source/chapter02/puppet/manifests/init.pp new file mode 100644 index 0000000..c2c990b --- /dev/null +++ b/Pro Puppet/source/chapter02/puppet/manifests/init.pp @@ -0,0 +1,3 @@ +class puppet { + include puppet::install, puppet::config, puppet::service +} diff --git a/Pro Puppet/source/chapter02/puppet/manifests/install.pp b/Pro Puppet/source/chapter02/puppet/manifests/install.pp new file mode 100644 index 0000000..3b1b032 --- /dev/null +++ b/Pro Puppet/source/chapter02/puppet/manifests/install.pp @@ -0,0 +1,5 @@ +class puppet::install { + package { "puppet" : + ensure => present, + } +} diff --git a/Pro Puppet/source/chapter02/puppet/manifests/master.pp b/Pro Puppet/source/chapter02/puppet/manifests/master.pp new file mode 100644 index 0000000..edbd841 --- /dev/null +++ b/Pro Puppet/source/chapter02/puppet/manifests/master.pp @@ -0,0 +1,17 @@ +class puppet::master { + +include puppet +include puppet::params + +package { "puppet-server": + ensure => installed, +} + +service { "puppetmasterd": + ensure => running, + hasstatus => true, + hasrestart => true, + enable => true, + require => File["/etc/puppet/puppet.conf"], + } +} diff --git a/Pro Puppet/source/chapter02/puppet/manifests/params.pp b/Pro Puppet/source/chapter02/puppet/manifests/params.pp new file mode 100644 index 0000000..aa794c6 --- /dev/null +++ b/Pro Puppet/source/chapter02/puppet/manifests/params.pp @@ -0,0 +1,3 @@ +class puppet::params { + $puppetserver = "puppet.example.com" +} diff --git a/Pro Puppet/source/chapter02/puppet/manifests/service.pp b/Pro Puppet/source/chapter02/puppet/manifests/service.pp new file mode 100644 index 0000000..cf9e78f --- /dev/null +++ b/Pro Puppet/source/chapter02/puppet/manifests/service.pp @@ -0,0 +1,9 @@ +class puppet::service { + service { "puppet": + ensure => running, + hasstatus => true, + hasrestart => true, + enable => true, + require => Class["puppet::install"], + } +} diff --git a/Pro Puppet/source/chapter02/puppet/templates/puppet.conf.erb b/Pro Puppet/source/chapter02/puppet/templates/puppet.conf.erb new file mode 100644 index 0000000..fb0c8d2 --- /dev/null +++ b/Pro Puppet/source/chapter02/puppet/templates/puppet.conf.erb @@ -0,0 +1,13 @@ +[main] + user = puppet + group = puppet + report = true + reports = log,store + +[master] + certname = <%= puppetserver %> + +[agent] + pluginsync = false + report = true + server = <%= puppetserver %> diff --git a/Pro Puppet/source/chapter02/ssh/files/sshd_config b/Pro Puppet/source/chapter02/ssh/files/sshd_config new file mode 100644 index 0000000..6ddb3d3 --- /dev/null +++ b/Pro Puppet/source/chapter02/ssh/files/sshd_config @@ -0,0 +1,6 @@ +Port 22 +Protocol 2 +SyslogFacility AUTHPRIV +PermitRootLogin no +PasswordAuthentication yes +UsePAM yes \ No newline at end of file diff --git a/Pro Puppet/source/chapter02/ssh/manifests/config.pp b/Pro Puppet/source/chapter02/ssh/manifests/config.pp new file mode 100644 index 0000000..6f3e25b --- /dev/null +++ b/Pro Puppet/source/chapter02/ssh/manifests/config.pp @@ -0,0 +1,11 @@ +class ssh::config { + file { "/etc/ssh/sshd_config": + ensure = > present, + owner => 'root', + group => 'root', + mode => 0440, + source => "puppet:///modules/ssh/sshd_config", + require => Class["ssh::install"], + notify => Class["ssh::service"], + } +} diff --git a/Pro Puppet/source/chapter02/ssh/manifests/init.pp b/Pro Puppet/source/chapter02/ssh/manifests/init.pp new file mode 100644 index 0000000..42af98c --- /dev/null +++ b/Pro Puppet/source/chapter02/ssh/manifests/init.pp @@ -0,0 +1,3 @@ +class ssh + include ssh::params, ssh::install, ssh::config, ssh::service +} diff --git a/Pro Puppet/source/chapter02/ssh/manifests/install.pp b/Pro Puppet/source/chapter02/ssh/manifests/install.pp new file mode 100644 index 0000000..c2243ad --- /dev/null +++ b/Pro Puppet/source/chapter02/ssh/manifests/install.pp @@ -0,0 +1,5 @@ +class ssh::install { + package { $ssh::params::package_name: + ensure => installed, + } +} diff --git a/Pro Puppet/source/chapter02/ssh/manifests/params.pp b/Pro Puppet/source/chapter02/ssh/manifests/params.pp new file mode 100644 index 0000000..d92f658 --- /dev/null +++ b/Pro Puppet/source/chapter02/ssh/manifests/params.pp @@ -0,0 +1,19 @@ +class ssh::params { + case $operatingsystem { + Solaris: { + $ssh_package_name = 'openssh' + $ssh_service_config = '/etc/ssh/sshd_config' + $ssh_service_name = 'sshd' + } + /(Ubuntu|Debian)/: { + $ssh_package_name = 'openssh-server' + $ssh_service_config = '/etc/ssh/sshd_config' + $ssh_service_name = 'ssh' + } + /(RedHat|CentOS|Fedora)/: { + $ssh_package_name = 'openssh-server' + $ssh_service_config = '/etc/ssh/sshd_config' + $ssh_service_name = 'sshd' + } + } +} diff --git a/Pro Puppet/source/chapter02/ssh/manifests/service.pp b/Pro Puppet/source/chapter02/ssh/manifests/service.pp new file mode 100644 index 0000000..14131c3 --- /dev/null +++ b/Pro Puppet/source/chapter02/ssh/manifests/service.pp @@ -0,0 +1,9 @@ +class ssh::service { + service { $ssh::params::ssh_service_name: + ensure => running, + hasstatus => true, + hasresstart => true, + enable => true, + require => Class["ssh::config"], + } +} diff --git a/Pro Puppet/source/chapter02/sudo/files/etc/sudoers b/Pro Puppet/source/chapter02/sudo/files/etc/sudoers new file mode 100644 index 0000000..6afad32 --- /dev/null +++ b/Pro Puppet/source/chapter02/sudo/files/etc/sudoers @@ -0,0 +1,45 @@ +# sudoers file. +# +# This file MUST be edited with the 'visudo' command as root. +# Failure to use 'visudo' may result in syntax or file permission errors +# that prevent sudo from running. +# +# See the sudoers man page for the details on how to write a sudoers file. +# + +# Host alias specification + +# User alias specification + +# Cmnd alias specification + +# Defaults specification +Defaults env_reset +Defaults env_keep += "BLOCKSIZE" +Defaults env_keep += "COLORFGBG COLORTERM" +Defaults env_keep += "__CF_USER_TEXT_ENCODING" +Defaults env_keep += "CHARSET LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE" +Defaults env_keep += "LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME" +Defaults env_keep += "LINES COLUMNS" +Defaults env_keep += "LSCOLORS" +Defaults env_keep += "SSH_AUTH_SOCK" +Defaults env_keep += "TZ" +Defaults env_keep += "DISPLAY XAUTHORIZATION XAUTHORITY" +Defaults env_keep += "EDITOR VISUAL" +Defaults env_keep += "HOME MAIL" + +# Runas alias specification + +# User privilege specification +root ALL=(ALL) ALL +%admin ALL=(ALL) ALL + +# Uncomment to allow people in group wheel to run all commands +# %wheel ALL=(ALL) ALL + +# Same thing without a password +# %wheel ALL=(ALL) NOPASSWD: ALL + +# Samples +# %users ALL=/sbin/mount /cdrom,/sbin/umount /cdrom +# %users localhost=/sbin/shutdown -h now diff --git a/Pro Puppet/source/chapter02/sudo/manifests/init.pp b/Pro Puppet/source/chapter02/sudo/manifests/init.pp new file mode 100644 index 0000000..7221453 --- /dev/null +++ b/Pro Puppet/source/chapter02/sudo/manifests/init.pp @@ -0,0 +1,20 @@ +class sudo { + package { sudo: + ensure => present, + } + + if $operatingsystem == “Ubuntu” { + package { “sudo-ldap”: + ensure => present, + require => Package[“sudo”], + } + } + + file { "/etc/sudoers": + owner => "root", + group => "root", + mode => 0440, + source => "puppet:///modules/sudo/etc/sudoers", + require => Package[“sudo”], + } +} diff --git a/Pro Puppet/source/chapter04/01_single_instance_apache_configuration/10_passenger.conf b/Pro Puppet/source/chapter04/01_single_instance_apache_configuration/10_passenger.conf new file mode 100644 index 0000000..ee25417 --- /dev/null +++ b/Pro Puppet/source/chapter04/01_single_instance_apache_configuration/10_passenger.conf @@ -0,0 +1,16 @@ +# /etc/httpd/conf.d/10_passenger.conf +# The passenger module path should match ruby gem version +LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11/ext/apache2/mod_passenger.so +PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11 +PassengerRuby /usr/bin/ruby +# Recommended Passenger Configuration +PassengerHighPerformance on +PassengerUseGlobalQueue on +# PassengerMaxPoolSize controls the number of application instances, +# typically 1.5x the number of processor cores. +PassengerMaxPoolSize 6 +# Restart ruby process after handling specific number of request to resolve MRI memory leak. +PassengerMaxRequests 4000 +# Shutdown idle Passenger instances after 30 min. +PassengerPoolIdleTime 1800 +# End of /etc/httpd/conf.d/10_passenger.conf diff --git a/Pro Puppet/source/chapter04/01_single_instance_apache_configuration/20_puppetmaster.conf b/Pro Puppet/source/chapter04/01_single_instance_apache_configuration/20_puppetmaster.conf new file mode 100644 index 0000000..6699487 --- /dev/null +++ b/Pro Puppet/source/chapter04/01_single_instance_apache_configuration/20_puppetmaster.conf @@ -0,0 +1,37 @@ +# /etc/httpd/conf.d/20_puppetmaster.conf +# Apache handles the SSL encryption and decryption. +# It replaces webrick and listens by default on 8140 +Listen 8140 + + SSLEngine on + SSLProtocol -ALL +SSLv3 +TLSv1 + SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP + # Puppet master should generate initial CA certificate. ensure certs are + # located in /var/lib/puppet/ssl Change puppet.example.com to the fully + # qualified domain name of the Puppet master, i.e. $(facter fqdn). + SSLCertificateFile /var/lib/puppet/ssl/certs/puppet.example.com.pem + SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/puppet.example.com.pem + SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem + SSLCACertificateFile /var/lib/puppet/ssl/ca/ca_crt.pem + # CRL checking should be enabled + # disable next line if Apache complains about CRL + SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem + # optional to allow CSR request, required if certificates distributed to + # client during provisioning. + SSLVerifyClient optional + SSLVerifyDepth 1 + SSLOptions +StdEnvVars + # The following client headers record authentication information for down stream workers. + RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e + RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e + RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e + RackAutoDetect On + DocumentRoot /etc/puppet/rack/puppetmaster/public/ + + Options None + AllowOverride None + Order allow,deny + allow from all + + +# /etc/httpd/conf.d/20_puppetmaster.conf diff --git a/Pro Puppet/source/chapter04/01_single_instance_apache_configuration/config.ru b/Pro Puppet/source/chapter04/01_single_instance_apache_configuration/config.ru new file mode 100644 index 0000000..46c2c4f --- /dev/null +++ b/Pro Puppet/source/chapter04/01_single_instance_apache_configuration/config.ru @@ -0,0 +1,15 @@ +# /etc/puppet/rack/puppetmaster/config.ru +# +# This configuration is valid for Puppet 2.6 +# Puppet 2.7 and later may require slightly different rack +# configuration. Please see docs.puppetlabs.com for up to date +# information. +# +# a config.ru, for use with every rack-compatible webserver. +$0 = "master" +# if you want debugging, uncomment the next line +# ARGV << "--debug" +ARGV << "--rack" +require 'puppet/application/master' +run Puppet::Application[:master].run +# EOF /etc/puppet/rack/puppetmaster/config.ru diff --git a/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/10_passenger.conf b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/10_passenger.conf new file mode 100644 index 0000000..ee25417 --- /dev/null +++ b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/10_passenger.conf @@ -0,0 +1,16 @@ +# /etc/httpd/conf.d/10_passenger.conf +# The passenger module path should match ruby gem version +LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11/ext/apache2/mod_passenger.so +PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11 +PassengerRuby /usr/bin/ruby +# Recommended Passenger Configuration +PassengerHighPerformance on +PassengerUseGlobalQueue on +# PassengerMaxPoolSize controls the number of application instances, +# typically 1.5x the number of processor cores. +PassengerMaxPoolSize 6 +# Restart ruby process after handling specific number of request to resolve MRI memory leak. +PassengerMaxRequests 4000 +# Shutdown idle Passenger instances after 30 min. +PassengerPoolIdleTime 1800 +# End of /etc/httpd/conf.d/10_passenger.conf diff --git a/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/20_puppetmaster.conf b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/20_puppetmaster.conf new file mode 100644 index 0000000..9c44da0 --- /dev/null +++ b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/20_puppetmaster.conf @@ -0,0 +1,40 @@ +# /etc/httpd/conf.d/20_puppetmaster.conf +# Apache handles the SSL encryption and decryption. +# It replaces webrick and listens by default on 8141 +# +# Updated to 8141 to allow the font end load balancer +# to listen on port 8140 +Listen 8141 + + SSLEngine on + SSLProtocol -ALL +SSLv3 +TLSv1 + SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP + # Puppet master should generate initial CA certificate. ensure certs are + # located in /var/lib/puppet/ssl Change puppet.example.com to the fully + # qualified domain name of the Puppet master, i.e. $(facter fqdn). + SSLCertificateFile /var/lib/puppet/ssl/certs/puppet.example.com.pem + SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/puppet.example.com.pem + SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem + SSLCACertificateFile /var/lib/puppet/ssl/ca/ca_crt.pem + # CRL checking should be enabled + # disable next line if Apache complains about CRL + SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem + # optional to allow CSR request, required if certificates distributed to + # client during provisioning. + SSLVerifyClient optional + SSLVerifyDepth 1 + SSLOptions +StdEnvVars + # The following client headers record authentication information for down stream workers. + RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e + RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e + RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e + RackAutoDetect On + DocumentRoot /etc/puppet/rack/puppetmaster/public/ + + Options None + AllowOverride None + Order allow,deny + allow from all + + +# /etc/httpd/conf.d/20_puppetmaster.conf diff --git a/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/30_puppetmaster_frontend.conf b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/30_puppetmaster_frontend.conf new file mode 100644 index 0000000..66c16d2 --- /dev/null +++ b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/30_puppetmaster_frontend.conf @@ -0,0 +1,41 @@ +# Available back-end worker virtual hosts +# NOTE the use of cleartext unencrypted HTTP. + + BalancerMember http://127.0.0.1:18140 + BalancerMember http://127.0.0.1:18141 + +Listen 8140 + + SSLEngine on + # SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA + SSLProtocol -ALL +SSLv3 +TLSv1 + SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP + # Puppet master should generate initial CA certificate. + # ensure certs are located in /var/lib/puppet/ssl + SSLCertificateFile /var/lib/puppet/ssl/certs/puppet.example.com.pem + SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/puppet.example.com.pem + SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem + SSLCACertificateFile /var/lib/puppet/ssl/ca/ca_crt.pem + # CRL checking should be enabled + # disable next line if Apache complains about CRL + SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem + # This is optional to allow CSR request, required if certificates distributed to client during provisioning. + SSLVerifyClient optional + SSLVerifyDepth 1 + SSLOptions +StdEnvVars + # The following client headers record authentication information for down stream workers. + RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e + RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e + RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e + + SetHandler balancer-manager + Order allow,deny + Allow from all + + + ProxyPass / balancer://puppetmaster/ + ProxyPassReverse / balancer://puppetmaster/ + ProxyPreserveHost On + + + diff --git a/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/40_puppetmaster_worker_18140.conf b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/40_puppetmaster_worker_18140.conf new file mode 100644 index 0000000..7f3107b --- /dev/null +++ b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/40_puppetmaster_worker_18140.conf @@ -0,0 +1,15 @@ +Listen 18140 + + SSLEngine off + # Obtain Authentication Information from Client Request Headers + SetEnvIf X-Client-Verify "(.*)" SSL_CLIENT_VERIFY=$1 + SetEnvIf X-SSL-Client-DN "(.*)" SSL_CLIENT_S_DN=$1 + RackAutoDetect On + DocumentRoot /etc/puppet/rack/puppetmaster_18140/public/ + + Options None + AllowOverride None + Order allow,deny + allow from all + + diff --git a/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/41_puppetmaster_worker_18141.conf b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/41_puppetmaster_worker_18141.conf new file mode 100644 index 0000000..e0d527c --- /dev/null +++ b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/41_puppetmaster_worker_18141.conf @@ -0,0 +1,15 @@ +Listen 18141 + + SSLEngine off + # Obtain Authentication Information from Client Request Headers + SetEnvIf X-Client-Verify "(.*)" SSL_CLIENT_VERIFY=$1 + SetEnvIf X-SSL-Client-DN "(.*)" SSL_CLIENT_S_DN=$1 + RackAutoDetect On + DocumentRoot /etc/puppet/rack/puppetmaster_18141/public/ + + Options None + AllowOverride None + Order allow,deny + allow from all + + diff --git a/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/config.ru b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/config.ru new file mode 100644 index 0000000..46c2c4f --- /dev/null +++ b/Pro Puppet/source/chapter04/02_load_balanced_apache_configuration/config.ru @@ -0,0 +1,15 @@ +# /etc/puppet/rack/puppetmaster/config.ru +# +# This configuration is valid for Puppet 2.6 +# Puppet 2.7 and later may require slightly different rack +# configuration. Please see docs.puppetlabs.com for up to date +# information. +# +# a config.ru, for use with every rack-compatible webserver. +$0 = "master" +# if you want debugging, uncomment the next line +# ARGV << "--debug" +ARGV << "--rack" +require 'puppet/application/master' +run Puppet::Application[:master].run +# EOF /etc/puppet/rack/puppetmaster/config.ru diff --git a/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/10_passenger.conf b/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/10_passenger.conf new file mode 100644 index 0000000..ee25417 --- /dev/null +++ b/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/10_passenger.conf @@ -0,0 +1,16 @@ +# /etc/httpd/conf.d/10_passenger.conf +# The passenger module path should match ruby gem version +LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11/ext/apache2/mod_passenger.so +PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11 +PassengerRuby /usr/bin/ruby +# Recommended Passenger Configuration +PassengerHighPerformance on +PassengerUseGlobalQueue on +# PassengerMaxPoolSize controls the number of application instances, +# typically 1.5x the number of processor cores. +PassengerMaxPoolSize 6 +# Restart ruby process after handling specific number of request to resolve MRI memory leak. +PassengerMaxRequests 4000 +# Shutdown idle Passenger instances after 30 min. +PassengerPoolIdleTime 1800 +# End of /etc/httpd/conf.d/10_passenger.conf diff --git a/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/20_puppetmaster.conf b/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/20_puppetmaster.conf new file mode 100644 index 0000000..9c44da0 --- /dev/null +++ b/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/20_puppetmaster.conf @@ -0,0 +1,40 @@ +# /etc/httpd/conf.d/20_puppetmaster.conf +# Apache handles the SSL encryption and decryption. +# It replaces webrick and listens by default on 8141 +# +# Updated to 8141 to allow the font end load balancer +# to listen on port 8140 +Listen 8141 + + SSLEngine on + SSLProtocol -ALL +SSLv3 +TLSv1 + SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP + # Puppet master should generate initial CA certificate. ensure certs are + # located in /var/lib/puppet/ssl Change puppet.example.com to the fully + # qualified domain name of the Puppet master, i.e. $(facter fqdn). + SSLCertificateFile /var/lib/puppet/ssl/certs/puppet.example.com.pem + SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/puppet.example.com.pem + SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem + SSLCACertificateFile /var/lib/puppet/ssl/ca/ca_crt.pem + # CRL checking should be enabled + # disable next line if Apache complains about CRL + SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem + # optional to allow CSR request, required if certificates distributed to + # client during provisioning. + SSLVerifyClient optional + SSLVerifyDepth 1 + SSLOptions +StdEnvVars + # The following client headers record authentication information for down stream workers. + RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e + RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e + RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e + RackAutoDetect On + DocumentRoot /etc/puppet/rack/puppetmaster/public/ + + Options None + AllowOverride None + Order allow,deny + allow from all + + +# /etc/httpd/conf.d/20_puppetmaster.conf diff --git a/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/config.ru b/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/config.ru new file mode 100644 index 0000000..46c2c4f --- /dev/null +++ b/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/config.ru @@ -0,0 +1,15 @@ +# /etc/puppet/rack/puppetmaster/config.ru +# +# This configuration is valid for Puppet 2.6 +# Puppet 2.7 and later may require slightly different rack +# configuration. Please see docs.puppetlabs.com for up to date +# information. +# +# a config.ru, for use with every rack-compatible webserver. +$0 = "master" +# if you want debugging, uncomment the next line +# ARGV << "--debug" +ARGV << "--rack" +require 'puppet/application/master' +run Puppet::Application[:master].run +# EOF /etc/puppet/rack/puppetmaster/config.ru diff --git a/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/config.ru.ca_primary b/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/config.ru.ca_primary new file mode 100644 index 0000000..38cf4c3 --- /dev/null +++ b/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/config.ru.ca_primary @@ -0,0 +1,23 @@ +# /etc/puppet/rack/puppetmaster_18142/config.ru +# +# This configuration is valid for Puppet 2.6 +# Puppet 2.7 and later may require slightly different rack +# configuration. Please see docs.puppetlabs.com for up to date +# information. +# +# a config.ru, for use with every rack-compatible webserver. +$0 = "master" +# if you want debugging, uncomment the next line +# ARGV << "--debug" + +# This puppetmaster instance will be the "active" or "primary" certificate authority +# The standby certificate authority will use a different certificate authority directory +# since we're running both the primary and the secondary on the same host. +# We recommend running the primary and secondary CA on two different machines which +# will allow both to have the same filesystem path configured. The primary system should +# periodically replicate itself to the secondary. +ARGV << "--cadir" << "/var/lib/puppet/ssl/ca" +ARGV << "--rack" +require 'puppet/application/master' +run Puppet::Application[:master].run +# EOF /etc/puppet/rack/puppetmaster/config.ru diff --git a/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/config.ru.ca_standby b/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/config.ru.ca_standby new file mode 100644 index 0000000..d321ab9 --- /dev/null +++ b/Pro Puppet/source/chapter04/03_load_balanced_apache_configuration_with_centralized_ca/config.ru.ca_standby @@ -0,0 +1,24 @@ +# /etc/puppet/rack/puppetmaster_18143/config.ru +# +# This configuration is valid for Puppet 2.6 +# Puppet 2.7 and later may require slightly different rack +# configuration. Please see docs.puppetlabs.com for up to date +# information. +# +# a config.ru, for use with every rack-compatible webserver. +$0 = "master" +# if you want debugging, uncomment the next line +# ARGV << "--debug" + +# This puppetmaster instance will be the "standby" or "secondary" certificate authority +# The standby certificate authority will use a different certificate authority directory +# since we're running both the primary and the secondary on the same host in the book. +# We recommend running the primary and secondary CA on two different machines which +# will allow both to have the same filesystem path configured. The primary system should +# periodically replicate itself to the secondary. +ARGV << "--cadir" << "/var/lib/puppet/ssl/ca.standby" +ARGV << "--rack" + +require 'puppet/application/master' +run Puppet::Application[:master].run +# EOF /etc/puppet/rack/puppetmaster/config.ru diff --git a/Pro Puppet/source/chapter04/README_passenger.markdown b/Pro Puppet/source/chapter04/README_passenger.markdown new file mode 100644 index 0000000..e0aabe0 --- /dev/null +++ b/Pro Puppet/source/chapter04/README_passenger.markdown @@ -0,0 +1,16 @@ +The Passenger 2.2.11 RPM packages referenced in Chapter 4 are available online +at: + + * http://yum.puppetlabs.com/prosvc/ + +These packages are not officially supported by Puppet Labs. I built them to +effectively manage passenger using RPM packages rather than having to build the +native C extensions on every system I was working with during my consulting +engagements. + +The repository location may change in the future. If the above URL is no +longer valid, please ask about these packages in #puppet on freenode or the +puppet-users mailing list. + +Thanks, +-Jeff McCune diff --git a/Pro Puppet/source/chapter05/ldap_nodes.ldif.html b/Pro Puppet/source/chapter05/ldap_nodes.ldif.html new file mode 100644 index 0000000..52cba3b --- /dev/null +++ b/Pro Puppet/source/chapter05/ldap_nodes.ldif.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +

# LDIF Export for: ou=Hosts,dc=testing,dc=com

+

dn: ou=Hosts,dc=testing,dc=com

+

objectClass: organizationalUnit

+

objectClass: top

+

ou: Hosts

+


+

dn: cn=basenode,ou=Hosts,dc=testing,dc=com

+

cn: basenode

+

description: Basenode

+

objectClass: device

+

objectClass: top

+

objectClass: puppetClient

+

puppetclass: baseapps

+


+

dn: cn=webserver,ou=Hosts,dc=testing,dc=com

+

cn: webserver

+

description: Basenode

+

objectClass: device

+

objectClass: top

+

objectClass: puppetClient

+

parentnode: basenode

+

puppetclass: apache

+

puppetclass: squid

+

puppetclass: named

+ + diff --git a/Pro Puppet/source/chapter05/puppet_mysql_node_classifier.pl b/Pro Puppet/source/chapter05/puppet_mysql_node_classifier.pl new file mode 100644 index 0000000..0f75423 --- /dev/null +++ b/Pro Puppet/source/chapter05/puppet_mysql_node_classifier.pl @@ -0,0 +1,50 @@ +#!/usr/bin/perl -w +use strict; +use YAML qw( Dump ); +use DBI; + +my $hostname = shift || die "No hostname passed"; + +$hostname =~ /^(\w+)\.(\w+)\.(\w{3})$/ + or die "Invalid hostname: $hostname"; + +my ( $host, $domain, $net ) = ( $1, $2, $3 ); + +# MySQL Configuration +my $data_source = "dbi:mysql:database=puppet;host=localhost"; +my $username = "puppet"; +my $password = "password"; + +# Connect to the server +my $dbh = DBI->connect($data_source, $username, $password) + or die $DBI::errstr; + +# Build the query +my $sth = $dbh->prepare( qq{SELECT class FROM nodes WHERE node = '$hostname'}) + or die "Can't prepare statement: $DBI::errstr"; + +# Execute the query +my $rc = $sth->execute + or die "Can't execute statement: $DBI::errstr"; + +# Set parameters +my %parameters = ( + puppet_server => "puppet.$domain.$net" + ); + +# Set classes +my @class; +while (my @row=$sth->fetchrow_array) + { push(@class,@row) } + +# Check for problems +die $sth->errstr if $sth->err; + +# Disconnect from database +$dbh->disconnect; + +# Print the YAML +print Dump( { + classes => \@class, + parameters => \%parameters, +} ); diff --git a/Pro Puppet/source/chapter05/puppet_node_classifier.pl b/Pro Puppet/source/chapter05/puppet_node_classifier.pl new file mode 100644 index 0000000..4f21fd9 --- /dev/null +++ b/Pro Puppet/source/chapter05/puppet_node_classifier.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl -w +use strict; +use YAML qw( Dump ); + +my $hostname = shift || die "No hostname passed"; + +$hostname =~ /^(\w+)\.(\w+)\.(\w{3})$/ + or die "Invalid hostname: $hostname"; + +my ( $host, $domain, $net ) = ( $1, $2, $3 ); + +my @classes = ( 'base', $domain, ); +my %parameters = ( + puppetserver => "puppet.$domain.$net" + ); + +print Dump( { + classes => \@classes, + parameters => \%parameters, +} ); diff --git a/Pro Puppet/source/chapter05/puppet_node_classifier.rb b/Pro Puppet/source/chapter05/puppet_node_classifier.rb new file mode 100644 index 0000000..0a4511f --- /dev/null +++ b/Pro Puppet/source/chapter05/puppet_node_classifier.rb @@ -0,0 +1,38 @@ +#!/usr/bin/env ruby + +require 'yaml' + +node = ARGV[0] +default = { 'classes' => []} + +unless node =~ /(^\S+)\.(\S+\.\S+)$/ + print default.to_yaml +end + +hostname = $1 + +base = { 'environment' => 'production', + 'parameters' => { + 'puppetserver' => 'puppet.example.com' + }, + 'classes' => [ 'base' ], + } + +case hostname + when /^web?\w+$/ + web = { 'classes' => 'apache' } + base['classes'] << web['classes'] + puts YAML.dump(base) + when /^db?\w+$/ + db = { 'classes' => 'mysql' } + base['classes'] << db['classes'] + puts YAML.dump(base) + when /^mail?\w+$/ + mail = { 'classes' => 'postfix' } + base['classes'] << mail['classes'] + puts YAML.dump(base) + else + print default.to_yaml +end + +exit 0 diff --git a/Pro Puppet/source/chapter05/puppet_node_classifier.sh b/Pro Puppet/source/chapter05/puppet_node_classifier.sh new file mode 100644 index 0000000..46d7ec9 --- /dev/null +++ b/Pro Puppet/source/chapter05/puppet_node_classifier.sh @@ -0,0 +1,9 @@ +#!/bin/sh +cat <<"END" +--- +classes: + - base +parameters: + puppetserver: puppet.example.com +END +exit 0 diff --git a/Pro Puppet/source/chapter06/01_modules/accounts/manifests/init.pp b/Pro Puppet/source/chapter06/01_modules/accounts/manifests/init.pp new file mode 100644 index 0000000..a764e01 --- /dev/null +++ b/Pro Puppet/source/chapter06/01_modules/accounts/manifests/init.pp @@ -0,0 +1,3 @@ +class accounts { + +} diff --git a/Pro Puppet/source/chapter06/01_modules/accounts/manifests/virtual.pp b/Pro Puppet/source/chapter06/01_modules/accounts/manifests/virtual.pp new file mode 100644 index 0000000..8a9f97c --- /dev/null +++ b/Pro Puppet/source/chapter06/01_modules/accounts/manifests/virtual.pp @@ -0,0 +1,16 @@ +class accounts::virtual { + @user { "mysql": + ensure => present, + uid => 27, + gid => 27, + home => "/var/lib/mysql", + shell => "/bin/bash", + } + @user { "apache": + ensure => present, + uid => 48, + gid => "apache", + home => "/var/www", + shell => "/sbin/nologin", + } +} diff --git a/Pro Puppet/source/chapter06/01_modules/apache/manifests/account.pp b/Pro Puppet/source/chapter06/01_modules/apache/manifests/account.pp new file mode 100644 index 0000000..31fde60 --- /dev/null +++ b/Pro Puppet/source/chapter06/01_modules/apache/manifests/account.pp @@ -0,0 +1,18 @@ +class pache::account($ensure=present) { + user { 'apache': + ensure => $ensure, + gid => 48, + } + group { 'apache': + ensure => $ensure, + gid => 48, + } + + # Resource Chaining inside of a conditional + if ($ensure == present) { + Group['apache'] -> User['apache'] + } else { + User['apache'] -> Group['apache'] + } + +} diff --git a/Pro Puppet/source/chapter06/01_modules/apache/manifests/init.pp b/Pro Puppet/source/chapter06/01_modules/apache/manifests/init.pp new file mode 100644 index 0000000..2cd6e94 --- /dev/null +++ b/Pro Puppet/source/chapter06/01_modules/apache/manifests/init.pp @@ -0,0 +1 @@ +class apache { } diff --git a/Pro Puppet/source/chapter06/01_modules/nagios/manifests/export/target.pp b/Pro Puppet/source/chapter06/01_modules/nagios/manifests/export/target.pp new file mode 100644 index 0000000..a41bad8 --- /dev/null +++ b/Pro Puppet/source/chapter06/01_modules/nagios/manifests/export/target.pp @@ -0,0 +1,16 @@ +# This class exports nagios host and service check resources +class nagios::export::target { + @@nagios_host { "$fqdn": + ensure => present, + alias => $hostname, + address => $ipaddress, + use => "generic-host", + } + @@nagios_service { "check_ping_${hostname}": + check_command => "check_ping!100.0,20%!500.0,60%", + use => "generic-service", + host_name => "$fqdn", + notification_period => "24x7", + service_description => "${hostname}_check_ping", + } +} diff --git a/Pro Puppet/source/chapter06/01_modules/nagios/manifests/init.pp b/Pro Puppet/source/chapter06/01_modules/nagios/manifests/init.pp new file mode 100644 index 0000000..e69de29 diff --git a/Pro Puppet/source/chapter06/01_modules/nagios/manifests/monitor.pp b/Pro Puppet/source/chapter06/01_modules/nagios/manifests/monitor.pp new file mode 100644 index 0000000..112b902 --- /dev/null +++ b/Pro Puppet/source/chapter06/01_modules/nagios/manifests/monitor.pp @@ -0,0 +1,18 @@ +# Manage the Nagios monitoring service +class nagios::monitor { + # Manage the packages + package { [ "nagios", "nagios-plugins" ]: + ensure => installed + } + # Manage the Nagios monitoring service + service { "nagios": + ensure => true, + hasstatus => true, + enable => true, + subscribe => [ Package["nagios"], Package["nagios-plugins"] ], + } + + # collect resources and populate /etc/nagios/nagios_*.cfg + Nagios_host <<||>> { notify => Service["nagios"] } + Nagios_service <<||>> { notify => Service["nagios"] } +} diff --git a/Pro Puppet/source/chapter06/01_modules/ssh/manifests/hostkeys.pp b/Pro Puppet/source/chapter06/01_modules/ssh/manifests/hostkeys.pp new file mode 100644 index 0000000..ac5c26c --- /dev/null +++ b/Pro Puppet/source/chapter06/01_modules/ssh/manifests/hostkeys.pp @@ -0,0 +1,13 @@ +class ssh::hostkeys { + # Export these resources into the configuration database. + @@sshkey { "${fqdn}_dsa": + host_aliases => [ "$fqdn", "$hostname", "$ipaddress" ], + type => dsa, + key => $sshdsakey, + } + @@sshkey { "${fqdn}_rsa": + host_aliases => [ "$fqdn", "$hostname", "$ipaddress" ], + type => rsa, + key => $sshrsakey, + } +} diff --git a/Pro Puppet/source/chapter06/01_modules/ssh/manifests/init.pp b/Pro Puppet/source/chapter06/01_modules/ssh/manifests/init.pp new file mode 100644 index 0000000..835df90 --- /dev/null +++ b/Pro Puppet/source/chapter06/01_modules/ssh/manifests/init.pp @@ -0,0 +1,4 @@ +# Intentionally left blank. +# Please see hostkeys.pp for the source code to the +# exported resources chapter. +class ssh { } diff --git a/Pro Puppet/source/chapter06/01_modules/ssh/manifests/knownhosts.pp b/Pro Puppet/source/chapter06/01_modules/ssh/manifests/knownhosts.pp new file mode 100644 index 0000000..185ca6a --- /dev/null +++ b/Pro Puppet/source/chapter06/01_modules/ssh/manifests/knownhosts.pp @@ -0,0 +1,7 @@ +# Collect all exported resources. +# Include this class on any system that should have +# all of the known hosts of every other system. +class ssh::knownhosts { + Sshkey <<| |>> { ensure => present } +} + diff --git a/Pro Puppet/source/chapter06/01_modules/webapp/manifests/init.pp b/Pro Puppet/source/chapter06/01_modules/webapp/manifests/init.pp new file mode 100644 index 0000000..847c4c0 --- /dev/null +++ b/Pro Puppet/source/chapter06/01_modules/webapp/manifests/init.pp @@ -0,0 +1,19 @@ +class webapp { + include accounts::virtual + # This is an example web application + package { 'webapp': ensure => present } + + # Realize a specific virtual resource using the collection + # Syntax. This will select only user resoruces with a title + # of 'mysql'. There can only be one or zero of these resources. + # The collection syntax may be used to configure relationships among + # virtual resources and other resources. This is not possible + # with the realize() function + User <| title == 'mysql' |> { before => Pacakge['webapp'] } + # Alternatively, we can use the realize() function. + # Unlike the collection syntax above, this function will fail + # if the virtual resource is not declared. + realize(User['mysql']) +} + + diff --git a/Pro Puppet/source/chapter06/02_loadbalancer.pp b/Pro Puppet/source/chapter06/02_loadbalancer.pp new file mode 100644 index 0000000..fc641cf --- /dev/null +++ b/Pro Puppet/source/chapter06/02_loadbalancer.pp @@ -0,0 +1,35 @@ +# All of the source code for the load balancer is contained in one Puppet +# Manifests for readability. Typically, each defined resource type and class +# should be located inside of a module directory structure. + +# This is the defined resource type we will export to other nodes. A worker +# system's catalog will export this configuration resource into the database +# and a front end load balancer's catalog will collect these resources from the +# database. + +define balancermember($url) { + file { "/etc/httpd/conf.d.members/worker_${name}.conf": + ensure => file, + owner => 0, + group => 0, + mode => '0644', + content => " BalancerMember $url \n", + } +} + +# Back end worker nodes shoudl have the worker class in their catalog. +# When a puppet master compiles the catalog of a worker, it will export +# the balancermember resource to the database. +class worker { + @@balancermember { "${fqdn}": + url => "http://${fqdn}:18140", + } +} + +# Front end load balancer nodes should have the loadbalancer_members class in +# their catalog. They will collect the balancermember resources exported by +# the workers. +class loadbalancer_members { + Balancermember <<| |>> { notify => Service['apache'] } +} + diff --git a/Pro Puppet/source/chapter08/cucumber/autosign.conf b/Pro Puppet/source/chapter08/cucumber/autosign.conf new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/autosign.conf @@ -0,0 +1 @@ +* diff --git a/Pro Puppet/source/chapter08/cucumber/features/catalog/policy.feature b/Pro Puppet/source/chapter08/cucumber/features/catalog/policy.feature new file mode 100644 index 0000000..92b14b3 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/catalog/policy.feature @@ -0,0 +1,15 @@ +Feature: General policy for all catalogs + In order to ensure applicability of a host's catalog + As a manifest developer + I want all catalogs to obey some general rules + + Scenario Outline: Compile and verify catalog + Given a node specified by "features/yaml/.example.com.yaml" + When I compile its catalog + Then compilation should succeed + And all resource dependencies should resolve + And it should have a localadmin account + + Examples: + | hostname | + | login | diff --git a/Pro Puppet/source/chapter08/cucumber/features/steps/cron.rb b/Pro Puppet/source/chapter08/cucumber/features/steps/cron.rb new file mode 100644 index 0000000..a0bf243 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/steps/cron.rb @@ -0,0 +1,6 @@ +Then /^cron job "([^\"]*)" should be "([^\"]*)"$/ do |name, state| + steps %Q{ + Then there should be a resource "Cron[#{name}]" + And the state should be "#{state}" + } +end diff --git a/Pro Puppet/source/chapter08/cucumber/features/steps/exec.rb b/Pro Puppet/source/chapter08/cucumber/features/steps/exec.rb new file mode 100644 index 0000000..64c7720 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/steps/exec.rb @@ -0,0 +1,5 @@ +Then /^exec "([^\"]*)" should be present$/ do |name| + steps %Q{ + Then there should be a resource "Exec[#{name}]" + } +end diff --git a/Pro Puppet/source/chapter08/cucumber/features/steps/file.rb b/Pro Puppet/source/chapter08/cucumber/features/steps/file.rb new file mode 100644 index 0000000..ffeeb47 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/steps/file.rb @@ -0,0 +1,44 @@ +Then /^following directories should be created:$/ do |directories| + directories.hashes.each do |dir| + steps %Q{ + Then there should be a resource "File[#{dir['name']}]" + And the state should be "directory" + And the directory should have standard permissions + } + end +end + +Then /^the file should be a symlink to "([^\"]*)"$/ do |target| + fail unless @resource["ensure"] == target +end + +Then /^the file should contain "([^\"]*)"$/ do |text| + fail unless @resource["content"].include?(text) +end + +Then /^the (directory|file|script) should have standard permissions$/ do |type| + case type + when "directory" + mode = "0755" + when "file" + mode = "0444" + when "script" + mode = "0555" + else + fail + end + + steps %Q{ + Then the file should have a "group" of "root" + And the file should have a "mode" of "#{mode}" + And the file should have an "owner" of "root" + } +end + +Then /^there should be a (file|script) "([^\"]*)"$/ do |type, name| + steps %Q{ + Then there should be a resource "File[#{name}]" + And the state should be "present" + And the #{type} should have standard permissions + } +end diff --git a/Pro Puppet/source/chapter08/cucumber/features/steps/package.rb b/Pro Puppet/source/chapter08/cucumber/features/steps/package.rb new file mode 100644 index 0000000..50a0533 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/steps/package.rb @@ -0,0 +1,14 @@ +Then /^following packages should be dealt with:$/ do |packages| + packages.hashes.each do |package| + steps %Q{ + Then package "#{package['name']}" should be "#{package['state']}" + } + end +end + +Then /^package "([^\"]*)" should be "([^\"]*)"$/ do |package, state| + steps %Q{ + Then there should be a resource "Package[#{package}]" + And the state should be "#{state}" + } +end diff --git a/Pro Puppet/source/chapter08/cucumber/features/steps/puppet.rb b/Pro Puppet/source/chapter08/cucumber/features/steps/puppet.rb new file mode 100644 index 0000000..0d124db --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/steps/puppet.rb @@ -0,0 +1,70 @@ +Given /^a node of class "([^\"]*)"$/ do |klass| + @klass = klass +end + +Given /^a node named "([^\"]*)"$/ do |name| + @facts['hostname'] = name +end + +Given /^a node in network "([^\"]*)"$/ do |network| + @facts['network_eth0'] = network +end + +Given /^it is a virtual node$/ do + @facts['processor0'] = "QEMU Virtual CPU version 0.11.0" +end + +When /^I compile the catalog$/ do + compile_catalog +end + +Then /^the [a-z]* should have "([^\"]*)" set to "(false|true)"$/ do |res, bool| + if bool == "false" + fail unless @resource[res] == false + else + fail unless @resource[res] == true + end +end + +Then /^the [a-z]* should have an? "([^\"]*)" of "([^\"]*)"$/ do |property, value| + fail unless @resource[property] == value +end + +Then /^the [a-z]* should notify "([^\"]*)"$/ do |res| + fail unless @resource["notify"].to_s == res + steps %Q{ + Then the catalog should contain "#{res}" + } +end + +Then /^the [a-z]* should require "([^\"]*)"$/ do |res| + req = @resource["require"] + if req.is_a?(Array) + found = false + req.each do |r| + if r.to_s == res + found = true + break + end + end + fail unless found + else + fail unless req.to_s == res + end + steps %Q{ + Then the catalog should contain "#{res}" + } +end + +Then /^the catalog should contain "([^\"]*)"$/ do |res| + fail unless resource(res) +end + +Then /^the state should be "([^\"]*)"$/ do |state| + fail unless @resource["ensure"] == state +end + +Then /^there should be a resource "([^\"]*)"$/ do |res| + @resource = resource(res) + fail unless @resource +end diff --git a/Pro Puppet/source/chapter08/cucumber/features/steps/service.rb b/Pro Puppet/source/chapter08/cucumber/features/steps/service.rb new file mode 100644 index 0000000..3bd773f --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/steps/service.rb @@ -0,0 +1,14 @@ +Then /^service "([^\"]*)" should be "([^\"]*)"$/ do |name, state| + steps %Q{ + Then there should be a resource "Service[#{name}]" + } + if state == "disabled" + steps %Q{ + Then the service should have "enable" set to "false" + } + elsif state == "running" + steps %Q{ + Then the state should be "#{state}" + } + end +end diff --git a/Pro Puppet/source/chapter08/cucumber/features/steps/user.rb b/Pro Puppet/source/chapter08/cucumber/features/steps/user.rb new file mode 100644 index 0000000..31755da --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/steps/user.rb @@ -0,0 +1,21 @@ +Then /^"([^\"]*)" should be in groups? "([^\"]*)"$/ do |user, groups| + steps %Q{ + Then there should be a resource "User[#{user}]" + And the user should be in groups "#{groups}" + } +end + +Then /^the user should be in groups "([^\"]*)"$/ do |groups| + g = @resource["groups"] + g_s = g + if g.is_a?(Array) + g_s = g.join(' ') + end + fail unless g_s == groups +end + +Then /^it should have a (\w+) account$/ do |user| + steps %Q{ + Then there should be a resource "User[#{user}]" + } +end diff --git a/Pro Puppet/source/chapter08/cucumber/features/support/hooks.rb b/Pro Puppet/source/chapter08/cucumber/features/support/hooks.rb new file mode 100644 index 0000000..3588300 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/support/hooks.rb @@ -0,0 +1,9 @@ +Before do + # local configuration + # @confdir = File.join(File.dirname(__FILE__), '..', '..') + @confdir = "/etc/puppet" + # @manifest = File.join(@confdir, 'manifests', 'site.pp') + @manifest = "/etc/puppet/manifests/site.pp" + # adjust facts like this + @facts['architecture'] = "i386" +end diff --git a/Pro Puppet/source/chapter08/cucumber/features/support/world.rb b/Pro Puppet/source/chapter08/cucumber/features/support/world.rb new file mode 100644 index 0000000..2f24c46 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/support/world.rb @@ -0,0 +1,7 @@ + +require 'cucumber-puppet/puppet' +require 'cucumber-puppet/steps' + +World do + CucumberPuppet.new +end diff --git a/Pro Puppet/source/chapter08/cucumber/features/yaml/login.example.com.yaml b/Pro Puppet/source/chapter08/cucumber/features/yaml/login.example.com.yaml new file mode 100644 index 0000000..9a7f39c --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/yaml/login.example.com.yaml @@ -0,0 +1,91 @@ +--- !ruby/object:Puppet::Node + classes: + - motd_location + - accounts_ruby + environment: &id002 production + expiration: 2011-02-24 12:30:42.481350 -05:00 + name: login.example.com + parameters: + kernel: Linux + netmask: 255.255.255.0 + processorcount: "1" + swapfree: 375.75 MB + physicalprocessorcount: "0" + operatingsystemrelease: "6.0" + fqdn: debian.puppetlabs.vm + uniqueid: 007f0101 + lsbmajdistrelease: "6" + !ruby/sym _timestamp: Thu Feb 24 12:00:42 -0500 2011 + ipaddress: 192.168.69.132 + memorysize: 502.58 MB + is_virtual: "true" + virtual: vmware + clientversion: &id001 2.6.4 + rubysitedir: /usr/local/lib/site_ruby/1.8 + ps: ps -ef + hardwaremodel: i686 + kernelrelease: 2.6.32-5-686 + domain: puppetlabs.vm + macaddress_eth0: 00:0c:29:fa:f8:75 + netmask_eth0: 255.255.255.0 + timezone: EST + id: root + uptime_days: "1" + lsbdistrelease: "6.0" + manufacturer: "VMware, Inc." + type: Other + uptime_hours: "26" + selinux: "false" + interfaces: eth0 + memoryfree: 393.30 MB + hardwareisa: unknown + processor0: Intel(R) Core(TM)2 Duo CPU P8800 @ 2.66GHz + enc_location: Florida + lsbdistcodename: squeeze + kernelversion: 2.6.32 + lsbdistdescription: Debian GNU/Linux 6.0 (squeeze) + path: /var/lib/puppet/src/puppet/sbin:/var/lib/puppet/src/puppet/bin:/var/lib/puppet/src/facter/bin:/var/lib/puppet/src/puppet-scaffold/bin:/var/lib/puppet/src/puppet-module-tool/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin + uptime: 1 day + hostname: debian + puppetversion: *id001 + environment: *id002 + account_resources: + alice: + comment: Alice + groups: + - sudo + - sudo_nopw + - devel + gid: 601 + uid: 601 + shell: /bin/bash + home: /home/alice + password: "!!" + bob: + comment: Bob + groups: + - sudo + - sudo_nopw + - ops + gid: 602 + uid: 602 + shell: /bin/zsh + home: /home/bob + password: "!!" + facterversion: 1.5.8 + sshrsakey: AAAAB3NzaC1yc2EAAAADAQABAAABAQC2kQq6JhXLvdeJJ6hR1AMx4RMA/vzoSE16NHgQL/rNmr5CbM1amnPccoCqSZMCQD4g8FVgPE1QhJp0hDwBY4POCVk/UZ7zz4oIDsKUjDFxclkKu26F442i07Gx/hAiHQeUYrTq92ypvQZ98yDJoUbi7I2//vyIZg4NlltGyWXvZdHlsBXlFau4cH6DoHhNM+ELXMKPf/JfrCd9v92L8LbU07u18tWLW3t0VfbMh7Tk/MydrD1aIYMoRZOkST31kdFvy9/T2Gvf8qGV3F7gjAusnEcRVxndqDW/fpprbbZLXG+hci9yKqT1vb/cR5x7SjoBE6BxOmsPqFnXYoPeqSPd + serialnumber: VMware-56 4d 84 91 f4 d3 e5 7f-a9 d1 52 11 0e fa f8 75 + ipaddress_eth0: 192.168.69.132 + macaddress: 00:0c:29:fa:f8:75 + operatingsystem: Debian + kernelmajversion: "2.6" + swapsize: 375.99 MB + rubyversion: 1.8.7 + architecture: i386 + sshdsakey: AAAAB3NzaC1kc3MAAACBAJMjWDP1S7JI7/YIOQvDAiwvFsyC6ZgWKZjqoh/+UTV4BdkF+Vc2E1e1Otrs9PIimFrhwfyo1XWuXUJfv1pFLGDGpPxOGhNLTwzb8YKHGMDtCVYANc8KxJvPIXC9N1+l6l25CGsJocqfpecHAr6hU5lW1ZF/KJSaWbtAovg6SqDRAAAAFQDnSfUH/SBh9QjgC+WEqfcXfQQeKQAAAIAHBKA3HWiRlbFFnOZBHZgawFhP/5q/KmGA5K+krA4asJV/Rn9OrJTwaa6uKotOS2HTiMLaKkLu69jAYhKYzeVLyOoY7H/LahBws0gmuAydgYPvJ6pc6nzuZDFdE+lJesWTWIXgOUmJvlgblfp5y/ITLDdT94fRbPo7DZJitB9YpAAAAIBnxSYn9gDTNFTw0mTPHwTHeT6hAtC+bN6mhR3AmrOHRakeLbm7KIZPzg70Q92HElmHrXGaY02eoRIqJNKdPUuZ1tqc7ph1tfov2nhzX8IQ3DlICdfrqBGfHLxfTAqTKijVoDoEfv0sKOYQi4j9QVljYzP3zVEX6ct7vAvEwytssw== + network_eth0: 192.168.69.0 + productname: VMware Virtual Platform + uptime_seconds: "94579" + lsbdistid: Debian + clientcert: login.example.com + time: 2011-02-24 12:00:42.475924 -05:00 diff --git a/Pro Puppet/source/chapter08/cucumber/features/yaml/login.example.com.yaml.no_localadmin b/Pro Puppet/source/chapter08/cucumber/features/yaml/login.example.com.yaml.no_localadmin new file mode 100644 index 0000000..9a7f39c --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/yaml/login.example.com.yaml.no_localadmin @@ -0,0 +1,91 @@ +--- !ruby/object:Puppet::Node + classes: + - motd_location + - accounts_ruby + environment: &id002 production + expiration: 2011-02-24 12:30:42.481350 -05:00 + name: login.example.com + parameters: + kernel: Linux + netmask: 255.255.255.0 + processorcount: "1" + swapfree: 375.75 MB + physicalprocessorcount: "0" + operatingsystemrelease: "6.0" + fqdn: debian.puppetlabs.vm + uniqueid: 007f0101 + lsbmajdistrelease: "6" + !ruby/sym _timestamp: Thu Feb 24 12:00:42 -0500 2011 + ipaddress: 192.168.69.132 + memorysize: 502.58 MB + is_virtual: "true" + virtual: vmware + clientversion: &id001 2.6.4 + rubysitedir: /usr/local/lib/site_ruby/1.8 + ps: ps -ef + hardwaremodel: i686 + kernelrelease: 2.6.32-5-686 + domain: puppetlabs.vm + macaddress_eth0: 00:0c:29:fa:f8:75 + netmask_eth0: 255.255.255.0 + timezone: EST + id: root + uptime_days: "1" + lsbdistrelease: "6.0" + manufacturer: "VMware, Inc." + type: Other + uptime_hours: "26" + selinux: "false" + interfaces: eth0 + memoryfree: 393.30 MB + hardwareisa: unknown + processor0: Intel(R) Core(TM)2 Duo CPU P8800 @ 2.66GHz + enc_location: Florida + lsbdistcodename: squeeze + kernelversion: 2.6.32 + lsbdistdescription: Debian GNU/Linux 6.0 (squeeze) + path: /var/lib/puppet/src/puppet/sbin:/var/lib/puppet/src/puppet/bin:/var/lib/puppet/src/facter/bin:/var/lib/puppet/src/puppet-scaffold/bin:/var/lib/puppet/src/puppet-module-tool/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin + uptime: 1 day + hostname: debian + puppetversion: *id001 + environment: *id002 + account_resources: + alice: + comment: Alice + groups: + - sudo + - sudo_nopw + - devel + gid: 601 + uid: 601 + shell: /bin/bash + home: /home/alice + password: "!!" + bob: + comment: Bob + groups: + - sudo + - sudo_nopw + - ops + gid: 602 + uid: 602 + shell: /bin/zsh + home: /home/bob + password: "!!" + facterversion: 1.5.8 + sshrsakey: AAAAB3NzaC1yc2EAAAADAQABAAABAQC2kQq6JhXLvdeJJ6hR1AMx4RMA/vzoSE16NHgQL/rNmr5CbM1amnPccoCqSZMCQD4g8FVgPE1QhJp0hDwBY4POCVk/UZ7zz4oIDsKUjDFxclkKu26F442i07Gx/hAiHQeUYrTq92ypvQZ98yDJoUbi7I2//vyIZg4NlltGyWXvZdHlsBXlFau4cH6DoHhNM+ELXMKPf/JfrCd9v92L8LbU07u18tWLW3t0VfbMh7Tk/MydrD1aIYMoRZOkST31kdFvy9/T2Gvf8qGV3F7gjAusnEcRVxndqDW/fpprbbZLXG+hci9yKqT1vb/cR5x7SjoBE6BxOmsPqFnXYoPeqSPd + serialnumber: VMware-56 4d 84 91 f4 d3 e5 7f-a9 d1 52 11 0e fa f8 75 + ipaddress_eth0: 192.168.69.132 + macaddress: 00:0c:29:fa:f8:75 + operatingsystem: Debian + kernelmajversion: "2.6" + swapsize: 375.99 MB + rubyversion: 1.8.7 + architecture: i386 + sshdsakey: AAAAB3NzaC1kc3MAAACBAJMjWDP1S7JI7/YIOQvDAiwvFsyC6ZgWKZjqoh/+UTV4BdkF+Vc2E1e1Otrs9PIimFrhwfyo1XWuXUJfv1pFLGDGpPxOGhNLTwzb8YKHGMDtCVYANc8KxJvPIXC9N1+l6l25CGsJocqfpecHAr6hU5lW1ZF/KJSaWbtAovg6SqDRAAAAFQDnSfUH/SBh9QjgC+WEqfcXfQQeKQAAAIAHBKA3HWiRlbFFnOZBHZgawFhP/5q/KmGA5K+krA4asJV/Rn9OrJTwaa6uKotOS2HTiMLaKkLu69jAYhKYzeVLyOoY7H/LahBws0gmuAydgYPvJ6pc6nzuZDFdE+lJesWTWIXgOUmJvlgblfp5y/ITLDdT94fRbPo7DZJitB9YpAAAAIBnxSYn9gDTNFTw0mTPHwTHeT6hAtC+bN6mhR3AmrOHRakeLbm7KIZPzg70Q92HElmHrXGaY02eoRIqJNKdPUuZ1tqc7ph1tfov2nhzX8IQ3DlICdfrqBGfHLxfTAqTKijVoDoEfv0sKOYQi4j9QVljYzP3zVEX6ct7vAvEwytssw== + network_eth0: 192.168.69.0 + productname: VMware Virtual Platform + uptime_seconds: "94579" + lsbdistid: Debian + clientcert: login.example.com + time: 2011-02-24 12:00:42.475924 -05:00 diff --git a/Pro Puppet/source/chapter08/cucumber/features/yaml/mail.example.com.yaml b/Pro Puppet/source/chapter08/cucumber/features/yaml/mail.example.com.yaml new file mode 100644 index 0000000..2a9c621 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/yaml/mail.example.com.yaml @@ -0,0 +1,54 @@ +--- !ruby/object:Puppet::Node + classes: [] + environment: production + expiration: 2011-02-20 20:57:46.751877 -06:00 + name: mail.example.com + parameters: + netmask: 255.255.255.0 + kernel: SunOS + uniqueid: 2c3668f6 + operatingsystemrelease: "5.10" + netmask_lo0: 255.0.0.0 + fqdn: mail.example.com + ipaddress: 192.168.69.131 + is_virtual: "true" + virtual: vmware + clientversion: 2.6.4 (Puppet Enterprise 1.0) + ps: ps -ef + netmask_e1000g0: 255.255.255.0 + kernelrelease: "5.10" + hardwaremodel: i86pc + rubysitedir: /opt/puppet/lib/ruby/site_ruby/1.8 + domain: localdomain + uptime_days: "0" + id: root + timezone: PST + !ruby/sym _timestamp: Sun Feb 20 18:27:46 -0800 2011 + type: 0x1 (other) + uptime_hours: "9" + hardwareisa: i386 + network_lo0: 127.0.0.0 + manufacturer: "VMware, Inc." + interfaces: "lo0,e1000g0" + network_e1000g0: 192.168.69.0 + kernelversion: Generic_142910-17 + ipaddress_lo0: 127.0.0.1 + path: /opt/puppet/bin:/opt/csw/bin:/opt/csw/bin:/usr/sbin:/usr/bin:/usr/local/git/bin:/usr/local/git/sbin:/usr/local/git/bin:/usr/local/git/sbin:/sbin + ipaddress_e1000g0: 192.168.69.131 + uptime: 9:56 hours + puppetversion: 2.6.4 (Puppet Enterprise 1.0) + hostname: solbuild + environment: production + serialnumber: VMware-56 4d 56 a3 13 fc c1 6e-cb af 2a eb 86 0b 3e 3a + operatingsystem: Solaris + kernelmajversion: Generic_142910-17 + facterversion: 1.5.8 + sshrsakey: AAAAB3NzaC1yc2EAAAABIwAAAIEA63yOsETchPCMz7Yz0NyL9+yJC9iIeKVnkZvIJn/XL/yWWF1GVyNx2CA4Vjg98gEtH8G4vPOVtS70Ou7fjH4m3gUmHLw//W8zgZUNSwpOytClYr4c/WgcUPuUwP2XKMPyRQXrFLG4m3dWLy4hj2fiaviPU1A6xe9YC304WG7Af4s= + macaddress: 0:c:29:b:3e:3a + rubyversion: 1.8.7 + macaddress_e1000g0: 0:c:29:b:3e:3a + uptime_seconds: "35806" + sshdsakey: AAAAB3NzaC1kc3MAAACBAI47I9AIPaPAcHR0OSI4vtTggsf45oQElvshEte7N88p+WEVOc27pJpF5egLmmslaBjUkHiMxcUJWO3YRDcDQPV2d513uzXtWzMfS6SMgg8x2mM+CqZzu0yTA+xVTZUyg8W5EZNaUBj6rKCoF7bnecpeufG5IwgJi+QdsKlIxT9BAAAAFQDonQMhOco741eTzRh+yqY+ddaUOwAAAIAL9YCde0TiANuS5123Fhcg9Kbzla+HQtNn6p6Flseafql2pplg8klefKrFlZRVt1USQzcl9eAxSpl3EPoFxe0HVbHEGTsV5JkRuPAA27xztobdYuwZC8hbsFHfTRZ9g/QK1Hvh8fUwBJlbedv2r/DeYL/uGKnjdwISgNG0RcCrsAAAAIAdRURNbnKY8ElZ1B/S/5dG6aKkbliUbhNPN2DSzJ17DBG4bkBTGuLBOmy4yB/23x/DJg+4rXkDowR49SGMx5KZIvASZ/6GQMKYAAzQjzSTPIpxyrvpE4IuBnRq6De2MuVbsrO7yKIrlBdWkgteWLrXYOq9JzGWnEndYAZmbk+kgA== + productname: VMware Virtual Platform + clientcert: mail.example.com + time: 2011-02-20 20:27:46.750957 -06:00 diff --git a/Pro Puppet/source/chapter08/cucumber/features/yaml/www.example.com.yaml b/Pro Puppet/source/chapter08/cucumber/features/yaml/www.example.com.yaml new file mode 100644 index 0000000..c097ff6 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/features/yaml/www.example.com.yaml @@ -0,0 +1,85 @@ +--- !ruby/object:Puppet::Node + classes: [] + environment: &id003 production + expiration: 2011-02-24 20:23:08.719084 -05:00 + name: www.example.com + parameters: + sp_boot_rom_version: MBP71.0039.B0B + sp_number_processors: "2" + kernelmajversion: "10.6" + kernelversion: 10.6.0 + sp_secure_vm: secure_vm_enabled + netmask_vmnet8: 255.255.255.0 + clientversion: &id001 2.6.4 + sp_machine_name: MacBook Pro + sp_kernel_version: Darwin 10.6.0 + rubysitedir: /Users/jeff/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/site_ruby/1.8 + clientcert: www.example.com + sp_platform_uuid: 0DCCCC4C-FE89-514C-8DF8-4F056A13DE4F + ipaddress_tun0: 192.168.101.30 + ps: ps auxwww + macosx_productversion_major: "10.6" + sp_machine_model: "MacBookPro7,1" + hostname: heif + macaddress_vmnet1: 00:50:56:c0:00:01 + kernelrelease: &id002 10.6.0 + sp_smc_version_system: 1.62f5 + !ruby/sym _timestamp: Thu Feb 24 19:53:08 -0500 2011 + kernel: &id004 Darwin + sp_current_processor_speed: 2.66 GHz + sp_mmm_entry: MMM_stateMMM_enabled + uptime_seconds: "523687" + facterversion: 1.5.8 + sp_boot_volume: Macintosh HD + sp_local_host_name: heif + sp_boot_mode: normal_boot + sp_serial_number: WQ0160YNATN + ipaddress_vmnet1: 172.16.35.1 + network_vmnet1: 172.16.35.0 + sp_packages: "1" + network_tun0: 192.168.101.30 + interfaces: "lo0,gif0,stf0,en0,en1,fw0,vmnet1,vmnet8,tun0" + sshdsakey: AAAAB3NzaC1kc3MAAACBAKQtukTkY7zS73vMljzLxLzaVW9fZljJLAqAiGiPQQwLuIFowvtC5wsl+bC883wwFn6rlqcEp38XCW5BQoqpA/VTdl1o75G2m6EmBPcZpyiB0z9sIwL3sX6EhVl5uTw1nfmarYDFr7Xu8e1F8qO7cGs676hEjoNgS7OZ+IIftnsZAAAAFQCjFou1o1yrgVZ5UWXVU7Fyxk7AJwAAAIB7XAvQGc5QTtgOuYvj+FDFAay4IRWMeMAMzyQuDf3LtBm741hgp1eyghYmI4Vpg5cT2mn/P8cGm24PsYaLro/opZij1UrTS/noVVyqR5XxKQ62zb3gbdGsFiBqDhL5gEbN5nqlBcsNQez4vCVNCE9u6xIMnQ6lohPcIrPDAV3bKwAAAIAeMoKaqRLCSoK2BeoeEnv0o9WIimvFlYim8EmT5AGgKkbioGpyUcLKwz7agYAnXKlYRWwLQ40x9eW3nWk/6H13G7GNVSZWVfZoVUkjWBZ589h6FPfTq/qj5y/ED+pTn9zq250H+/B4NIKhw1gfji/yb7qJ6sI9fxsg0BLSVbJIog== + uptime: 6 days + timezone: EST + puppetversion: *id001 + path: /Users/jeff/src/puppet/sbin:/Users/jeff/src/puppet/bin:/Users/jeff/src/facter/bin:/Users/jeff/src/puppet-scaffold/bin:/Users/jeff/src/puppet-module-tool/bin:/Users/jeff/.rvm/gems/ruby-1.8.7-p302/bin:/Users/jeff/.rvm/gems/ruby-1.8.7-p302@global/bin:/Users/jeff/.rvm/rubies/ruby-1.8.7-p302/bin:/Users/jeff/.rvm/bin:/Users/jeff/src/puppet/sbin:/Users/jeff/src/puppet/bin:/Users/jeff/src/facter/bin:/Users/jeff/src/puppet-scaffold/bin:/Users/jeff/src/puppet-module-tool/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin:/usr/X11/bin:/Users/jeff/customization/bin:/Users/jeff/bin:/Users/jeff/.gem/ruby/1.8/bin:/usr/local/sbin:/opt/local/sbin:/opt/local/bin:/Library/Application Support/VMware Fusion + hardwaremodel: i386 + fqdn: www.example.com + sp_os_version: Mac OS X 10.6.6 (10J567) + sp_64bit_kernel_and_kexts: "no" + macaddress_en0: 58:b0:35:f2:47:a3 + uptime_days: "6" + operatingsystemrelease: *id002 + sp_cpu_type: Intel Core 2 Duo + sshrsakey: AAAAB3NzaC1yc2EAAAABIwAAAQEAy7lrgErefIFXAfaQ+TTdKv+Y26LV0Zd+HIa3AJZQekcSXZxuofgjKMJLyVvC1Qums1p3uU6OuOOLJXynTNsNfg/wQdODFpip/doAuf+Lc9lLGX6Cg83I9Qq7K64uoXfPkGWquvMBy++tF6QvsRPF7IZJGqqwCeirIdkYtMtzSlassu210U/XrPPFa3BagXdp1VZ0JV4MPt3CVJsIMJqFrSDlv3PbTrTu10n4tpdmgca6IJtXMwaoRszrFQERyOX0e40/AjC4taY/CeOm9i2Hx6zu28PeW3Wy7g7uLPGp1UqvraHO+oqoaYHMPXNtn2FJFktKbspKM+IHR9sbm2133Q== + environment: *id003 + macosx_productversion_minor: "6" + macaddress_en1: f8:1e:df:ea:ed:5c + macaddress_vmnet8: 00:50:56:c0:00:08 + netmask_lo0: 255.0.0.0 + rubyversion: 1.8.7 + ipaddress_lo0: 127.0.0.1 + netmask_vmnet1: 255.255.255.0 + sp_user_name: Jeff McCune (jeff) + ipaddress: 192.168.1.107 + network_lo0: 127.0.0.0 + sp_physical_memory: 8 GB + ipaddress_vmnet8: 192.168.69.1 + network_vmnet8: 192.168.69.0 + netmask_en1: 255.255.255.0 + sp_uptime: up 6:1:28:36 + macosx_productname: Mac OS X + ipaddress_en1: 192.168.1.107 + sp_l2_cache: 3 MB + macosx_buildversion: 10J567 + macaddress_fw0: 7c:6d:62:ff:fe:ff + network_en1: 192.168.1.0 + domain: local + uptime_hours: "145" + sp_bus_speed: 1.07 GHz + netmask: 255.255.255.0 + netmask_tun0: 255.255.255.255 + macosx_productversion: 10.6.6 + operatingsystem: *id004 + time: 2011-02-24 19:53:08.717919 -05:00 diff --git a/Pro Puppet/source/chapter08/cucumber/manifests/site.pp b/Pro Puppet/source/chapter08/cucumber/manifests/site.pp new file mode 100644 index 0000000..b331e0a --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/manifests/site.pp @@ -0,0 +1 @@ +node default { } diff --git a/Pro Puppet/source/chapter08/cucumber/modules/accounts_ruby/manifests/init.rb b/Pro Puppet/source/chapter08/cucumber/modules/accounts_ruby/manifests/init.rb new file mode 100644 index 0000000..b43e396 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/modules/accounts_ruby/manifests/init.rb @@ -0,0 +1,55 @@ +# Define a new accounts_ruby class. This is equivalent to: +# class accounts_ruby { ... } +hostclass :accounts_ruby do + + # Bring the accounts resources defined in the ENC into a local + # Ruby variable. + accounts = scope.lookupvar("account_resources") + + # Perform a sanity check on the data provided by the ENC. + raise Puppet::Error, + "account_resources must be a Hash" unless accounts.kind_of?(Hash) + + # First declare groups required by the accounts. These groups may be + # referenced in /etc/sudoers to grant sudo access and access without + # a password entry. + group([:sudo, :sudo_nopw], :ensure => "present") + + # Iterate over each account + # The Hash key will be stored in the local title variable + # The value of the hash entry will be stored in parameters + # The parameters are the resource parameters for each user account. + accounts.each do |title, parameters| + + # Some more sanity checking on the data passed in from the ENC. + raise Puppet::Error, + "account_resources[#{title}] must be a Hash" unless parameters.kind_of?(Hash) + + # Manage the home directory of this account with a file resource. + file(parameters["home"], + :ensure => "directory", + :owner => title, + :group => title, + :mode => 0700) + + # Each account should have a group of the same name. + group(title, + :ensure => "present", + :gid => parameters["gid"]) + + # Declare the user resource with the parameters for this account. + user(title, + :ensure => "present", + :uid => parameters["uid"], + :gid => parameters["gid"], + :comment => parameters["comment"], + :groups => parameters["groups"], + :shell => parameters["shell"], + :password => parameters["password"], + :home => parameters["home"], + :managehome => false) + + end + +end + diff --git a/Pro Puppet/source/chapter08/cucumber/modules/motd_location/manifests/init.rb b/Pro Puppet/source/chapter08/cucumber/modules/motd_location/manifests/init.rb new file mode 100644 index 0000000..54c1d76 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/modules/motd_location/manifests/init.rb @@ -0,0 +1,30 @@ +# Message of the Day class implemented in the Ruby DSL +hostclass :motd_location do + + # Lookup the enc_location parameter set by the ENC + # Assign it to the location variable in Ruby + location = scope.lookupvar("enc_location") + # Set a Ruby String variable to represent the contents + # of the message of the day file + motd_content = "This system is in: #{location}\n" + + # Declare a file resource using Ruby syntax + # This is equivalent to the Puppet Syntax: + # file { motd: + # ensure => "file", + # path => "/etc/motd", + # content => $motd_content, + # owner => 0, + # group => 0, + # mode => 0644, + # } + file("motd", + :ensure => "file", + :path => "/etc/motd", + :content => motd_content, + :owner => 0, + :group => 0, + :mode => 0644) + +end + diff --git a/Pro Puppet/source/chapter08/cucumber/puppet.conf b/Pro Puppet/source/chapter08/cucumber/puppet.conf new file mode 100644 index 0000000..eefaea8 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/puppet.conf @@ -0,0 +1,21 @@ +[main] + daemonize = false + vardir = /var/lib/puppet + ssldir = $vardir/ssl + manifestdir = $confdir/manifests + manifest = $confdir/manifests/site.pp + archive_files = true + server = hypervisor + certname = heif + certdnsnames = heif:hypervisor:www:danu-wire:parent:*:*.*:*.*.*:*.*.*.* + node_terminus = exec + external_nodes = $confdir/resources_enc.rb + +[agent] + report = true + test = true + +[master] + reports = store,http + reporturl = http://demo2:3000/reports/upload + diff --git a/Pro Puppet/source/chapter08/cucumber/resources_enc.rb b/Pro Puppet/source/chapter08/cucumber/resources_enc.rb new file mode 100644 index 0000000..d7a10c5 --- /dev/null +++ b/Pro Puppet/source/chapter08/cucumber/resources_enc.rb @@ -0,0 +1,59 @@ +#!/usr/bin/env ruby +# + +# Load the YAML library in ruby. Provide the to_yaml method for all +# Ruby objects. +require 'yaml' + +# The output hash. Must contain the "parameters" and "classes" key. +# See: http://docs.puppetlabs.com/guides/external_nodes.html +@out = Hash.new + +# Output Array of classes, Hash of Parameters +@out["classes"] = Array.new +@out["parameters"] = Hash.new + +# Add the motd_location class to the catalogs +@out["classes"] << "motd_location" +# And, add the accounts_ruby class to the catalog +@out["classes"] << "accounts_ruby" + +# Add a location parameter +@out["parameters"]["enc_location"] = "Florida" + +# Store account information dynamically in the account_resources +# parameter. These values could come from LDAP, SQL, etc... +@out["parameters"]['account_resources'] = Hash.new + +# @out["parameters"]['account_resources']["localadmin"] = { +# "comment" => "Local Administrator", +# "home" => "/home/localadmin", +# "uid" => 600, +# "gid" => 600, +# "groups" => [ "sudo", "sudo_nopw", "ops" ], +# "shell" => "/bin/bash", +# "password" => "!!", +# } + +@out["parameters"]['account_resources']["alice"] = { + "comment" => "Alice", + "home" => "/home/alice", + "uid" => 601, + "gid" => 601, + "groups" => [ "sudo", "sudo_nopw", "devel" ], + "shell" => "/bin/bash", + "password" => "!!", +} + +@out["parameters"]['account_resources']["bob"] = { + "comment" => "Bob", + "home" => "/home/bob", + "uid" => 602, + "gid" => 602, + "groups" => [ "sudo", "sudo_nopw", "ops" ], + "shell" => "/bin/zsh", + "password" => "!!", +} + +puts @out.to_yaml + diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/.gitignore b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/.gitignore new file mode 100644 index 0000000..42a59a4 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/.gitignore @@ -0,0 +1,2 @@ +pkg/ +metadata.json diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/CHANGELOG b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/CHANGELOG new file mode 100644 index 0000000..39dd040 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/CHANGELOG @@ -0,0 +1,2 @@ +2011-06-16 Jeff McCune - 0.0.3 +Initial release under puppetlabs diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/LICENSE b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/LICENSE new file mode 100644 index 0000000..57bc88a --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/Modulefile b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/Modulefile new file mode 100644 index 0000000..4e78cfb --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/Modulefile @@ -0,0 +1,11 @@ +name 'puppetlabs-ntp' +version '0.0.3' +source 'git://github.com/puppetlabs/puppetlabs-ntp' +author 'Puppet Labs' +license 'Apache Version 2.0' +summary 'NTP Module' +description 'NTP Module for Debian, Ubuntu, CentOS, RHEL, OEL' +project_page 'http://github.com/puppetlabs/puppetlabs-ntp' + +## Add dependencies, if any: +dependency 'puppetlabs/stdlib', '>= 0.1.6' diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/README.markdown b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/README.markdown new file mode 100644 index 0000000..15bac43 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/README.markdown @@ -0,0 +1,11 @@ +# NTP # + +Manage the NTP service. + +This module has been built and tested using Puppet 2.6.x + +# Platforms # + + * Enterprise Linux 5 + * Ubuntu 10.04 Lucid + diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/files/README.markdown b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/files/README.markdown new file mode 100644 index 0000000..be52188 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/files/README.markdown @@ -0,0 +1,22 @@ +Files +===== + +Puppet comes with both a client and server for copying files around. The file +serving function is provided as part of the central Puppet daemon, +puppetmasterd, and the client function is used through the source attribute of +file objects. Learn more at +http://projects.puppetlabs.com/projects/puppet/wiki/File_Serving_Configuration + +You can use managed files like this: + + class myclass { + package { mypackage: ensure => latest } + service { myservice: ensure => running } + file { "/etc/myfile": + source => "puppet://$servername/modules/mymodule/myfile" + } + } + +The files are searched for in: + + $modulepath/mymodule/files/myfile diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/facter/README.markdown b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/facter/README.markdown new file mode 100644 index 0000000..2b96273 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/facter/README.markdown @@ -0,0 +1,22 @@ +Facter +====== + +Define facts in this directory. + +Sometimes you need to be able to write conditional expressions based +on site-specific data that just isn’t available via Facter. The +solution may be to add a fact to Facter. These additional facts can +then be distributed to Puppet clients and are available for use in +manifests. Learn more at +http://projects.puppetlabs.com/projects/puppet/wiki/Adding_Facts + +File paths should match the fact name; for example, a fact +`hardware_platform`, defined like this: + + Facter.add("hardware_platform") do + setcode do + %x{/bin/uname -i}.chomp + end + end + +Should be found in `hardware_platform.rb` in this directory. diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/parser/functions/README.markdown b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/parser/functions/README.markdown new file mode 100644 index 0000000..15d7495 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/parser/functions/README.markdown @@ -0,0 +1,17 @@ +Functions +========= + +Define functions in this directory. + +File paths should match the function name; for example, a function +`myfunction`, defined like this: + + Puppet::Parser::Functions::newfunction( + :myfunction, + :type => :statement, + :doc => "Documentation here." + ) do |vals| + # ... + end + +Should be found in `myfunction.rb` in this directory. diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/provider/README.markdown b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/provider/README.markdown new file mode 100644 index 0000000..27aa1a9 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/provider/README.markdown @@ -0,0 +1,14 @@ +Providers +========= + +Define providers under this directory. + +File paths should match the resource type name and provider name; for +example, a provider `myprovider` for a resource type `mytype`, defined like this: + + Puppet::Type.type(:mytype).provide(:myprovider) do + desc "Documentation here" + # ... + end + +Should be found in `mytype/myprovider.rb` under this directory. diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/type/README.markdown b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/type/README.markdown new file mode 100644 index 0000000..7a169c7 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/lib/puppet/type/README.markdown @@ -0,0 +1,14 @@ +Resource Types +============== + +Define resource types in this directory. + +Filenames should match the resource type name; for example, a resource +type `mytype`, defined like this: + + Puppet::Type.newtype(:mytype) do + @doc = "Documentation here." + # ... + end + +Should be found in `mytype.rb` diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/manifests/README.markdown b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/manifests/README.markdown new file mode 100644 index 0000000..bbf645a --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/manifests/README.markdown @@ -0,0 +1,28 @@ +Manifests +========= + +Module manifest files belong in this directory. + +`init.pp` defines how the module will carry out its tasks in this file. + +Add additional definitions in this directory. Their file paths should match the +definition name; for example, a definition `mydefinition`, defined like this: + + # Definition: mydefinition + # + # This is the mydefinition in the mymodule module. + # + # Parameters: + # + # Actions: + # + # Requires: + # + # Sample Usage: + # + # [Remember: No empty lines between comments and class definition] + define mydefinition { + # ... + } + +Should be found in `mydefinition.pp` in this directory. diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/manifests/init.pp b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/manifests/init.pp new file mode 100644 index 0000000..ee655f7 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/manifests/init.pp @@ -0,0 +1,113 @@ +# Class: ntp +# +# This module manages the ntp service. +# +# Jeff McCune +# 2011-02-23 +# +# Tested platforms: +# - Debian 6.0 Squeeze +# - CentOS 5.4 +# +# Parameters: +# +# $servers = [ "0.debian.pool.ntp.org iburst", +# "1.debian.pool.ntp.org iburst", +# "2.debian.pool.ntp.org iburst", +# "3.debian.pool.ntp.org iburst", ] +# +# Actions: +# +# Installs, configures, and manages the ntp service. +# +# Requires: +# +# Sample Usage: +# +# class { "ntp": +# servers => [ 'time.apple.com' ], +# autoupdate => false, +# } +# +# [Remember: No empty lines between comments and class definition] +class ntp($servers="UNSET", + $ensure="running", + $autoupdate=false +) { + + if ! ($ensure in [ "running", "stopped" ]) { + fail("ensure parameter must be running or stopped") + } + + if $autoupdate == true { + $package_ensure = latest + } elsif $autoupdate == false { + $package_ensure = present + } else { + fail("autoupdate parameter must be true or false") + } + + case $operatingsystem { + debian, ubuntu: { + $supported = true + $pkg_name = [ "ntp" ] + $svc_name = "ntp" + $config = "/etc/ntp.conf" + $config_tpl = "ntp.conf.debian.erb" + if ($servers == "UNSET") { + $servers_real = [ "0.debian.pool.ntp.org iburst", + "1.debian.pool.ntp.org iburst", + "2.debian.pool.ntp.org iburst", + "3.debian.pool.ntp.org iburst", ] + } else { + $servers_real = $servers + } + } + centos, redhat, oel: { + $supported = true + $pkg_name = [ "ntp" ] + $svc_name = "ntpd" + $config = "/etc/ntp.conf" + $config_tpl = "ntp.conf.el.erb" + if ($servers == "UNSET") { + $servers_real = [ "0.centos.pool.ntp.org", + "1.centos.pool.ntp.org", + "2.centos.pool.ntp.org", ] + } else { + $servers_real = $servers + } + } + default: { + $supported = false + notify { "${module_name}_unsupported": + message => "The ${module_name} module is not supported on ${operatingsystem}", + } + } + } + + if ($supported == true) { + + package { $pkg_name: + ensure => $package_ensure, + } + + file { $config: + ensure => file, + owner => 0, + group => 0, + mode => 0644, + content => template("${module_name}/${config_tpl}"), + require => Package[$pkg_name], + } + + service { "ntp": + ensure => $ensure, + name => $svc_name, + hasstatus => true, + hasrestart => true, + subscribe => [ Package[$pkg_name], File[$config] ], + } + + } + +} diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/README.markdown b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/README.markdown new file mode 100644 index 0000000..286d341 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/README.markdown @@ -0,0 +1,7 @@ +Specs +===== + +The Puppet project uses RSpec for testing. + +For more information on RSpec, see http://rspec.info/ + diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/spec.opts b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/spec.opts new file mode 100644 index 0000000..91cd642 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/spec.opts @@ -0,0 +1,6 @@ +--format +s +--colour +--loadby +mtime +--backtrace diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/spec_helper.rb b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/spec_helper.rb new file mode 100644 index 0000000..a4aeeae --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/spec_helper.rb @@ -0,0 +1,18 @@ +require 'pathname' +dir = Pathname.new(__FILE__).parent +$LOAD_PATH.unshift(dir, dir + 'lib', dir + '../lib') + +require 'mocha' +require 'puppet' +gem 'rspec', '=1.2.9' +require 'spec/autorun' + +Spec::Runner.configure do |config| + config.mock_with :mocha +end + +# We need this because the RAL uses 'should' as a method. This +# allows us the same behaviour but with a different method name. +class Object + alias :must :should +end diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/unit/puppet/provider/README.markdown b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/unit/puppet/provider/README.markdown new file mode 100644 index 0000000..7025850 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/unit/puppet/provider/README.markdown @@ -0,0 +1,4 @@ +Provider Specs +============== + +Define specs for your providers under this directory. diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/unit/puppet/type/README.markdown b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/unit/puppet/type/README.markdown new file mode 100644 index 0000000..1ee19ac --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/spec/unit/puppet/type/README.markdown @@ -0,0 +1,4 @@ +Resource Type Specs +=================== + +Define specs for your resource types in this directory. diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/templates/README.markdown b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/templates/README.markdown new file mode 100644 index 0000000..575bbea --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/templates/README.markdown @@ -0,0 +1,23 @@ +Templates +========= + +Puppet supports templates and templating via ERB, which is part of the Ruby +standard library and is used for many other projects including Ruby on Rails. +Templates allow you to manage the content of template files, for example +configuration files that cannot yet be managed as a Puppet type. Learn more at +http://projects.puppetlabs.com/projects/puppet/wiki/Puppet_Templating + +You can use templates like this: + + class myclass { + package { mypackage: ensure => latest } + service { myservice: ensure => running } + file { "/etc/myfile": + content => template("mymodule/myfile.erb") + } + } + +The templates are searched for in: + + $templatedir/mymodule/myfile.erb + $modulepath/mymodule/templates/myfile.erb diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/templates/ntp.conf.debian.erb b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/templates/ntp.conf.debian.erb new file mode 100644 index 0000000..f51414f --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/templates/ntp.conf.debian.erb @@ -0,0 +1,55 @@ +# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help + +driftfile /var/lib/ntp/ntp.drift + + +# Enable this if you want statistics to be logged. +#statsdir /var/log/ntpstats/ + +statistics loopstats peerstats clockstats +filegen loopstats file loopstats type day enable +filegen peerstats file peerstats type day enable +filegen clockstats file clockstats type day enable + + +# You do need to talk to an NTP server or two (or three). +#server ntp.your-provider.example + +# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will +# pick a different set every time it starts up. Please consider joining the +# pool: + +# Managed by puppet class { "ntp": servers => [ ... ] } +<% servers_real.each do |server| -%> +server <%= server %> +<% end -%> + +# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for +# details. The web page +# might also be helpful. +# +# Note that "restrict" applies to both servers and clients, so a configuration +# that might be intended to block requests from certain clients could also end +# up blocking replies from your own upstream servers. + +# By default, exchange time with everybody, but don't allow configuration. +restrict -4 default kod notrap nomodify nopeer noquery +restrict -6 default kod notrap nomodify nopeer noquery + +# Local users may interrogate the ntp server more closely. +restrict 127.0.0.1 +restrict ::1 + +# Clients from this (example!) subnet have unlimited access, but only if +# cryptographically authenticated. +#restrict 192.168.123.0 mask 255.255.255.0 notrust + + +# If you want to provide time to your local subnet, change the next line. +# (Again, the address is an example only.) +#broadcast 192.168.123.255 + +# If you want to listen to time broadcasts on your local subnet, de-comment the +# next lines. Please do this only if you trust everybody on the network! +#disable auth +#broadcastclient diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/templates/ntp.conf.el.erb b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/templates/ntp.conf.el.erb new file mode 100644 index 0000000..db2aa9c --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/templates/ntp.conf.el.erb @@ -0,0 +1,52 @@ +# Permit time synchronization with our time source, but do not +# permit the source to query or modify the service on this system. +restrict default kod nomodify notrap nopeer noquery +restrict -6 default kod nomodify notrap nopeer noquery + +# Permit all access over the loopback interface. This could +# be tightened as well, but to do so would effect some of +# the administrative functions. +restrict 127.0.0.1 +restrict -6 ::1 + +# Hosts on local network are less restricted. +#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap + +# Use public servers from the pool.ntp.org project. +# Please consider joining the pool (http://www.pool.ntp.org/join.html). + +# Managed by puppet class { "ntp": servers => [ ... ] } +<% servers_real.each do |server| -%> +server <%= server %> +<% end -%> + +#broadcast 192.168.1.255 key 42 # broadcast server +#broadcastclient # broadcast client +#broadcast 224.0.1.1 key 42 # multicast server +#multicastclient 224.0.1.1 # multicast client +#manycastserver 239.255.254.254 # manycast server +#manycastclient 239.255.254.254 key 42 # manycast client + +# Undisciplined Local Clock. This is a fake driver intended for backup +# and when no outside source of synchronized time is available. +server 127.127.1.0 # local clock +fudge 127.127.1.0 stratum 10 + +# Drift file. Put this in a directory which the daemon can write to. +# No symbolic links allowed, either, since the daemon updates the file +# by creating a temporary in the same directory and then rename()'ing +# it to the file. +driftfile /var/lib/ntp/drift + +# Key file containing the keys and key identifiers used when operating +# with symmetric key cryptography. +keys /etc/ntp/keys + +# Specify the key identifiers which are trusted. +#trustedkey 4 8 42 + +# Specify the key identifier to use with the ntpdc utility. +#requestkey 8 + +# Specify the key identifier to use with the ntpq utility. +#controlkey 8 diff --git a/Pro Puppet/source/chapter08/puppet_module_tool/ntp/tests/init.pp b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/tests/init.pp new file mode 100644 index 0000000..e6d9b53 --- /dev/null +++ b/Pro Puppet/source/chapter08/puppet_module_tool/ntp/tests/init.pp @@ -0,0 +1,11 @@ +node default { + + notify { 'enduser-before': } + notify { 'enduser-after': } + + class { 'ntp': + require => Notify['enduser-before'], + before => Notify['enduser-after'], + } + +} diff --git a/Pro Puppet/source/chapter08/rubydsl/autosign.conf b/Pro Puppet/source/chapter08/rubydsl/autosign.conf new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/Pro Puppet/source/chapter08/rubydsl/autosign.conf @@ -0,0 +1 @@ +* diff --git a/Pro Puppet/source/chapter08/rubydsl/manifests/site.pp b/Pro Puppet/source/chapter08/rubydsl/manifests/site.pp new file mode 100644 index 0000000..dd5fbcc --- /dev/null +++ b/Pro Puppet/source/chapter08/rubydsl/manifests/site.pp @@ -0,0 +1,3 @@ +node default { + +} diff --git a/Pro Puppet/source/chapter08/rubydsl/modules/accounts_ruby/manifests/init.rb b/Pro Puppet/source/chapter08/rubydsl/modules/accounts_ruby/manifests/init.rb new file mode 100644 index 0000000..b43e396 --- /dev/null +++ b/Pro Puppet/source/chapter08/rubydsl/modules/accounts_ruby/manifests/init.rb @@ -0,0 +1,55 @@ +# Define a new accounts_ruby class. This is equivalent to: +# class accounts_ruby { ... } +hostclass :accounts_ruby do + + # Bring the accounts resources defined in the ENC into a local + # Ruby variable. + accounts = scope.lookupvar("account_resources") + + # Perform a sanity check on the data provided by the ENC. + raise Puppet::Error, + "account_resources must be a Hash" unless accounts.kind_of?(Hash) + + # First declare groups required by the accounts. These groups may be + # referenced in /etc/sudoers to grant sudo access and access without + # a password entry. + group([:sudo, :sudo_nopw], :ensure => "present") + + # Iterate over each account + # The Hash key will be stored in the local title variable + # The value of the hash entry will be stored in parameters + # The parameters are the resource parameters for each user account. + accounts.each do |title, parameters| + + # Some more sanity checking on the data passed in from the ENC. + raise Puppet::Error, + "account_resources[#{title}] must be a Hash" unless parameters.kind_of?(Hash) + + # Manage the home directory of this account with a file resource. + file(parameters["home"], + :ensure => "directory", + :owner => title, + :group => title, + :mode => 0700) + + # Each account should have a group of the same name. + group(title, + :ensure => "present", + :gid => parameters["gid"]) + + # Declare the user resource with the parameters for this account. + user(title, + :ensure => "present", + :uid => parameters["uid"], + :gid => parameters["gid"], + :comment => parameters["comment"], + :groups => parameters["groups"], + :shell => parameters["shell"], + :password => parameters["password"], + :home => parameters["home"], + :managehome => false) + + end + +end + diff --git a/Pro Puppet/source/chapter08/rubydsl/modules/motd_location/manifests/init.rb b/Pro Puppet/source/chapter08/rubydsl/modules/motd_location/manifests/init.rb new file mode 100644 index 0000000..54c1d76 --- /dev/null +++ b/Pro Puppet/source/chapter08/rubydsl/modules/motd_location/manifests/init.rb @@ -0,0 +1,30 @@ +# Message of the Day class implemented in the Ruby DSL +hostclass :motd_location do + + # Lookup the enc_location parameter set by the ENC + # Assign it to the location variable in Ruby + location = scope.lookupvar("enc_location") + # Set a Ruby String variable to represent the contents + # of the message of the day file + motd_content = "This system is in: #{location}\n" + + # Declare a file resource using Ruby syntax + # This is equivalent to the Puppet Syntax: + # file { motd: + # ensure => "file", + # path => "/etc/motd", + # content => $motd_content, + # owner => 0, + # group => 0, + # mode => 0644, + # } + file("motd", + :ensure => "file", + :path => "/etc/motd", + :content => motd_content, + :owner => 0, + :group => 0, + :mode => 0644) + +end + diff --git a/Pro Puppet/source/chapter08/rubydsl/puppet.conf b/Pro Puppet/source/chapter08/rubydsl/puppet.conf new file mode 100644 index 0000000..050f5b0 --- /dev/null +++ b/Pro Puppet/source/chapter08/rubydsl/puppet.conf @@ -0,0 +1,21 @@ +[main] + daemonize = false + vardir = /jeff/.puppet/var + ssldir = $vardir/ssl + manifestdir = $confdir/manifests + manifest = $confdir/manifests/site.pp + archive_files = true + server = hypervisor + certname = heif + certdnsnames = heif:hypervisor:www:danu-wire:parent + node_terminus = exec + external_nodes = $confdir/resources_enc.rb + +[agent] + report = true + test = true + +[master] + reports = store,http + reporturl = http://demo2:3000/reports/upload + diff --git a/Pro Puppet/source/chapter08/rubydsl/resources_enc.rb b/Pro Puppet/source/chapter08/rubydsl/resources_enc.rb new file mode 100644 index 0000000..d7a94d9 --- /dev/null +++ b/Pro Puppet/source/chapter08/rubydsl/resources_enc.rb @@ -0,0 +1,49 @@ +#!/usr/bin/env ruby +# + +# Load the YAML library in ruby. Provide the to_yaml method for all +# Ruby objects. +require 'yaml' + +# The output hash. Must contain the "parameters" and "classes" key. +# See: http://docs.puppetlabs.com/guides/external_nodes.html +@out = Hash.new + +# Output Array of classes, Hash of Parameters +@out["classes"] = Array.new +@out["parameters"] = Hash.new + +# Add the motd_location class to the catalogs +@out["classes"] << "motd_location" +# And, add the accounts_ruby class to the catalog +@out["classes"] << "accounts_ruby" + +# Add a location parameter +@out["parameters"]["enc_location"] = "Florida" + +# Store account information dynamically in the account_resources +# parameter. These values could come from LDAP, SQL, etc... +@out["parameters"]['account_resources'] = Hash.new + +@out["parameters"]['account_resources']["alice"] = { + "comment" => "Alice", + "home" => "/home/alice", + "uid" => 601, + "gid" => 601, + "groups" => [ "sudo", "sudo_nopw", "devel" ], + "shell" => "/bin/bash", + "password" => "!!", +} + +@out["parameters"]['account_resources']["bob"] = { + "comment" => "Bob", + "home" => "/home/bob", + "uid" => 602, + "gid" => 602, + "groups" => [ "sudo", "sudo_nopw", "ops" ], + "shell" => "/bin/zsh", + "password" => "!!", +} + +puts @out.to_yaml + diff --git a/Pro Puppet/source/chapter09/summary.rb b/Pro Puppet/source/chapter09/summary.rb new file mode 100644 index 0000000..2117bdf --- /dev/null +++ b/Pro Puppet/source/chapter09/summary.rb @@ -0,0 +1,20 @@ +require 'puppet' + +Puppet::Reports.register_report(:summary) do + + desc <<-DESC + Send summary report information to the report directory." + DESC + + def process + client = self.host + summary = self.summary + dir = File.join(Puppet[:reportdir], client) + client = self.host + file = "summary.txt" + destination = File.join(dir, file) + File.open(destination,"w") do |f| + f.write(summary) + end + end +end diff --git a/Pro Puppet/source/chapter10/facter/home.rb b/Pro Puppet/source/chapter10/facter/home.rb new file mode 100644 index 0000000..7c09a3e --- /dev/null +++ b/Pro Puppet/source/chapter10/facter/home.rb @@ -0,0 +1,5 @@ +Facter.add("home") do + setcode do + ENV['HOME'] + end +end diff --git a/Pro Puppet/source/chapter10/facter/networks.rb b/Pro Puppet/source/chapter10/facter/networks.rb new file mode 100644 index 0000000..a7afa5e --- /dev/null +++ b/Pro Puppet/source/chapter10/facter/networks.rb @@ -0,0 +1,20 @@ +netname = nil +netaddr = nil +test = {} + + File.open("/etc/networks").each do |line| + netname = $1 and netaddr = $2 if line =~ /^(\w+.?\w+)\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/ + if netname != nil && netaddr != nil + test["network_" + netname] = netaddr + netname = nil + netaddr = nil + end + end + + test.each { |name,fact| + Facter.add(name) do + setcode do + fact + end + end + } diff --git a/Pro Puppet/source/chapter10/facter/timezone.rb b/Pro Puppet/source/chapter10/facter/timezone.rb new file mode 100644 index 0000000..fbd1e4a --- /dev/null +++ b/Pro Puppet/source/chapter10/facter/timezone.rb @@ -0,0 +1,9 @@ +Facter.add("timezone") do + setcode do + if Facter.value(:operatingsystem) =~ /Debian|Ubuntu/ + File.readlines("/etc/timezone").to_a.last + else + tz = Time.new.zone + end + end +end diff --git a/Pro Puppet/source/chapter10/puppet/functions/sha512.rb b/Pro Puppet/source/chapter10/puppet/functions/sha512.rb new file mode 100644 index 0000000..85f39f1 --- /dev/null +++ b/Pro Puppet/source/chapter10/puppet/functions/sha512.rb @@ -0,0 +1,7 @@ +Puppet::Parser::Functions::newfunction(:sha512, :type => :rvalue, :doc => "Returns a SHA1 hash value from a provided string.") do |args| + + require 'sha1' + + Digest::SHA512.hexdigest(args[0]) + +end diff --git a/Pro Puppet/source/chapter10/puppet/types/httpauth/provider/httpauth.rb b/Pro Puppet/source/chapter10/puppet/types/httpauth/provider/httpauth.rb new file mode 100644 index 0000000..bc94fe8 --- /dev/null +++ b/Pro Puppet/source/chapter10/puppet/types/httpauth/provider/httpauth.rb @@ -0,0 +1,59 @@ +begin + require 'webrick' +rescue + Puppet.warning "You need WEBrick installed to manage HTTP Authentication files." +end + +Puppet::Type.type(:httpauth).provide(:httpauth) do + desc "Manage HTTP Basic and Digest authentication files" + + def create + # Create a user in the file we opened in the mech method + @htauth.set_passwd(resource[:realm], resource[:name], resource[:password]) + @htauth.flush + end + + def destroy + # Delete a user in the file we opened in the mech method + @htauth.delete_passwd(resource[:realm], resource[:name]) + @htauth.flush + end + + def exists? + # Check if the file exists at all + if File.exists?(resource[:file]) + # If it does exist open the file + mech(resource[:file]) + + # Check if the user exists in the file + cp = @htauth.get_passwd(resource[:realm], resource[:name], false) + + # Check if the current password matches the proposed password + return check_passwd(resource[:realm], resource[:name], resource[:password], cp) + else + # If the file doesn't exist then create it + File.new(resource[:file], "w") + mech(resource[:file]) + return false + end + end + + # Open the password file + def mech(file) + if resource[:mechanism] == :digest + @htauth = WEBrick::HTTPAuth::Htdigest.new(file) + elsif resource[:mechanism] == :basic + @htauth = WEBrick::HTTPAuth::Htpasswd.new(file) + end + end + + # Check password matches + def check_passwd(realm, user, password, cp) + if resource[:mechanism] == :digest + WEBrick::HTTPAuth::DigestAuth.make_passwd(realm, user, password) == cp + elsif resource[:mechanism] == :basic + # Can't ask webbrick as it uses a random seed + password.crypt(cp[0,2]) == cp + end + end +end diff --git a/Pro Puppet/source/chapter10/puppet/types/httpauth/type/httpauth.rb b/Pro Puppet/source/chapter10/puppet/types/httpauth/type/httpauth.rb new file mode 100644 index 0000000..d03a104 --- /dev/null +++ b/Pro Puppet/source/chapter10/puppet/types/httpauth/type/httpauth.rb @@ -0,0 +1,56 @@ +Puppet::Type.newtype(:httpauth) do + @doc = "Manage HTTP Basic or Digest password files." + + " httpauth { 'user': " + + " file => '/path/to/password/file', " + + " password => 'password', " + + " mechanism => basic, " + + " ensure => present, " + + " } " + + ensurable do + newvalue(:present) do + provider.create + end + + newvalue(:absent) do + provider.destroy + end + + defaultto :present + end + + newparam(:name) do + desc "The name of the user to be managed." + + isnamevar + end + + newparam(:file) do + desc "The HTTP password file to be managed. If it doesn't exist it is created." + end + + newparam(:password) do + desc "The password in plaintext." + + end + + newparam(:realm) do + desc "The realm - defaults to nil and mainly used for Digest authentication." + + defaultto "nil" + end + + newparam(:mechanism) do + desc "The authentication mechanism to use - either basic or digest. Default to basic." + + newvalues(:basic, :digest) + + defaultto :basic + end + + # Ensure a password is always specified + validate do + raise Puppet::Error, "You must specify a password for the user." unless @parameters.include?(:password) + end + +end diff --git a/Pro Puppet/source/chapter10/puppet/types/repo/provider/git.rb b/Pro Puppet/source/chapter10/puppet/types/repo/provider/git.rb new file mode 100644 index 0000000..1ec613e --- /dev/null +++ b/Pro Puppet/source/chapter10/puppet/types/repo/provider/git.rb @@ -0,0 +1,20 @@ +require 'fileutils' +Puppet::Type.type(:repo).provide(:git) do + + desc "Provides Git support for the repo provider" + + commands :gitcmd => "git" + + def create + gitcmd "clone", resource[:name], resource[:path] + end + + def destroy + FileUtils.rm_rf resource[:path] + end + + def exists? + File.directory? resource[:path] + end + +end diff --git a/Pro Puppet/source/chapter10/puppet/types/repo/provider/svn.rb b/Pro Puppet/source/chapter10/puppet/types/repo/provider/svn.rb new file mode 100644 index 0000000..7202c21 --- /dev/null +++ b/Pro Puppet/source/chapter10/puppet/types/repo/provider/svn.rb @@ -0,0 +1,18 @@ +Puppet::Type.type(:repo).provide(:svn) do + desc "Provides Subversion support for the repo type" + + commands :svncmd => "svn" + commands :svnadmin => "svnadmin" + + def create + svncmd "checkout", resource[:name], resource[:path] + end + + def destroy + FileUtils.rm_rf resource[:path] + end + + def exists? + File.directory? resource[:path] + end +end diff --git a/Pro Puppet/source/chapter10/puppet/types/repo/type/repo.rb b/Pro Puppet/source/chapter10/puppet/types/repo/type/repo.rb new file mode 100644 index 0000000..a529399 --- /dev/null +++ b/Pro Puppet/source/chapter10/puppet/types/repo/type/repo.rb @@ -0,0 +1,29 @@ +Puppet::Type.newtype(:repo) do + @doc = "Manage repos" + ensurable + + newparam(:source) do + desc "The repo source" + + validate do |value| + if value =~ /^git/ + resource[:provider] = :git + else + resource[:provider] = :svn + end + end + + isnamevar + end + + newparam(:path) do + desc "Destination path" + + validate do |value| + unless value =~ /^\/[a-z0-9]+/ + raise ArgumentError , "%s is not a valid file path" % value + end + end + end +end + diff --git a/Pro Puppet/source/chapter10/puppet/types/shells/provider/parsed.rb b/Pro Puppet/source/chapter10/puppet/types/shells/provider/parsed.rb new file mode 100644 index 0000000..87f32d0 --- /dev/null +++ b/Pro Puppet/source/chapter10/puppet/types/shells/provider/parsed.rb @@ -0,0 +1,13 @@ +require 'puppet/provider/parsedfile' + +shells = "/etc/shells" + +Puppet::Type.type(:shells).provide(:parsed, :parent => Puppet::Provider::ParsedFile, :default_target => shells, :filetype => :flat) do + + desc "The shells provider that uses the ParsedFile class" + + text_line :comment, :match => /^#/; + text_line :blank, :match => /^\s*$/; + + record_line :parsed, :fields => %w{name} +end diff --git a/Pro Puppet/source/chapter10/puppet/types/shells/type/shells.rb b/Pro Puppet/source/chapter10/puppet/types/shells/type/shells.rb new file mode 100644 index 0000000..aee410c --- /dev/null +++ b/Pro Puppet/source/chapter10/puppet/types/shells/type/shells.rb @@ -0,0 +1,24 @@ +Puppet::Type.newtype(:shells) do + @doc = "Manage the contents of /etc/shells + shells { "/bin/newshell": + ensure => present, + }" + +ensurable + +newparam(:shell) do + desc "The shell to manage" + isnamevar +end + +newproperty(:target) do + desc "Location of the shells file" + defaultto { + if @resource.class.defaultprovider.ancestors.include? (Puppet::Provider::ParsedFile) + @resource.class.defaultprovider.default_target + else + nil + end + } + end +end diff --git a/Pro Puppet/source/chapter11/README.markdown b/Pro Puppet/source/chapter11/README.markdown new file mode 100644 index 0000000..2f47bbb --- /dev/null +++ b/Pro Puppet/source/chapter11/README.markdown @@ -0,0 +1,4 @@ +There is no source code for Chapter 11. Please see the mcollective-plugins +project for examples of MCollective agent plugins. + + * [https://github.com/puppetlabs/mcollective-plugins](https://github.com/puppetlabs/mcollective-plugins) diff --git a/README.md b/README.md new file mode 100644 index 0000000..5a2a1b8 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +#Apress Source Code + +This repository accompanies [*Pro Puppet*](http://www.apress.com/9781430230571) by James Turnbull and Jeffrey McCune (Apress, 2011). + +![Cover image](9781430230571.jpg) + +Download the files as a zip using the green button, or clone the repository to your machine using Git. + +##Releases + +Release v1.0 corresponds to the code in the published book, without corrections or updates. + +##Contributions + +See the file Contributing.md for more information on how you can contribute to this repository. diff --git a/contributing.md b/contributing.md new file mode 100644 index 0000000..f6005ad --- /dev/null +++ b/contributing.md @@ -0,0 +1,14 @@ +# Contributing to Apress Source Code + +Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. + +## How to Contribute + +1. Make sure you have a GitHub account. +2. Fork the repository for the relevant book. +3. Create a new branch on which to make your change, e.g. +`git checkout -b my_code_contribution` +4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. +5. Submit a pull request. + +Thank you for your contribution! \ No newline at end of file