From e35fca3d367a6294123a0d9a2c077f4db7dfe809 Mon Sep 17 00:00:00 2001 From: varac Date: Thu, 12 May 2016 13:59:13 +0200 Subject: [feat] catch abnormal proc termination in syslog Sometimes a floating point exception or segfault of a process results in systemd restarting it, we want to recognize this from the syslog i.e.: systemd[1]: pixelated-server.service: main process exited, code=killed, status=8/FPE systemd[1]: Unit pixelated-server.service entered failed state. - Related: https://github.com/pixelated/pixelated-user-agent/issues/683 --- puppet/modules/site_check_mk/files/agent/logwatch/syslog_tail.cfg | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/syslog_tail.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/syslog_tail.cfg index 71395c50..7daf0cac 100644 --- a/puppet/modules/site_check_mk/files/agent/logwatch/syslog_tail.cfg +++ b/puppet/modules/site_check_mk/files/agent/logwatch/syslog_tail.cfg @@ -15,3 +15,7 @@ # 401 Unauthorized error logged by webapp and possible other # applications C Unauthorized +# catch abnormal termination of processes (due to segfault/fpe +# signals etc). +# see https://github.com/pixelated/pixelated-user-agent/issues/683 + C systemd.*: main process exited, code=killed, status= -- cgit v1.2.3 From 112e8e98bca4a11a068cc771e41d4b819da4ef52 Mon Sep 17 00:00:00 2001 From: varac Date: Thu, 28 Apr 2016 13:48:06 +0200 Subject: [lint] make future parser happy --- puppet/modules/site_nagios/manifests/server.pp | 2 +- puppet/modules/site_openvpn/manifests/server_config.pp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_nagios/manifests/server.pp b/puppet/modules/site_nagios/manifests/server.pp index aa9b956e..6537124d 100644 --- a/puppet/modules/site_nagios/manifests/server.pp +++ b/puppet/modules/site_nagios/manifests/server.pp @@ -59,7 +59,7 @@ class site_nagios::server inherits nagios::base { include site_webapp::common_vhost include apache::module::headers - File ['nagios_htpasswd'] { + File['nagios_htpasswd'] { source => undef, content => "nagiosadmin:${nagiosadmin_pw}", mode => '0640', diff --git a/puppet/modules/site_openvpn/manifests/server_config.pp b/puppet/modules/site_openvpn/manifests/server_config.pp index 6decc665..15e6fb38 100644 --- a/puppet/modules/site_openvpn/manifests/server_config.pp +++ b/puppet/modules/site_openvpn/manifests/server_config.pp @@ -30,7 +30,7 @@ # auth SHA1 # # dkg: For HMAC digest to authenticate packets, we just want SHA256. OpenVPN lists -# a number of “digest” with names like “RSA-SHA256”, but this are legacy and +# a number of "digest" with names like "RSA-SHA256", but this are legacy and # should be avoided. # # elijah: i am not so sure that the digest algo matters for 'auth' option, because @@ -40,14 +40,14 @@ # cipher AES-128-CBC # # dkg: For the choice of cipher, we need to select an algorithm and a -# cipher mode. OpenVPN defaults to Blowfish, which is a fine algorithm — but +# cipher mode. OpenVPN defaults to Blowfish, which is a fine algorithm - but # our control channel is already relying on AES not being broken; if the # control channel is cracked, then the key material for the tunnel is exposed, # and the choice of algorithm is moot. So it makes more sense to me to rely on # the same cipher here: AES128. As for the cipher mode, OFB seems cleaner to # me, but CBC is more well-tested, and the OpenVPN man page (at least as of -# version 2.2.1) says “CBC is recommended and CFB and OFB should be considered -# advanced modes.” +# version 2.2.1) says "CBC is recommended and CFB and OFB should be considered +# advanced modes." # # note: the default is BF-CBC (blowfish) # -- cgit v1.2.3 From 3e63ce3c71620433dc135959b2743aa010b28fe1 Mon Sep 17 00:00:00 2001 From: varac Date: Tue, 17 May 2016 12:52:57 +0200 Subject: update submodules so "rake test" doesnt complain anymore --- puppet/modules/apache | 2 +- puppet/modules/backupninja | 2 +- puppet/modules/bundler | 2 +- puppet/modules/couchdb | 2 +- puppet/modules/nagios | 2 +- puppet/modules/rubygems | 2 +- puppet/modules/tor | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/apache b/puppet/modules/apache index 117bed9a..415e9504 160000 --- a/puppet/modules/apache +++ b/puppet/modules/apache @@ -1 +1 @@ -Subproject commit 117bed9a9263c21d253d86b667eb165948efdc24 +Subproject commit 415e9504f99dca3ccaa4dfd389dde24ad9d0e01c diff --git a/puppet/modules/backupninja b/puppet/modules/backupninja index 49751354..5268a87c 160000 --- a/puppet/modules/backupninja +++ b/puppet/modules/backupninja @@ -1 +1 @@ -Subproject commit 497513547be79f9d3c8e96f1650ec43ee634b277 +Subproject commit 5268a87c329f895017f8ea6c6abc377a4f9a6a77 diff --git a/puppet/modules/bundler b/puppet/modules/bundler index b4a4a843..bacec3e0 160000 --- a/puppet/modules/bundler +++ b/puppet/modules/bundler @@ -1 +1 @@ -Subproject commit b4a4a8434616247156e59b860b47cc6256ead8d1 +Subproject commit bacec3e072649be4ade56f7df8506b46ae9c5166 diff --git a/puppet/modules/couchdb b/puppet/modules/couchdb index 40d2289f..76ff149a 160000 --- a/puppet/modules/couchdb +++ b/puppet/modules/couchdb @@ -1 +1 @@ -Subproject commit 40d2289f8e10625cd45fdccdf492b5fb6490e66d +Subproject commit 76ff149a095023611c05bbb00157d06f87b07c05 diff --git a/puppet/modules/nagios b/puppet/modules/nagios index 68dab01a..e6fee3c7 160000 --- a/puppet/modules/nagios +++ b/puppet/modules/nagios @@ -1 +1 @@ -Subproject commit 68dab01a85996e14efcccf856b623a2caf257823 +Subproject commit e6fee3c731f68ccf8b6add8ada2162c7ad2b8407 diff --git a/puppet/modules/rubygems b/puppet/modules/rubygems index e704c9fe..510a3693 160000 --- a/puppet/modules/rubygems +++ b/puppet/modules/rubygems @@ -1 +1 @@ -Subproject commit e704c9fe1c40fea5b10fe3ca2b4f5de825341cc6 +Subproject commit 510a3693eab5dc78ed27d3728ee4d3b12334ea12 diff --git a/puppet/modules/tor b/puppet/modules/tor index 8c936c16..9981a70f 160000 --- a/puppet/modules/tor +++ b/puppet/modules/tor @@ -1 +1 @@ -Subproject commit 8c936c166b6da1ebd0e8d95e56ceee5167357d63 +Subproject commit 9981a70f7ba1f9e4fe33e4eb46654295287c1fc1 -- cgit v1.2.3 From 18a3a1953802021afccf7105876de7839f152189 Mon Sep 17 00:00:00 2001 From: varac Date: Fri, 20 May 2016 08:13:11 +0200 Subject: [feat] Automatic couchdb db compaction Automatic background couchdb db compaction frees a huge amount of diskspace. - Resolves: #8118 --- puppet/modules/site_couchdb/files/local.ini | 89 +---------------------------- 1 file changed, 3 insertions(+), 86 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_couchdb/files/local.ini b/puppet/modules/site_couchdb/files/local.ini index 22aa0177..b921a927 100644 --- a/puppet/modules/site_couchdb/files/local.ini +++ b/puppet/modules/site_couchdb/files/local.ini @@ -1,91 +1,8 @@ -; CouchDB Configuration Settings +; Puppet modified file !! ; Custom settings should be made in this file. They will override settings ; in default.ini, but unlike changes made to default.ini, this file won't be ; overwritten on server upgrade. -[couchdb] -;max_document_size = 4294967296 ; bytes - -[httpd] -;port = 5984 -;bind_address = 127.0.0.1 -; Options for the MochiWeb HTTP server. -;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] -; For more socket options, consult Erlang's module 'inet' man page. -;socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}] - -; Uncomment next line to trigger basic-auth popup on unauthorized requests. -;WWW-Authenticate = Basic realm="administrator" - -; Uncomment next line to set the configuration modification whitelist. Only -; whitelisted values may be changed via the /_config URLs. To allow the admin -; to change this value over HTTP, remember to include {httpd,config_whitelist} -; itself. Excluding it from the list would require editing this file to update -; the whitelist. -;config_whitelist = [{httpd,config_whitelist}, {log,level}, {etc,etc}] - -[httpd_global_handlers] -;_google = {couch_httpd_proxy, handle_proxy_req, <<"http://www.google.com">>} - -# futon is enabled by default on bigcouch in default.ini -# we need to find another way to disable futon, it won't work disabling it here -# enable futon -#_utils = {couch_httpd_misc_handlers, handle_utils_dir_req, "/usr/share/couchdb/www"} -# disable futon -#_utils = {couch_httpd_misc_handlers, handle_welcome_req, <<"Welcome, Futon is disabled!">>} - -[couch_httpd_auth] -; If you set this to true, you should also uncomment the WWW-Authenticate line -; above. If you don't configure a WWW-Authenticate header, CouchDB will send -; Basic realm="server" in order to prevent you getting logged out. -; require_valid_user = false - -[log] -;level = debug - -[os_daemons] -; For any commands listed here, CouchDB will attempt to ensure that -; the process remains alive while CouchDB runs as well as shut them -; down when CouchDB exits. -;foo = /path/to/command -with args - -[daemons] -; enable SSL support by uncommenting the following line and supply the PEM's below. -; the default ssl port CouchDB listens on is 6984 -;httpsd = {couch_httpd, start_link, [https]} - -[ssl] -;cert_file = /etc/couchdb/server_cert.pem -;key_file = /etc/couchdb/server_key.pem -;password = somepassword -; set to true to validate peer certificates -;verify_ssl_certificates = false -; Path to file containing PEM encoded CA certificates (trusted -; certificates used for verifying a peer certificate). May be omitted if -; you do not want to verify the peer. -;cacert_file = /full/path/to/cacertf -; The verification fun (optionnal) if not specidied, the default -; verification fun will be used. -;verify_fun = {Module, VerifyFun} -;ssl_certificate_max_depth = 1 -; To enable Virtual Hosts in CouchDB, add a vhost = path directive. All requests to -; the Virual Host will be redirected to the path. In the example below all requests -; to http://example.com/ are redirected to /database. -; If you run CouchDB on a specific port, include the port number in the vhost: -; example.com:5984 = /database - -[vhosts] -;example.com = /database/ - -[update_notification] -;unique notifier name=/full/path/to/exe -with "cmd line arg" - -; To create an admin account uncomment the '[admins]' section below and add a -; line in the format 'username = password'. When you next start CouchDB, it -; will change the password to a hash (so that your passwords don't linger -; around in plain-text files). You can add more admin accounts with more -; 'username = password' lines. Don't forget to restart CouchDB after -; changing this. -;[admins] -;admin = mysecretpassword +[compactions] +_default = [{db_fragmentation, "70%"}, {view_fragmentation, "60%"}, {from, "03:00"}, {to, "05:00"}] -- cgit v1.2.3 From 46af641b65a530a6afc238d554d0b71e5d99f9d5 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 31 May 2016 13:45:36 -0400 Subject: Disable puppet-agent daemon from running. The agent wakes up every two minutes and tries to connect to the default server, failing with a certificate warning. We don't use the agent, so we can safely disable it (#8032) Change-Id: I707f42b59205993325431aba283552b1b73a0ad1 --- puppet/modules/site_config/manifests/default.pp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_config/manifests/default.pp b/puppet/modules/site_config/manifests/default.pp index 256de1a1..9bc8c30d 100644 --- a/puppet/modules/site_config/manifests/default.pp +++ b/puppet/modules/site_config/manifests/default.pp @@ -7,8 +7,9 @@ class site_config::default { include site_config::params include site_config::setup - # default class, used by all hosts + service { 'puppet': ensure => stopped } + # default class, used by all hosts include lsb, git # configure sysctl parameters -- cgit v1.2.3 From 4d92b3a758e16fa2c7ee34a06272bd64a5c038ad Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 31 May 2016 15:39:59 -0400 Subject: Reduce check_mk timeouts (#7807). check_mk operations can take a long time (such as when doing a re-inventory using "check_mk -II") when multiple hosts are down. This decreases the connect timeout to 5 seconds. Change-Id: I1eac5f14bad2afc2ffc4cbf8c950c24b052a0d6e --- puppet/modules/site_check_mk/templates/use_ssh.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_check_mk/templates/use_ssh.mk b/puppet/modules/site_check_mk/templates/use_ssh.mk index 55269536..25f951e0 100644 --- a/puppet/modules/site_check_mk/templates/use_ssh.mk +++ b/puppet/modules/site_check_mk/templates/use_ssh.mk @@ -1,6 +1,6 @@ # http://mathias-kettner.de/checkmk_datasource_programs.html datasource_programs = [ <% @nagios_hosts.sort.each do |name,config| %> - ( "ssh -l root -i /etc/check_mk/.ssh/id_rsa -p <%=config['ssh_port']%> <%=config['domain_internal']%> check_mk_agent", [ "<%=config['domain_internal']%>" ], ),<%- end -%> + ( "ssh -o ConnectTimeout=5 -l root -i /etc/check_mk/.ssh/id_rsa -p <%=config['ssh_port']%> <%=config['domain_internal']%> check_mk_agent", [ "<%=config['domain_internal']%>" ], ),<%- end -%> ] -- cgit v1.2.3 From 8ce5fe27d53e0e1f5f36a9de812069a823d59222 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 1 Jun 2016 13:08:38 -0700 Subject: ensure soledad server has access to x509::variables --- puppet/modules/soledad/manifests/server.pp | 1 + 1 file changed, 1 insertion(+) (limited to 'puppet/modules') diff --git a/puppet/modules/soledad/manifests/server.pp b/puppet/modules/soledad/manifests/server.pp index 8674f421..6cf806d0 100644 --- a/puppet/modules/soledad/manifests/server.pp +++ b/puppet/modules/soledad/manifests/server.pp @@ -17,6 +17,7 @@ class soledad::server { $sources = hiera('sources') + include x509::variables include site_config::x509::cert include site_config::x509::key include site_config::x509::ca -- cgit v1.2.3 From 5b2cb9a14bf5735e61e148c21496677c8458bd63 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 1 Jun 2016 13:08:38 -0700 Subject: ensure soledad server has access to x509::variables --- puppet/modules/soledad/manifests/server.pp | 1 + 1 file changed, 1 insertion(+) (limited to 'puppet/modules') diff --git a/puppet/modules/soledad/manifests/server.pp b/puppet/modules/soledad/manifests/server.pp index 8674f421..6cf806d0 100644 --- a/puppet/modules/soledad/manifests/server.pp +++ b/puppet/modules/soledad/manifests/server.pp @@ -17,6 +17,7 @@ class soledad::server { $sources = hiera('sources') + include x509::variables include site_config::x509::cert include site_config::x509::key include site_config::x509::ca -- cgit v1.2.3 From 954a746947b7395fe3252e9df371da30546ee762 Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 2 Jun 2016 12:42:10 -0400 Subject: Fix opendkim milter location (#8163). The unix socket method for connecting to the milter was incorrectly reverted, this puts it back to how it should be. Change-Id: Ifde669c920a249c782f577a112f4d45e60a889a2 --- puppet/modules/site_postfix/manifests/mx.pp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_postfix/manifests/mx.pp b/puppet/modules/site_postfix/manifests/mx.pp index c269946b..e743118e 100644 --- a/puppet/modules/site_postfix/manifests/mx.pp +++ b/puppet/modules/site_postfix/manifests/mx.pp @@ -69,10 +69,10 @@ class site_postfix::mx { value => '$alias_maps'; # setup clamav and opendkim on smtpd 'smtpd_milters': - value => 'unix:/run/clamav/milter.ctl,inet:localhost:8891'; + value => 'unix:/run/clamav/milter.ctl,unix:/run/opendkim/opendkim.sock'; # setup opendkim for smtp (non-smtpd) outgoing mail 'non_smtpd_milters': - value => 'inet:localhost:8891'; + value => 'unix:/run/opendkim/opendkim.sock'; 'milter_default_action': value => 'accept'; # Make sure that the right values are set, these could be set to different -- cgit v1.2.3 From 2e5657647ed790eec8bd679c47eb57bd4eaed621 Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 3 Jun 2016 12:02:09 -0700 Subject: auto run bundler when needed for site_static --- puppet/modules/site_static/manifests/location.pp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_static/manifests/location.pp b/puppet/modules/site_static/manifests/location.pp index d116de2f..ab2b7494 100644 --- a/puppet/modules/site_static/manifests/location.pp +++ b/puppet/modules/site_static/manifests/location.pp @@ -23,6 +23,19 @@ define site_static::location($path, $format, $source) { } } + if ($format == 'rack') { + # Run bundler if there is a Gemfile + exec { 'bundler_update': + cwd => $file_path, + command => '/bin/bash -c "/usr/bin/bundle check --path vendor/bundle || /usr/bin/bundle install --path vendor/bundle --without test development debug"', + unless => '/usr/bin/bundle check --path vendor/bundle', + onlyif => 'test -f Gemfile', + user => 'www-data', + timeout => 600, + require => [Class['bundler::install'], Class['site_config::ruby::dev']]; + } + } + vcsrepo { $file_path: ensure => present, force => true, -- cgit v1.2.3 From edde26f34f7fea1756fdf58b352329e61787b882 Mon Sep 17 00:00:00 2001 From: Christoph Kluenter Date: Mon, 6 Jun 2016 10:14:50 +0200 Subject: debian packages don't know AllowSupplementaryGroups if this is set in the config, the deamons do not start anymore. From the debian changelog: clamav (0.99.2+dfsg-0+deb8u1) stable; urgency=medium * Import new Upstream. * Drop AllowSupplementaryGroups option which is default now (Closes: #822444). --- puppet/modules/clamav/templates/clamav-milter.conf.erb | 1 - 1 file changed, 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/clamav/templates/clamav-milter.conf.erb b/puppet/modules/clamav/templates/clamav-milter.conf.erb index 9bf7099e..50b4c620 100644 --- a/puppet/modules/clamav/templates/clamav-milter.conf.erb +++ b/puppet/modules/clamav/templates/clamav-milter.conf.erb @@ -4,7 +4,6 @@ FixStaleSocket true User clamav MilterSocketGroup clamav MilterSocketMode 666 -AllowSupplementaryGroups true ReadTimeout 120 Foreground false PidFile /var/run/clamav/clamav-milter.pid -- cgit v1.2.3 From c0cbf928c057d299f533a2a8b61bb54cc6ba5974 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 7 Jun 2016 15:26:01 -0400 Subject: refresh_stunnel sometimes doesn't run (#8168). It turns out that in some corner-cases, the script is not called: (1) start the deploy, create files in /var/lib/puppet/stunnel4/config (2) halt puppet before apply finishes (3) re-run deploy in this scenario, next time you run deploy, refresh_stunnel will never get called to populate /etc/stunnel, because the files in /var/lib/puppet/stunnel4/config haven't changed. This problem can be really confusing when it happens. To fix this, we just run refresh_stunnel every, it is pretty fast and the script has more complete logic for what to do than puppet, which has only an asymmetrical view on the situation. Change-Id: I9e5fad1d081c2fe07f3ac8f07cfb87d86b88f7c9 --- puppet/modules/stunnel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/stunnel b/puppet/modules/stunnel index 79e874c1..008777bd 160000 --- a/puppet/modules/stunnel +++ b/puppet/modules/stunnel @@ -1 +1 @@ -Subproject commit 79e874c1a86ad5c48c4e726a5d4c68bd879ce454 +Subproject commit 008777bd9837c87a8f501f36dbf2bd4f79c8c868 -- cgit v1.2.3 From 543e5108d6b50928cac3c7e031e6a96d5f664ee1 Mon Sep 17 00:00:00 2001 From: varac Date: Sat, 11 Jun 2016 15:27:45 +0200 Subject: Move custom functions to site_config module --- .../parser/functions/create_resources_hash_from.rb | 116 ++++++ .../lib/puppet/parser/functions/sorted_json.rb | 47 +++ .../lib/puppet/parser/functions/sorted_yaml.rb | 400 +++++++++++++++++++++ 3 files changed, 563 insertions(+) create mode 100644 puppet/modules/site_config/lib/puppet/parser/functions/create_resources_hash_from.rb create mode 100644 puppet/modules/site_config/lib/puppet/parser/functions/sorted_json.rb create mode 100644 puppet/modules/site_config/lib/puppet/parser/functions/sorted_yaml.rb (limited to 'puppet/modules') diff --git a/puppet/modules/site_config/lib/puppet/parser/functions/create_resources_hash_from.rb b/puppet/modules/site_config/lib/puppet/parser/functions/create_resources_hash_from.rb new file mode 100644 index 00000000..47d0df9c --- /dev/null +++ b/puppet/modules/site_config/lib/puppet/parser/functions/create_resources_hash_from.rb @@ -0,0 +1,116 @@ +# +# create_resources_hash_from.rb +# +# 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. +# + +module Puppet::Parser::Functions + newfunction(:create_resources_hash_from, :type => :rvalue, :doc => <<-EOS +Given: + A formatted string (to use as the resource name) + An array to loop through (because puppet cannot loop) + A hash defining the parameters for a resource + And optionally an hash of parameter names to add to the resource and an + associated formatted string that should be configured with the current + element of the loop array + +This function will return a hash of hashes that can be used with the +create_resources function. + +*Examples:* + $allowed_hosts = ['10.0.0.0/8', '192.168.0.0/24'] + $resource_name = "100 allow %s to apache on ports 80" + $my_resource_hash = { + 'proto' => 'tcp', + 'action' => 'accept', + 'dport' => 80 + } + $dynamic_parameters = { + 'source' => '%s' + } + + $created_resource_hash = create_resources_hash_from($resource_name, $allowed_hosts, $my_resource_hash, $dynamic_parameters) + +$created_resource_hash would equal: + { + '100 allow 10.0.0.0/8 to apache on ports 80' => { + 'proto' => 'tcp', + 'action' => 'accept', + 'dport' => 80, + 'source' => '10.0.0.0/8' + }, + '100 allow 192.168.0.0/24 to apache on ports 80' => { + 'proto' => 'tcp', + 'action' => 'accept', + 'dport' => 80, + 'source' => '192.168.0.0/24' + } + } + +$created_resource_hash could then be used with create_resources + + create_resources(firewall, $created_resource_hash) + +To create a bunch of resources in a way that would only otherwise be possible +with a loop of some description. + EOS + ) do |arguments| + + raise Puppet::ParseError, "create_resources_hash_from(): Wrong number of arguments " + + "given (#{arguments.size} for 3 or 4)" if arguments.size < 3 or arguments.size > 4 + + formatted_string = arguments[0] + + unless formatted_string.is_a?(String) + raise(Puppet::ParseError, 'create_resources_hash_from(): first argument must be a string') + end + + loop_array = arguments[1] + + unless loop_array.is_a?(Array) + raise(Puppet::ParseError, 'create_resources_hash_from(): second argument must be an array') + end + + resource_hash = arguments[2] + unless resource_hash.is_a?(Hash) + raise(Puppet::ParseError, 'create_resources_hash_from(): third argument must be a hash') + end + + if arguments.size == 4 + dynamic_parameters = arguments[3] + unless dynamic_parameters.is_a?(Hash) + raise(Puppet::ParseError, 'create_resources_hash_from(): fourth argument must be a hash') + end + end + + result = {} + + loop_array.each do |i| + my_resource_hash = resource_hash.clone + if dynamic_parameters + dynamic_parameters.each do |param, value| + if my_resource_hash.member?(param) + raise(Puppet::ParseError, "create_resources_hash_from(): dynamic_parameter '#{param}' already exists in resource hash") + end + my_resource_hash[param] = sprintf(value,[i]) + end + end + result[sprintf(formatted_string,[i])] = my_resource_hash + end + + result + end +end + +# vim: set ts=2 sw=2 et : +# encoding: utf-8 diff --git a/puppet/modules/site_config/lib/puppet/parser/functions/sorted_json.rb b/puppet/modules/site_config/lib/puppet/parser/functions/sorted_json.rb new file mode 100644 index 00000000..605da00e --- /dev/null +++ b/puppet/modules/site_config/lib/puppet/parser/functions/sorted_json.rb @@ -0,0 +1,47 @@ +# +# Written by Gavin Mogan, from https://gist.github.com/halkeye/2287885 +# Put in the public domain by the author. +# + +require 'json' + +def sorted_json(obj) + case obj + when String, Fixnum, Float, TrueClass, FalseClass, NilClass + return obj.to_json + when Array + arrayRet = [] + obj.each do |a| + arrayRet.push(sorted_json(a)) + end + return "[" << arrayRet.join(',') << "]"; + when Hash + ret = [] + obj.keys.sort.each do |k| + ret.push(k.to_json << ":" << sorted_json(obj[k])) + end + return "{" << ret.join(",") << "}"; + else + raise Exception("Unable to handle object of type <%s>" % obj.class.to_s) + end +end + +module Puppet::Parser::Functions + newfunction(:sorted_json, :type => :rvalue, :doc => <<-EOS +This function takes data, outputs making sure the hash keys are sorted + +*Examples:* + + sorted_json({'key'=>'value'}) + +Would return: {'key':'value'} + EOS + ) do |arguments| + raise(Puppet::ParseError, "sorted_json(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + json = arguments[0] + return sorted_json(json) + end +end + diff --git a/puppet/modules/site_config/lib/puppet/parser/functions/sorted_yaml.rb b/puppet/modules/site_config/lib/puppet/parser/functions/sorted_yaml.rb new file mode 100644 index 00000000..46cd46ce --- /dev/null +++ b/puppet/modules/site_config/lib/puppet/parser/functions/sorted_yaml.rb @@ -0,0 +1,400 @@ +# encoding: UTF-8 +# +# provides sorted_yaml() function, using Ya2YAML. +# see https://github.com/afunai/ya2yaml +# + +class Ya2YAML + # + # Author:: Akira FUNAI + # Copyright:: Copyright (c) 2006-2010 Akira FUNAI + # License:: MIT License + # + + def initialize(opts = {}) + options = opts.dup + options[:indent_size] = 2 if options[:indent_size].to_i <= 0 + options[:minimum_block_length] = 0 if options[:minimum_block_length].to_i <= 0 + options.update( + { + :printable_with_syck => true, + :escape_b_specific => true, + :escape_as_utf8 => true, + } + ) if options[:syck_compatible] + + @options = options + end + + def _ya2yaml(obj) + #raise 'set $KCODE to "UTF8".' if (RUBY_VERSION < '1.9.0') && ($KCODE != 'UTF8') + if (RUBY_VERSION < '1.9.0') + $KCODE = 'UTF8' + end + '--- ' + emit(obj, 1) + "\n" + rescue SystemStackError + raise ArgumentError, "ya2yaml can't handle circular references" + end + + private + + def emit(obj, level) + case obj + when Array + if (obj.length == 0) + '[]' + else + indent = "\n" + s_indent(level - 1) + ### + ### NOTE: a minor modification to normal Ya2YAML... + ### We want arrays to be output in sorted order, not just + ### Hashes. + ### + #obj.collect {|o| + # indent + '- ' + emit(o, level + 1) + #}.join('') + obj.sort {|a,b| a.to_s <=> b.to_s}.collect {|o| + indent + '- ' + emit(o, level + 1) + }.join('') + end + when Hash + if (obj.length == 0) + '{}' + else + indent = "\n" + s_indent(level - 1) + hash_order = @options[:hash_order] + if (hash_order && level == 1) + hash_keys = obj.keys.sort {|x, y| + x_order = hash_order.index(x) ? hash_order.index(x) : Float::MAX + y_order = hash_order.index(y) ? hash_order.index(y) : Float::MAX + o = (x_order <=> y_order) + (o != 0) ? o : (x.to_s <=> y.to_s) + } + elsif @options[:preserve_order] + hash_keys = obj.keys + else + hash_keys = obj.keys.sort {|x, y| x.to_s <=> y.to_s } + end + hash_keys.collect {|k| + key = emit(k, level + 1) + if ( + is_one_plain_line?(key) || + key =~ /\A(#{REX_BOOL}|#{REX_FLOAT}|#{REX_INT}|#{REX_NULL})\z/x + ) + indent + key + ': ' + emit(obj[k], level + 1) + else + indent + '? ' + key + + indent + ': ' + emit(obj[k], level + 1) + end + }.join('') + end + when NilClass + '~' + when String + emit_string(obj, level) + when TrueClass, FalseClass + obj.to_s + when Fixnum, Bignum, Float + obj.to_s + when Date + obj.to_s + when Time + offset = obj.gmtoff + off_hm = sprintf( + '%+.2d:%.2d', + (offset / 3600.0).to_i, + (offset % 3600.0) / 60 + ) + u_sec = (obj.usec != 0) ? sprintf(".%.6d", obj.usec) : '' + obj.strftime("%Y-%m-%d %H:%M:%S#{u_sec} #{off_hm}") + when Symbol + '!ruby/symbol ' + emit_string(obj.to_s, level) + when Range + '!ruby/range ' + obj.to_s + when Regexp + '!ruby/regexp ' + obj.inspect + else + case + when obj.is_a?(Struct) + struct_members = {} + obj.each_pair{|k, v| struct_members[k.to_s] = v } + '!ruby/struct:' + obj.class.to_s.sub(/^(Struct::(.+)|.*)$/, '\2') + ' ' + + emit(struct_members, level + 1) + else + # serialized as a generic object + object_members = {} + obj.instance_variables.each{|k, v| + object_members[k.to_s.sub(/^@/, '')] = obj.instance_variable_get(k) + } + '!ruby/object:' + obj.class.to_s + ' ' + + emit(object_members, level + 1) + end + end + end + + def emit_string(str, level) + (is_string, is_printable, is_one_line, is_one_plain_line) = string_type(str) + if is_string + if is_printable + if is_one_plain_line + emit_simple_string(str, level) + else + (is_one_line || str.length < @options[:minimum_block_length]) ? + emit_quoted_string(str, level) : + emit_block_string(str, level) + end + else + emit_quoted_string(str, level) + end + else + emit_base64_binary(str, level) + end + end + + def emit_simple_string(str, level) + str + end + + def emit_block_string(str, level) + str = normalize_line_break(str) + + indent = s_indent(level) + indentation_indicator = (str =~ /\A /) ? indent.size.to_s : '' + str =~ /(#{REX_NORMAL_LB}*)\z/ + chomping_indicator = case $1.length + when 0 + '-' + when 1 + '' + else + '+' + end + + str.chomp! + str.gsub!(/#{REX_NORMAL_LB}/) { + $1 + indent + } + '|' + indentation_indicator + chomping_indicator + "\n" + indent + str + end + + def emit_quoted_string(str, level) + str = yaml_escape(normalize_line_break(str)) + if (str.length < @options[:minimum_block_length]) + str.gsub!(/#{REX_NORMAL_LB}/) { ESCAPE_SEQ_LB[$1] } + else + str.gsub!(/#{REX_NORMAL_LB}$/) { ESCAPE_SEQ_LB[$1] } + str.gsub!(/(#{REX_NORMAL_LB}+)(.)/) { + trail_c = $3 + $1 + trail_c.sub(/([\t ])/) { ESCAPE_SEQ_WS[$1] } + } + indent = s_indent(level) + str.gsub!(/#{REX_NORMAL_LB}/) { + ESCAPE_SEQ_LB[$1] + "\\\n" + indent + } + end + '"' + str + '"' + end + + def emit_base64_binary(str, level) + indent = "\n" + s_indent(level) + base64 = [str].pack('m') + '!binary |' + indent + base64.gsub(/\n(?!\z)/, indent) + end + + def string_type(str) + if str.respond_to?(:encoding) && (!str.valid_encoding? || str.encoding == Encoding::ASCII_8BIT) + return false, false, false, false + end + (ucs_codes = str.unpack('U*')) rescue ( + # ArgumentError -> binary data + return false, false, false, false + ) + if ( + @options[:printable_with_syck] && + str =~ /\A#{REX_ANY_LB}* | #{REX_ANY_LB}*\z|#{REX_ANY_LB}{2}\z/ + ) + # detour Syck bug + return true, false, nil, false + end + ucs_codes.each {|ucs_code| + return true, false, nil, false unless is_printable?(ucs_code) + } + return true, true, is_one_line?(str), is_one_plain_line?(str) + end + + def is_printable?(ucs_code) + # YAML 1.1 / 4.1.1. + ( + [0x09, 0x0a, 0x0d, 0x85].include?(ucs_code) || + (ucs_code <= 0x7e && ucs_code >= 0x20) || + (ucs_code <= 0xd7ff && ucs_code >= 0xa0) || + (ucs_code <= 0xfffd && ucs_code >= 0xe000) || + (ucs_code <= 0x10ffff && ucs_code >= 0x10000) + ) && + !( + # treat LS/PS as non-printable characters + @options[:escape_b_specific] && + (ucs_code == 0x2028 || ucs_code == 0x2029) + ) + end + + def is_one_line?(str) + str !~ /#{REX_ANY_LB}(?!\z)/ + end + + def is_one_plain_line?(str) + # YAML 1.1 / 4.6.11. + str !~ /^([\-\?:,\[\]\{\}\#&\*!\|>'"%@`\s]|---|\.\.\.)/ && + str !~ /[:\#\s\[\]\{\},]/ && + str !~ /#{REX_ANY_LB}/ && + str !~ /^(#{REX_BOOL}|#{REX_FLOAT}|#{REX_INT}|#{REX_MERGE} + |#{REX_NULL}|#{REX_TIMESTAMP}|#{REX_VALUE})$/x + end + + def s_indent(level) + # YAML 1.1 / 4.2.2. + ' ' * (level * @options[:indent_size]) + end + + def normalize_line_break(str) + # YAML 1.1 / 4.1.4. + str.gsub(/(#{REX_CRLF}|#{REX_CR}|#{REX_NEL})/, "\n") + end + + def yaml_escape(str) + # YAML 1.1 / 4.1.6. + str.gsub(/[^a-zA-Z0-9]/u) {|c| + ucs_code, = (c.unpack('U') rescue [??]) + case + when ESCAPE_SEQ[c] + ESCAPE_SEQ[c] + when is_printable?(ucs_code) + c + when @options[:escape_as_utf8] + c.respond_to?(:bytes) ? + c.bytes.collect {|b| '\\x%.2x' % b }.join : + '\\x' + c.unpack('H2' * c.size).join('\\x') + when ucs_code == 0x2028 || ucs_code == 0x2029 + ESCAPE_SEQ_LB[c] + when ucs_code <= 0x7f + sprintf('\\x%.2x', ucs_code) + when ucs_code <= 0xffff + sprintf('\\u%.4x', ucs_code) + else + sprintf('\\U%.8x', ucs_code) + end + } + end + + module Constants + UCS_0X85 = [0x85].pack('U') # c285@UTF8 Unicode next line + UCS_0XA0 = [0xa0].pack('U') # c2a0@UTF8 Unicode non-breaking space + UCS_0X2028 = [0x2028].pack('U') # e280a8@UTF8 Unicode line separator + UCS_0X2029 = [0x2029].pack('U') # e280a9@UTF8 Unicode paragraph separator + + # non-break characters + ESCAPE_SEQ = { + "\x00" => '\\0', + "\x07" => '\\a', + "\x08" => '\\b', + "\x0b" => '\\v', + "\x0c" => '\\f', + "\x1b" => '\\e', + "\"" => '\\"', + "\\" => '\\\\', + } + + # non-breaking space + ESCAPE_SEQ_NS = { + UCS_0XA0 => '\\_', + } + + # white spaces + ESCAPE_SEQ_WS = { + "\x09" => '\\t', + " " => '\\x20', + } + + # line breaks + ESCAPE_SEQ_LB ={ + "\x0a" => '\\n', + "\x0d" => '\\r', + UCS_0X85 => '\\N', + UCS_0X2028 => '\\L', + UCS_0X2029 => '\\P', + } + + # regexps for line breaks + REX_LF = Regexp.escape("\x0a") + REX_CR = Regexp.escape("\x0d") + REX_CRLF = Regexp.escape("\x0d\x0a") + REX_NEL = Regexp.escape(UCS_0X85) + REX_LS = Regexp.escape(UCS_0X2028) + REX_PS = Regexp.escape(UCS_0X2029) + + REX_ANY_LB = /(#{REX_LF}|#{REX_CR}|#{REX_NEL}|#{REX_LS}|#{REX_PS})/ + REX_NORMAL_LB = /(#{REX_LF}|#{REX_LS}|#{REX_PS})/ + + # regexps for language-Independent types for YAML1.1 + REX_BOOL = / + y|Y|yes|Yes|YES|n|N|no|No|NO + |true|True|TRUE|false|False|FALSE + |on|On|ON|off|Off|OFF + /x + REX_FLOAT = / + [-+]?([0-9][0-9_]*)?\.[0-9.]*([eE][-+][0-9]+)? # (base 10) + |[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]* # (base 60) + |[-+]?\.(inf|Inf|INF) # (infinity) + |\.(nan|NaN|NAN) # (not a number) + /x + REX_INT = / + [-+]?0b[0-1_]+ # (base 2) + |[-+]?0[0-7_]+ # (base 8) + |[-+]?(0|[1-9][0-9_]*) # (base 10) + |[-+]?0x[0-9a-fA-F_]+ # (base 16) + |[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+ # (base 60) + /x + REX_MERGE = / + << + /x + REX_NULL = / + ~ # (canonical) + |null|Null|NULL # (English) + | # (Empty) + /x + REX_TIMESTAMP = / + [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] # (ymd) + |[0-9][0-9][0-9][0-9] # (year) + -[0-9][0-9]? # (month) + -[0-9][0-9]? # (day) + ([Tt]|[ \t]+)[0-9][0-9]? # (hour) + :[0-9][0-9] # (minute) + :[0-9][0-9] # (second) + (\.[0-9]*)? # (fraction) + (([ \t]*)Z|[-+][0-9][0-9]?(:[0-9][0-9])?)? # (time zone) + /x + REX_VALUE = / + = + /x + end + + include Constants +end + +module Puppet::Parser::Functions + newfunction(:sorted_yaml, + :type => :rvalue, + :doc => "This function outputs yaml, but ensures the keys are sorted." + ) do |arguments| + + if arguments.is_a?(Array) + if arguments.size != 1 + raise(Puppet::ParseError, "sorted_yaml(): Wrong number of arguments given (#{arguments.size} for 1)") + end + yaml = arguments.first + else + yaml = arguments + end + return Ya2YAML.new()._ya2yaml(yaml) + end +end -- cgit v1.2.3 From f4f278ea62751220790dfc7fae58ecdc5756c4b5 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 14 Jun 2016 10:02:40 -0400 Subject: update stunnel module for refresh_stunnel fixes Change-Id: I7675dbaba4d896a62dab9fcf4817092ea69f1298 --- puppet/modules/stunnel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/stunnel b/puppet/modules/stunnel index 008777bd..421c8e52 160000 --- a/puppet/modules/stunnel +++ b/puppet/modules/stunnel @@ -1 +1 @@ -Subproject commit 008777bd9837c87a8f501f36dbf2bd4f79c8c868 +Subproject commit 421c8e527d57fd4d1221dbd341394d954cd38314 -- cgit v1.2.3 From 3aba84e808035a02c35bb64a04daccc5ab03e5db Mon Sep 17 00:00:00 2001 From: Micah Anderson Date: Tue, 14 Jun 2016 10:46:20 -0400 Subject: Ensure stunnel package, service and default ordering. --- puppet/modules/stunnel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/stunnel b/puppet/modules/stunnel index 421c8e52..4056d79a 160000 --- a/puppet/modules/stunnel +++ b/puppet/modules/stunnel @@ -1 +1 @@ -Subproject commit 421c8e527d57fd4d1221dbd341394d954cd38314 +Subproject commit 4056d79a2e07b7178cbbdb1576aa6f5ccd1d9e83 -- cgit v1.2.3 From bf6d0fe1b74910026d577b80e5894f22c6edfde7 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 14 Jun 2016 12:37:10 -0400 Subject: make sure required x509 bits are there before stunnel is started Change-Id: I772c3b6e489e3c1848c45c6bcaa240324fc88928 --- puppet/modules/site_stunnel/manifests/client.pp | 6 +++++- puppet/modules/site_stunnel/manifests/servers.pp | 6 +++++- puppet/modules/stunnel | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_stunnel/manifests/client.pp b/puppet/modules/site_stunnel/manifests/client.pp index c9e034f1..de9febd4 100644 --- a/puppet/modules/site_stunnel/manifests/client.pp +++ b/puppet/modules/site_stunnel/manifests/client.pp @@ -39,7 +39,11 @@ define site_stunnel::client ( debuglevel => $debuglevel, sslversion => 'TLSv1', syslog => 'no', - output => $logfile; + output => $logfile, + require => [ + Class['Site_config::X509::Key'], + Class['Site_config::X509::Cert'], + Class['Site_config::X509::Ca'] ]; } # define the log files so that we can purge the diff --git a/puppet/modules/site_stunnel/manifests/servers.pp b/puppet/modules/site_stunnel/manifests/servers.pp index e76d1e9d..3dc5dce6 100644 --- a/puppet/modules/site_stunnel/manifests/servers.pp +++ b/puppet/modules/site_stunnel/manifests/servers.pp @@ -39,7 +39,11 @@ define site_stunnel::servers ( debuglevel => $debuglevel, sslversion => 'TLSv1', syslog => 'no', - output => $logfile; + output => $logfile, + require => [ + Class['Site_config::X509::Key'], + Class['Site_config::X509::Cert'], + Class['Site_config::X509::Ca'] ]; } # allow incoming connections on $accept_port diff --git a/puppet/modules/stunnel b/puppet/modules/stunnel index 4056d79a..523612fb 160000 --- a/puppet/modules/stunnel +++ b/puppet/modules/stunnel @@ -1 +1 @@ -Subproject commit 4056d79a2e07b7178cbbdb1576aa6f5ccd1d9e83 +Subproject commit 523612fb6daff51837423619f5014e62dc835559 -- cgit v1.2.3 From 05c8afd886e31f7f46b07387ac8346b071f43e50 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 14 Jun 2016 12:51:08 -0400 Subject: switch to two-space soft tabs to fix lint error Change-Id: Ic12b243b195e40482a70dd70219212c3697899ba --- puppet/modules/site_stunnel/manifests/client.pp | 7 +++---- puppet/modules/site_stunnel/manifests/servers.pp | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_stunnel/manifests/client.pp b/puppet/modules/site_stunnel/manifests/client.pp index de9febd4..7c431c50 100644 --- a/puppet/modules/site_stunnel/manifests/client.pp +++ b/puppet/modules/site_stunnel/manifests/client.pp @@ -40,10 +40,9 @@ define site_stunnel::client ( sslversion => 'TLSv1', syslog => 'no', output => $logfile, - require => [ - Class['Site_config::X509::Key'], - Class['Site_config::X509::Cert'], - Class['Site_config::X509::Ca'] ]; + require => [ Class['Site_config::X509::Key'], + Class['Site_config::X509::Cert'], + Class['Site_config::X509::Ca'] ]; } # define the log files so that we can purge the diff --git a/puppet/modules/site_stunnel/manifests/servers.pp b/puppet/modules/site_stunnel/manifests/servers.pp index 3dc5dce6..37aaf5a6 100644 --- a/puppet/modules/site_stunnel/manifests/servers.pp +++ b/puppet/modules/site_stunnel/manifests/servers.pp @@ -40,10 +40,9 @@ define site_stunnel::servers ( sslversion => 'TLSv1', syslog => 'no', output => $logfile, - require => [ - Class['Site_config::X509::Key'], - Class['Site_config::X509::Cert'], - Class['Site_config::X509::Ca'] ]; + require => [ Class['Site_config::X509::Key'], + Class['Site_config::X509::Cert'], + Class['Site_config::X509::Ca'] ]; } # allow incoming connections on $accept_port -- cgit v1.2.3 From 12b00fbf578d88281d3a00f268ffeda460d383d8 Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 16 Jun 2016 11:39:11 -0400 Subject: Fix matching for cleanup check. The onlyif check was incorrectly specified in the original implementation in commit id: 15b83d88dcedab496a19cef57f11c5c8e091dd4a this inverts it so it is properly detected. Change-Id: I531e206fff1ca61780adcd195e1f917011e50fb4 --- puppet/modules/site_postfix/manifests/mx.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_postfix/manifests/mx.pp b/puppet/modules/site_postfix/manifests/mx.pp index e743118e..0b760eb4 100644 --- a/puppet/modules/site_postfix/manifests/mx.pp +++ b/puppet/modules/site_postfix/manifests/mx.pp @@ -96,7 +96,7 @@ class site_postfix::mx { # access the opendkim milter socket (#8020) exec { 'unset_cleanup_chroot': command => '/usr/sbin/postconf -F "cleanup/unix/chroot=n"', - onlyif => '/usr/sbin/postconf -h -F "cleanup/unix/chroot" | egrep -q ^n', + onlyif => '/usr/sbin/postconf -h -F "cleanup/unix/chroot" | egrep -qv ^n', notify => Service['postfix'], require => File['/etc/postfix/master.cf'] } -- cgit v1.2.3 From 293cdaee6db4a4d0b13a56fcd047819d60f38ce2 Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 16 Jun 2016 12:24:01 -0400 Subject: Disable the Trace method (#8195) The Trace method is enabled because of the Apache module, but it is not the default in Debian, and it should not be enabled, for more information see the following: https://www.kb.cert.org/vuls/id/867593 Change-Id: I06a06ae679dbf7049f26a017125b61e5e38f6268 --- puppet/modules/site_apache/files/conf.d/security | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_apache/files/conf.d/security b/puppet/modules/site_apache/files/conf.d/security index a5ae5bdc..fdcf6270 100644 --- a/puppet/modules/site_apache/files/conf.d/security +++ b/puppet/modules/site_apache/files/conf.d/security @@ -45,8 +45,8 @@ ServerSignature Off # # Set to one of: On | Off | extended # -#TraceEnable Off -TraceEnable On +TraceEnable Off +#TraceEnable On # Setting this header will prevent other sites from embedding pages from this # site as frames. This defends against clickjacking attacks. -- cgit v1.2.3 From 3df7a57d866cf1e6eda9bb9e3fe19c7387ec6c1d Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 21 Jun 2016 09:50:27 -0400 Subject: Fix hidden service static template (#8203). Change-Id: Iab9597f5f0336f66df9b73fea9d79c789cbb8302 --- puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb b/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb index 232b1577..697a7ff3 100644 --- a/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb +++ b/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb @@ -41,7 +41,7 @@ DocumentRoot "/srv/static/root/public" <% if scope.function_guess_apache_version([]) == '2.4' %> - AllowOverride None + AllowOverride FileInfo Indexes Options=All,MultiViews Require all granted <% end %> -- cgit v1.2.3 From 8b69bebad7fe00886705f0402d542c1f11fba7b0 Mon Sep 17 00:00:00 2001 From: varac Date: Mon, 27 Jun 2016 13:32:21 +0200 Subject: Lint and Document site_webapp::hidden_service --- puppet/modules/site_webapp/manifests/hidden_service.pp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_webapp/manifests/hidden_service.pp b/puppet/modules/site_webapp/manifests/hidden_service.pp index 72a2ce95..da2a5607 100644 --- a/puppet/modules/site_webapp/manifests/hidden_service.pp +++ b/puppet/modules/site_webapp/manifests/hidden_service.pp @@ -1,3 +1,4 @@ +# Configure tor hidden service for webapp class site_webapp::hidden_service { $tor = hiera('tor') $hidden_service = $tor['hidden_service'] @@ -8,7 +9,7 @@ class site_webapp::hidden_service { include apache::module::alias include apache::module::expires include apache::module::removeip - + include tor::daemon tor::daemon::hidden_service { 'webapp': ports => [ '80 127.0.0.1:80'] } @@ -40,7 +41,7 @@ class site_webapp::hidden_service { apache::module { 'status': ensure => present, conf_content => ' ' } # the access_compat module is required to enable Allow directives apache::module { 'access_compat': ensure => present } - + apache::vhost::file { 'hidden_service': content => template('site_apache/vhosts.d/hidden_service.conf.erb'); -- cgit v1.2.3 From b21a3e9126a1734b2cea975e57b5c9e8206f12fa Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 27 Jun 2016 15:49:30 -0700 Subject: Fix the permissions on the DOMAIN/provider.json file for static sites. --- .../templates/vhosts.d/hidden_service.conf.erb | 2 +- .../modules/site_config/manifests/remove/files.pp | 11 +++++++++++ puppet/modules/site_static/manifests/init.pp | 22 ++++++++++++++++++---- .../modules/site_static/templates/apache.conf.erb | 8 ++++++-- 4 files changed, 36 insertions(+), 7 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb b/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb index 697a7ff3..b34bd189 100644 --- a/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb +++ b/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb @@ -47,7 +47,7 @@ <% end %> AccessFileName .htaccess - Alias /provider.json /srv/leap/provider.json + Alias /provider.json /srv/static/public/provider.json Header set X-Minimum-Client-Version 0.5 diff --git a/puppet/modules/site_config/manifests/remove/files.pp b/puppet/modules/site_config/manifests/remove/files.pp index 41d6462e..3de8d695 100644 --- a/puppet/modules/site_config/manifests/remove/files.pp +++ b/puppet/modules/site_config/manifests/remove/files.pp @@ -11,7 +11,18 @@ class site_config::remove::files { + # + # Platform X removals + # + + tidy { + '/srv/leap/provider.json':; + } + + # # Platform 0.8 removals + # + tidy { '/etc/default/leap_mx':; '/etc/logrotate.d/mx':; diff --git a/puppet/modules/site_static/manifests/init.pp b/puppet/modules/site_static/manifests/init.pp index 4a722d62..8063d432 100644 --- a/puppet/modules/site_static/manifests/init.pp +++ b/puppet/modules/site_static/manifests/init.pp @@ -13,20 +13,34 @@ class site_static { $bootstrap = $static['bootstrap_files'] $tor = hiera('tor', false) + file { + '/srv/static/': + ensure => 'directory', + owner => 'root', + group => 'root', + mode => '0744'; + '/srv/static/public': + ensure => 'directory', + owner => 'root', + group => 'root', + mode => '0744'; + } + if $bootstrap['enabled'] { $bootstrap_domain = $bootstrap['domain'] $bootstrap_client = $bootstrap['client_version'] - file { '/srv/leap/provider.json': + file { '/srv/static/public/provider.json': content => $bootstrap['provider_json'], owner => 'www-data', group => 'www-data', - mode => '0444'; + mode => '0444', + notify => Service[apache]; } # It is important to always touch provider.json: the client needs to check x-min-client-version header, # but this is only sent when the file has been modified (otherwise 304 is sent by apache). The problem # is that changing min client version won't alter the content of provider.json, so we must touch it. - exec { '/bin/touch /srv/leap/provider.json': - require => File['/srv/leap/provider.json']; + exec { '/bin/touch /srv/static/public/provider.json': + require => File['/srv/static/public/provider.json']; } } diff --git a/puppet/modules/site_static/templates/apache.conf.erb b/puppet/modules/site_static/templates/apache.conf.erb index 6b969d1c..b3e5fc09 100644 --- a/puppet/modules/site_static/templates/apache.conf.erb +++ b/puppet/modules/site_static/templates/apache.conf.erb @@ -23,6 +23,10 @@ bootstrap_client = scope.lookupvar('site_static::bootstrap_client') -%> + + Require all granted + + ServerName <%= @domain %> ServerAlias www.<%= @domain %> @@ -46,7 +50,7 @@ #RewriteLogLevel 3 Include include.d/ssl_common.inc - + <%- if @tls_only -%> Header always set Strict-Transport-Security: "max-age=15768000;includeSubdomains" <%- end -%> @@ -63,7 +67,7 @@ AccessFileName .htaccess <%- if ([@aliases]+[@domain]).flatten.include?(bootstrap_domain) -%> - Alias /provider.json /srv/leap/provider.json + Alias /provider.json /srv/static/public/provider.json Header set X-Minimum-Client-Version <%= bootstrap_client['min'] %> -- cgit v1.2.3 From c7e0864ccb00c67f2dfe7cd8d5a1665c08dd6033 Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 23 Jun 2016 14:05:20 -0400 Subject: Make sure bind9 doesn't take over unbound (#8213). Change-Id: Icaab817870d005b7a854a3fb8c402705d0b2d77f --- puppet/modules/site_config/manifests/caching_resolver.pp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_config/manifests/caching_resolver.pp b/puppet/modules/site_config/manifests/caching_resolver.pp index 8bf465c1..59b135a3 100644 --- a/puppet/modules/site_config/manifests/caching_resolver.pp +++ b/puppet/modules/site_config/manifests/caching_resolver.pp @@ -2,10 +2,22 @@ class site_config::caching_resolver { tag 'leap_base' + # We need to make sure Package['bind9'] isn't installed because when it is, it + # keeps unbound from running. Some base debian installs will install bind9, + # and then start it, so unbound will never get properly started. So this will + # make sure bind9 is removed before. + package { 'bind9': + ensure => absent + } + file { [ '/etc/default/bind9', '/etc/bind/named.conf.options' ]: + ensure => absent + } + class { 'unbound': root_hints => false, anchor => false, ssl => false, + require => Package['bind9'], settings => { server => { verbosity => '1', -- cgit v1.2.3 From 9f2a4f859f42895969d96c25ac9941ff95a28d1f Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 23 Jun 2016 11:36:00 -0400 Subject: Reload tor if config or key is changed (#8210). Change-Id: I3d733b6645c804a5fb337ad4b8edc59a66ad50b5 --- puppet/modules/site_webapp/manifests/hidden_service.pp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_webapp/manifests/hidden_service.pp b/puppet/modules/site_webapp/manifests/hidden_service.pp index da2a5607..ffc9888d 100644 --- a/puppet/modules/site_webapp/manifests/hidden_service.pp +++ b/puppet/modules/site_webapp/manifests/hidden_service.pp @@ -25,14 +25,16 @@ class site_webapp::hidden_service { source => "/srv/leap/files/nodes/${::hostname}/tor.key", owner => 'debian-tor', group => 'debian-tor', - mode => '0600'; + mode => '0600', + notify => Service['tor']; '/var/lib/tor/webapp/hostname': ensure => present, content => $tor_domain, owner => 'debian-tor', group => 'debian-tor', - mode => '0600'; + mode => '0600', + notify => Service['tor']; } # it is necessary to zero out the config of the status module -- cgit v1.2.3 From 4cf9b7d34fce1c37d3b4bb16e62f078df642263b Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 23 Jun 2016 12:05:29 -0400 Subject: Stop tor from restarting on every deploy (#8211). We were creating the hidden service name without a newline, and then tor would be restarted and change the hidden service hostname file to have a newline, which would then require that the next deploy would change that file to not have a newline again. This fixes that problem by making the hostname have a newline so it matches what tor wants. Change-Id: I38f450684d557cf943ec94f2f8e19cda3aefdf66 --- puppet/modules/site_webapp/manifests/hidden_service.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_webapp/manifests/hidden_service.pp b/puppet/modules/site_webapp/manifests/hidden_service.pp index ffc9888d..d2662b65 100644 --- a/puppet/modules/site_webapp/manifests/hidden_service.pp +++ b/puppet/modules/site_webapp/manifests/hidden_service.pp @@ -30,7 +30,7 @@ class site_webapp::hidden_service { '/var/lib/tor/webapp/hostname': ensure => present, - content => $tor_domain, + content => "${tor_domain}\n", owner => 'debian-tor', group => 'debian-tor', mode => '0600', -- cgit v1.2.3 From 29d6b7dbbc3b9d8b11f0b215cad894fcfca9989c Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 23 Jun 2016 12:08:54 -0400 Subject: Make static tor hidden services work (#8212). When tor hidden services were enabled for static sites, only a very basic configuration was setup and it didn't take into account the different location configurations that can be configured for a static site. This commit resolves that by making a site_static::hidden_service class similar to the site_webapp::hidden_service class, and fixes up the apache vhost template to properly create the location blocks for the hidden service vhost. Change-Id: Ice3586f4173bd2d1bd3defca29d21c7403d5a03a --- .../templates/vhosts.d/hidden_service.conf.erb | 15 -------- .../site_static/manifests/hidden_service.pp | 37 ++++++++++++++++++ puppet/modules/site_static/manifests/init.pp | 20 +++++----- .../modules/site_static/templates/apache.conf.erb | 45 +++++++++++++++++++++- 4 files changed, 91 insertions(+), 26 deletions(-) create mode 100644 puppet/modules/site_static/manifests/hidden_service.pp (limited to 'puppet/modules') diff --git a/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb b/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb index b34bd189..1d19094e 100644 --- a/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb +++ b/puppet/modules/site_apache/templates/vhosts.d/hidden_service.conf.erb @@ -37,19 +37,4 @@ <% end -%> -<% if (defined? @services) and (@services.include? 'static') -%> - DocumentRoot "/srv/static/root/public" - <% if scope.function_guess_apache_version([]) == '2.4' %> - - AllowOverride FileInfo Indexes Options=All,MultiViews - Require all granted - - <% end %> - AccessFileName .htaccess - - Alias /provider.json /srv/static/public/provider.json - - Header set X-Minimum-Client-Version 0.5 - -<% end -%> diff --git a/puppet/modules/site_static/manifests/hidden_service.pp b/puppet/modules/site_static/manifests/hidden_service.pp new file mode 100644 index 00000000..f1f15f8e --- /dev/null +++ b/puppet/modules/site_static/manifests/hidden_service.pp @@ -0,0 +1,37 @@ +# create hidden service for static sites +class site_static::hidden_service { + + include tor::daemon + tor::daemon::hidden_service { 'static': ports => [ '80 127.0.0.1:80'] } + file { + '/var/lib/tor/webapp/': + ensure => directory, + owner => 'debian-tor', + group => 'debian-tor', + mode => '2700'; + + '/var/lib/tor/static/private_key': + ensure => present, + source => "/srv/leap/files/nodes/${::hostname}/tor.key", + owner => 'debian-tor', + group => 'debian-tor', + mode => '0600', + notify => Service['tor']; + + '/var/lib/tor/static/hostname': + ensure => present, + content => "${::site_static::tor_domain}\n", + owner => 'debian-tor', + group => 'debian-tor', + mode => '0600', + notify => Service['tor']; + } + + # it is necessary to zero out the config of the status module + # because we are configuring our own version that is unavailable + # over the hidden service (see: #7456 and #7776) + apache::module { 'status': ensure => present, conf_content => ' ' } + + include site_shorewall::tor +} + diff --git a/puppet/modules/site_static/manifests/init.pp b/puppet/modules/site_static/manifests/init.pp index 8063d432..4912fbab 100644 --- a/puppet/modules/site_static/manifests/init.pp +++ b/puppet/modules/site_static/manifests/init.pp @@ -7,11 +7,14 @@ class site_static { include site_config::x509::key include site_config::x509::ca_bundle - $static = hiera('static') - $domains = $static['domains'] - $formats = $static['formats'] - $bootstrap = $static['bootstrap_files'] - $tor = hiera('tor', false) + $static = hiera('static') + $domains = $static['domains'] + $formats = $static['formats'] + $bootstrap = $static['bootstrap_files'] + + $tor = hiera('tor', false) + $hidden_service = $tor['hidden_service'] + $tor_domain = "${hidden_service['address']}.onion" file { '/srv/static/': @@ -71,15 +74,14 @@ class site_static { } } - create_resources(site_static::domain, $domains) - if $tor { - $hidden_service = $tor['hidden_service'] if $hidden_service['active'] { - include site_webapp::hidden_service + include site_static::hidden_service } } + create_resources(site_static::domain, $domains) + include site_shorewall::defaults include site_shorewall::service::http include site_shorewall::service::https diff --git a/puppet/modules/site_static/templates/apache.conf.erb b/puppet/modules/site_static/templates/apache.conf.erb index b3e5fc09..2013e5ee 100644 --- a/puppet/modules/site_static/templates/apache.conf.erb +++ b/puppet/modules/site_static/templates/apache.conf.erb @@ -27,12 +27,52 @@ Require all granted +<%- if @tor -%> + + ServerName <%= @tor_domain %> + ServerAlias www.<%= @tor_domain %> + + + Header set X-Frame-Options "deny" + Header always unset X-Powered-By + Header always unset X-Runtime + + + DocumentRoot "/<%= @document_root %>/" + AccessFileName .htaccess + +<%- if ([@aliases]+[@domain]).flatten.include?(bootstrap_domain) -%> + Alias /provider.json /srv/leap/provider.json + + Header set X-Minimum-Client-Version <%= bootstrap_client['min'] %> + +<%- end -%> + +<%- if @apache_config -%> +<%= @apache_config.gsub(':percent:','%') %> +<%- end -%> + +<%- @locations && @locations.each do |name, location| -%> +<%- location_path = location['path'].gsub(%r{^/|/$}, '') -%> +<%- directory = location_directory(name, location) -%> +<%- local_vars = {'location_path'=>location_path, 'directory'=>directory, 'location'=>location, 'name'=>name} -%> +<%- template_path = File.join(File.dirname(__FILE__), location['format']) + '.erb' -%> +<%- break unless File.exists?(template_path) -%> + ## + ## <%= name %> (<%= location['format'] %>) + ## +<%= scope.function_templatewlv([template_path, local_vars]) %> +<%- end -%> +<%- end -%> + + ServerName <%= @domain %> ServerAlias www.<%= @domain %> <%- @aliases && @aliases.each do |domain_alias| -%> ServerAlias <%= domain_alias %> <%- end -%> + <%- if @tls_only -%> RewriteEngine On RewriteRule ^.*$ https://<%= @domain -%>%{REQUEST_URI} [R=permanent,L] @@ -50,13 +90,15 @@ #RewriteLogLevel 3 Include include.d/ssl_common.inc - + + <%- if @tls_only -%> Header always set Strict-Transport-Security: "max-age=15768000;includeSubdomains" <%- end -%> Header set X-Frame-Options "deny" Header always unset X-Powered-By Header always unset X-Runtime + SSLCertificateKeyFile /etc/x509/keys/<%= @domain %>.key SSLCertificateFile /etc/x509/certs/<%= @domain %>.crt @@ -88,5 +130,4 @@ ## <%= scope.function_templatewlv([template_path, local_vars]) %> <%- end -%> - -- cgit v1.2.3 From 8e0fdbb46761505b9188c9ea2a6c0df0c55ac458 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 28 Jun 2016 21:56:31 -0400 Subject: Fix for when tor is not an array. When tor is not configured, then its possible to get this error on deploy: Error: tor is not a hash or array when accessing it with hidden_service at /srv/leap/puppet/modules/site_static/manifests/init.pp:16 on node rewdevstatic1.rewire.org This commit only accesses the array when its enabled. Change-Id: Ia75ac7a51179da980966adba0cc614b9cd642b0c --- puppet/modules/site_static/manifests/init.pp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_static/manifests/init.pp b/puppet/modules/site_static/manifests/init.pp index 4912fbab..0acfc223 100644 --- a/puppet/modules/site_static/manifests/init.pp +++ b/puppet/modules/site_static/manifests/init.pp @@ -11,10 +11,7 @@ class site_static { $domains = $static['domains'] $formats = $static['formats'] $bootstrap = $static['bootstrap_files'] - $tor = hiera('tor', false) - $hidden_service = $tor['hidden_service'] - $tor_domain = "${hidden_service['address']}.onion" file { '/srv/static/': @@ -75,6 +72,8 @@ class site_static { } if $tor { + $hidden_service = $tor['hidden_service'] + $tor_domain = "${hidden_service['address']}.onion" if $hidden_service['active'] { include site_static::hidden_service } -- cgit v1.2.3 From d0ff379fe2a43d7968b8828c8b31af5254f6f85b Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 28 Jun 2016 13:16:47 -0400 Subject: Remove bigcouch (#8056) Change-Id: I0c6e27298c63bd37de1410985d054799818c22a4 --- .../files/agent/logwatch/bigcouch.cfg | 28 -- .../agent/nagios_plugins/check_unix_open_fds.pl | 322 --------------------- .../site_check_mk/manifests/agent/couchdb.pp | 20 +- .../manifests/agent/couchdb/bigcouch.pp | 49 ---- .../site_check_mk/manifests/agent/couchdb/plain.pp | 23 -- .../site_config/manifests/remove/bigcouch.pp | 27 ++ puppet/modules/site_couchdb/files/runit_config | 6 - puppet/modules/site_couchdb/manifests/bigcouch.pp | 50 ---- .../site_couchdb/manifests/bigcouch/add_nodes.pp | 8 - .../site_couchdb/manifests/bigcouch/compaction.pp | 8 - .../manifests/bigcouch/settle_cluster.pp | 11 - puppet/modules/site_couchdb/manifests/init.pp | 9 +- puppet/modules/site_couchdb/manifests/logrotate.pp | 14 - puppet/modules/site_couchdb/manifests/plain.pp | 2 - puppet/modules/site_couchdb/manifests/setup.pp | 7 - 15 files changed, 29 insertions(+), 555 deletions(-) delete mode 100644 puppet/modules/site_check_mk/files/agent/logwatch/bigcouch.cfg delete mode 100755 puppet/modules/site_check_mk/files/agent/nagios_plugins/check_unix_open_fds.pl delete mode 100644 puppet/modules/site_check_mk/manifests/agent/couchdb/bigcouch.pp delete mode 100644 puppet/modules/site_check_mk/manifests/agent/couchdb/plain.pp delete mode 100644 puppet/modules/site_couchdb/files/runit_config delete mode 100644 puppet/modules/site_couchdb/manifests/bigcouch.pp delete mode 100644 puppet/modules/site_couchdb/manifests/bigcouch/add_nodes.pp delete mode 100644 puppet/modules/site_couchdb/manifests/bigcouch/compaction.pp delete mode 100644 puppet/modules/site_couchdb/manifests/bigcouch/settle_cluster.pp delete mode 100644 puppet/modules/site_couchdb/manifests/logrotate.pp (limited to 'puppet/modules') diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/bigcouch.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/bigcouch.cfg deleted file mode 100644 index 0f378a5a..00000000 --- a/puppet/modules/site_check_mk/files/agent/logwatch/bigcouch.cfg +++ /dev/null @@ -1,28 +0,0 @@ -/opt/bigcouch/var/log/bigcouch.log nocontext=1 -# ignore requests that are fine - I undefined - -.*200$ - I undefined - -.*201$ - I 127.0.0.1 undefined.* ok - I 127.0.0.1 localhost:5984 .* ok - # https://leap.se/code/issues/5246 - I Shutting down group server - # ignore bigcouch conflict errors - I Error in process.*{{nocatch,conflict} - # ignore "Uncaught error in HTTP request: {exit, normal}" error - # it's suppressed in later versions of bigcouch anhow - # see https://leap.se/code/issues/5226 - I Uncaught error in HTTP request: {exit,normal} - I Uncaught error in HTTP request: {exit, - # Ignore rexi_EXIT bigcouch error (Bug #6512) - I Error in process <[0-9.]+> on node .* with exit value: {{rexi_EXIT,{(killed|noproc|shutdown),\[{couch_db,collect_results - # Ignore "Generic server terminating" bigcouch message (Feature #6544) - I Generic server <.*> terminating - I {error_report,<.*>, - I {error_info, - C Uncaught error in HTTP request: {error, - C Response abnormally terminated: {nodedown, - C rexi_DOWN,noproc - C rexi_DOWN,noconnection - C error - C Connection attempt from disallowed node - W Apache CouchDB has started diff --git a/puppet/modules/site_check_mk/files/agent/nagios_plugins/check_unix_open_fds.pl b/puppet/modules/site_check_mk/files/agent/nagios_plugins/check_unix_open_fds.pl deleted file mode 100755 index 06163d49..00000000 --- a/puppet/modules/site_check_mk/files/agent/nagios_plugins/check_unix_open_fds.pl +++ /dev/null @@ -1,322 +0,0 @@ -#!/usr/bin/perl -w - -# check_unix_open_fds Nagios Plugin -# -# TComm - Carlos Peris Pla -# -# This nagios plugin is free software, and comes with ABSOLUTELY -# NO WARRANTY. It may be used, redistributed and/or modified under -# the terms of the GNU General Public Licence (see -# http://www.fsf.org/licensing/licenses/gpl.txt). - - -# MODULE DECLARATION - -use strict; -use Nagios::Plugin; - - -# FUNCTION DECLARATION - -sub CreateNagiosManager (); -sub CheckArguments (); -sub PerformCheck (); - - -# CONSTANT DEFINITION - -use constant NAME => 'check_unix_open_fds'; -use constant VERSION => '0.1b'; -use constant USAGE => "Usage:\ncheck_unix_open_fds -w -c \n". - "\t\t[-V ]\n"; -use constant BLURB => "This plugin checks, in UNIX systems with the command lsof installed and with its SUID bit activated, the number\n". - "of file descriptors opened by an application and its processes.\n"; -use constant LICENSE => "This nagios plugin is free software, and comes with ABSOLUTELY\n". - "no WARRANTY. It may be used, redistributed and/or modified under\n". - "the terms of the GNU General Public Licence\n". - "(see http://www.fsf.org/licensing/licenses/gpl.txt).\n"; -use constant EXAMPLE => "\n\n". - "Example:\n". - "\n". - "check_unix_open_fds -a /usr/local/nagios/bin/ndo2db -w 20,75 -c 25,85\n". - "\n". - "It returns CRITICAL if number of file descriptors opened by ndo2db is higher than 85,\n". - "if not it returns WARNING if number of file descriptors opened by ndo2db is higher \n". - "than 75, if not it returns CRITICAL if number of file descriptors opened by any process\n". - "of ndo2db is higher than 25, if not it returns WARNING if number of file descriptors \n". - "opened by any process of ndo2db is higher than 20.\n". - "In other cases it returns OK if check has been performed succesfully.\n\n"; - - -# VARIABLE DEFINITION - -my $Nagios; -my $Error; -my $PluginResult; -my $PluginOutput; -my @WVRange; -my @CVRange; - - -# MAIN FUNCTION - -# Get command line arguments -$Nagios = &CreateNagiosManager(USAGE, VERSION, BLURB, LICENSE, NAME, EXAMPLE); -eval {$Nagios->getopts}; - -if (!$@) { - # Command line parsed - if (&CheckArguments($Nagios, \$Error, \@WVRange, \@CVRange)) { - # Argument checking passed - $PluginResult = &PerformCheck($Nagios, \$PluginOutput, \@WVRange, \@CVRange) - } - else { - # Error checking arguments - $PluginOutput = $Error; - $PluginResult = UNKNOWN; - } - $Nagios->nagios_exit($PluginResult,$PluginOutput); -} -else { - # Error parsing command line - $Nagios->nagios_exit(UNKNOWN,$@); -} - - - -# FUNCTION DEFINITIONS - -# Creates and configures a Nagios plugin object -# Input: strings (usage, version, blurb, license, name and example) to configure argument parsing functionality -# Return value: reference to a Nagios plugin object - -sub CreateNagiosManager() { - # Create GetOpt object - my $Nagios = Nagios::Plugin->new(usage => $_[0], version => $_[1], blurb => $_[2], license => $_[3], plugin => $_[4], extra => $_[5]); - - # Add argument units - $Nagios->add_arg(spec => 'application|a=s', - help => 'Application path for which you want to check the number of open file descriptors', - required => 1); - - # Add argument warning - $Nagios->add_arg(spec => 'warning|w=s', - help => "Warning thresholds. Format: ", - required => 1); - # Add argument critical - $Nagios->add_arg(spec => 'critical|c=s', - help => "Critical thresholds. Format: ", - required => 1); - - # Return value - return $Nagios; -} - - -# Checks argument values and sets some default values -# Input: Nagios Plugin object -# Output: reference to Error description string, Memory Unit, Swap Unit, reference to WVRange ($_[4]), reference to CVRange ($_[5]) -# Return value: True if arguments ok, false if not - -sub CheckArguments() { - my ($Nagios, $Error, $WVRange, $CVRange) = @_; - my $commas; - my $units; - my $i; - my $firstpos; - my $secondpos; - - # Check Warning thresholds list - $commas = $Nagios->opts->warning =~ tr/,//; - if ($commas !=1){ - ${$Error} = "Invalid Warning list format. One comma is expected."; - return 0; - } - else{ - $i=0; - $firstpos=0; - my $warning=$Nagios->opts->warning; - while ($warning =~ /[,]/g) { - $secondpos=pos $warning; - if ($secondpos - $firstpos==1){ - @{$WVRange}[$i] = "~:"; - } - else{ - @{$WVRange}[$i] = substr $Nagios->opts->warning, $firstpos, ($secondpos-$firstpos-1); - } - $firstpos=$secondpos; - $i++ - } - if (length($Nagios->opts->warning) - $firstpos==0){#La coma es el ultimo elemento del string - @{$WVRange}[$i] = "~:"; - } - else{ - @{$WVRange}[$i] = substr $Nagios->opts->warning, $firstpos, (length($Nagios->opts->warning)-$firstpos); - } - - if (@{$WVRange}[0] !~/^(@?(\d+|(\d+|~):(\d+)?))?$/){ - ${$Error} = "Invalid Process Warning threshold in ${$WVRange[0]}"; - return 0; - }if (@{$WVRange}[1] !~/^(@?(\d+|(\d+|~):(\d+)?))?$/){ - ${$Error} = "Invalid Application Warning threshold in ${$WVRange[1]}"; - return 0; - } - } - - # Check Critical thresholds list - $commas = $Nagios->opts->critical =~ tr/,//; - if ($commas !=1){ - ${$Error} = "Invalid Critical list format. One comma is expected."; - return 0; - } - else{ - $i=0; - $firstpos=0; - my $critical=$Nagios->opts->critical; - while ($critical =~ /[,]/g) { - $secondpos=pos $critical ; - if ($secondpos - $firstpos==1){ - @{$CVRange}[$i] = "~:"; - } - else{ - @{$CVRange}[$i] =substr $Nagios->opts->critical, $firstpos, ($secondpos-$firstpos-1); - } - $firstpos=$secondpos; - $i++ - } - if (length($Nagios->opts->critical) - $firstpos==0){#La coma es el ultimo elemento del string - @{$CVRange}[$i] = "~:"; - } - else{ - @{$CVRange}[$i] = substr $Nagios->opts->critical, $firstpos, (length($Nagios->opts->critical)-$firstpos); - } - - if (@{$CVRange}[0] !~/^(@?(\d+|(\d+|~):(\d+)?))?$/) { - ${$Error} = "Invalid Process Critical threshold in @{$CVRange}[0]"; - return 0; - } - if (@{$CVRange}[1] !~/^(@?(\d+|(\d+|~):(\d+)?))?$/) { - ${$Error} = "Invalid Application Critical threshold in @{$CVRange}[1]"; - return 0; - } - } - - return 1; -} - - -# Performs whole check: -# Input: Nagios Plugin object, reference to Plugin output string, Application, referece to WVRange, reference to CVRange -# Output: Plugin output string -# Return value: Plugin return value - -sub PerformCheck() { - my ($Nagios, $PluginOutput, $WVRange, $CVRange) = @_; - my $Application; - my @AppNameSplitted; - my $ApplicationName; - my $PsCommand; - my $PsResult; - my @PsResultLines; - my $ProcLine; - my $ProcPid; - my $LsofCommand; - my $LsofResult; - my $ProcCount = 0; - my $FDCount = 0; - my $ProcFDAvg = 0; - my $PerProcMaxFD = 0; - my $ProcOKFlag = 0; - my $ProcWarningFlag = 0; - my $ProcCriticalFlag = 0; - my $OKFlag = 0; - my $WarningFlag = 0; - my $CriticalFlag = 0; - my $LastWarningProcFDs = 0; - my $LastWarningProc = -1; - my $LastCriticalProcFDs = 0; - my $LastCriticalProc = -1; - my $ProcPluginReturnValue = UNKNOWN; - my $AppPluginReturnValue = UNKNOWN; - my $PluginReturnValue = UNKNOWN; - my $PerformanceData = ""; - my $PerfdataUnit = "FDs"; - - $Application = $Nagios->opts->application; - $PsCommand = "ps -eaf | grep $Application"; - $PsResult = `$PsCommand`; - @AppNameSplitted = split(/\//, $Application); - $ApplicationName = $AppNameSplitted[$#AppNameSplitted]; - @PsResultLines = split(/\n/, $PsResult); - if ( $#PsResultLines > 1 ) { - foreach my $Proc (split(/\n/, $PsResult)) { - if ($Proc !~ /check_unix_open_fds/ && $Proc !~ / grep /) { - $ProcCount += 1; - $ProcPid = (split(/\s+/, $Proc))[1]; - $LsofCommand = "lsof -p $ProcPid | wc -l"; - $LsofResult = `$LsofCommand`; - $LsofResult = ($LsofResult > 0 ) ? ($LsofResult - 1) : 0; - $FDCount += $LsofResult; - if ($LsofResult >= $PerProcMaxFD) { $PerProcMaxFD = $LsofResult; } - $ProcPluginReturnValue = $Nagios->check_threshold(check => $LsofResult,warning => @{$WVRange}[0],critical => @{$CVRange}[0]); - if ($ProcPluginReturnValue eq OK) { - $ProcOKFlag = 1; - } - elsif ($ProcPluginReturnValue eq WARNING) { - $ProcWarningFlag = 1; - if ($LsofResult >= $LastWarningProcFDs) { - $LastWarningProcFDs = $LsofResult; - $LastWarningProc = $ProcPid; - } - } - #if ($LsofResult >= $PCT) { - elsif ($ProcPluginReturnValue eq CRITICAL) { - $ProcCriticalFlag = 1; - if ($LsofResult >= $LastCriticalProcFDs) { - $LastCriticalProcFDs = $LsofResult; - $LastCriticalProc = $ProcPid; - } - } - } - } - if ($ProcCount) { $ProcFDAvg = int($FDCount / $ProcCount); } - $AppPluginReturnValue = $Nagios->check_threshold(check => $FDCount,warning => @{$WVRange}[1],critical => @{$CVRange}[1]); - #if ($FDCount >= $TWT) { - if ($AppPluginReturnValue eq OK) { $OKFlag = 1; } - elsif ($AppPluginReturnValue eq WARNING) { $WarningFlag = 1; } - elsif ($AppPluginReturnValue eq CRITICAL) { $CriticalFlag = 1; } - - # PluginReturnValue and PluginOutput - if ($CriticalFlag) { - $PluginReturnValue = CRITICAL; - ${$PluginOutput} .= "$ApplicationName handling $FDCount files (critical threshold set to @{$CVRange}[1])"; - } - elsif ($WarningFlag) { - $PluginReturnValue = WARNING; - ${$PluginOutput} .= "$ApplicationName handling $FDCount files (warning threshold set to @{$WVRange}[1])"; - } - elsif ($ProcCriticalFlag) { - $PluginReturnValue = CRITICAL; - ${$PluginOutput} .= "Process ID $LastCriticalProc handling $LastCriticalProcFDs files (critical threshold set to @{$CVRange}[0])"; - } - elsif ($ProcWarningFlag) { - $PluginReturnValue = WARNING; - ${$PluginOutput} .= "Process ID $LastWarningProc handling $LastWarningProcFDs files (warning threshold set to @{$WVRange}[0])"; - } - elsif ($OKFlag && $ProcOKFlag) { - $PluginReturnValue = OK; - ${$PluginOutput} .= "$ApplicationName handling $FDCount files"; - } - } - else { - ${$PluginOutput} .= "No existe la aplicacion $ApplicationName"; - } - - - $PerformanceData .= "ProcCount=$ProcCount$PerfdataUnit FDCount=$FDCount$PerfdataUnit ProcFDAvg=$ProcFDAvg$PerfdataUnit PerProcMaxFD=$PerProcMaxFD$PerfdataUnit"; - - # Output with performance data: - ${$PluginOutput} .= " | $PerformanceData"; - - return $PluginReturnValue; -} diff --git a/puppet/modules/site_check_mk/manifests/agent/couchdb.pp b/puppet/modules/site_check_mk/manifests/agent/couchdb.pp index 1554fd3c..9fc771e0 100644 --- a/puppet/modules/site_check_mk/manifests/agent/couchdb.pp +++ b/puppet/modules/site_check_mk/manifests/agent/couchdb.pp @@ -1,5 +1,4 @@ -# configure logwatch and nagios checks for couchdb (both bigcouch and plain -# couchdb installations) +# configure logwatch and nagios checks for couchdb class site_check_mk::agent::couchdb { concat::fragment { 'syslog_couchdb': @@ -14,21 +13,4 @@ class site_check_mk::agent::couchdb { mode => '0755', require => Package['check_mk-agent'] } - - # check open files for bigcouch proc - include site_check_mk::agent::package::perl_plugin - file { '/srv/leap/nagios/plugins/check_unix_open_fds.pl': - source => 'puppet:///modules/site_check_mk/agent/nagios_plugins/check_unix_open_fds.pl', - mode => '0755' - } - augeas { - 'Couchdb_open_files': - incl => '/etc/check_mk/mrpe.cfg', - lens => 'Spacevars.lns', - changes => [ - 'rm /files/etc/check_mk/mrpe.cfg/Couchdb_open_files', - 'set Couchdb_open_files \'/srv/leap/nagios/plugins/check_unix_open_fds.pl -a beam -w 28672,28672 -c 30720,30720\'' ], - require => File['/etc/check_mk/mrpe.cfg']; - } - } diff --git a/puppet/modules/site_check_mk/manifests/agent/couchdb/bigcouch.pp b/puppet/modules/site_check_mk/manifests/agent/couchdb/bigcouch.pp deleted file mode 100644 index 82c3ac72..00000000 --- a/puppet/modules/site_check_mk/manifests/agent/couchdb/bigcouch.pp +++ /dev/null @@ -1,49 +0,0 @@ -# configure logwatch and nagios checks for bigcouch -class site_check_mk::agent::couchdb::bigcouch { - - # watch bigcouch logs - # currently disabled because bigcouch is too noisy - # see https://leap.se/code/issues/7375 for more details - # and site_config::remove_files for removing leftovers - #file { '/etc/check_mk/logwatch.d/bigcouch.cfg': - # source => 'puppet:///modules/site_check_mk/agent/logwatch/bigcouch.cfg', - #} - - # check syslog msg from: - # - empd - # - /usr/local/bin/couch-doc-update - concat::fragment { 'syslog_bigcouch': - source => 'puppet:///modules/site_check_mk/agent/logwatch/syslog/bigcouch.cfg', - target => '/etc/check_mk/logwatch.d/syslog.cfg', - order => '02'; - } - - # check bigcouch processes - augeas { - 'Bigcouch_epmd_procs': - incl => '/etc/check_mk/mrpe.cfg', - lens => 'Spacevars.lns', - changes => [ - 'rm /files/etc/check_mk/mrpe.cfg/Bigcouch_epmd_procs', - 'set Bigcouch_epmd_procs \'/usr/lib/nagios/plugins/check_procs -w 1:1 -c 1:1 -a /opt/bigcouch/erts-5.9.1/bin/epmd\'' ], - require => File['/etc/check_mk/mrpe.cfg']; - 'Bigcouch_beam_procs': - incl => '/etc/check_mk/mrpe.cfg', - lens => 'Spacevars.lns', - changes => [ - 'rm /files/etc/check_mk/mrpe.cfg/Bigcouch_beam_procs', - 'set Bigcouch_beam_procs \'/usr/lib/nagios/plugins/check_procs -w 1:1 -c 1:1 -a /opt/bigcouch/erts-5.9.1/bin/beam\'' ], - require => File['/etc/check_mk/mrpe.cfg']; - } - - augeas { - 'Bigcouch_open_files': - incl => '/etc/check_mk/mrpe.cfg', - lens => 'Spacevars.lns', - changes => [ - 'rm /files/etc/check_mk/mrpe.cfg/Bigcouch_open_files', - 'set Bigcouch_open_files \'/srv/leap/nagios/plugins/check_unix_open_fds.pl -a beam -w 28672,28672 -c 30720,30720\'' ], - require => File['/etc/check_mk/mrpe.cfg']; - } - -} diff --git a/puppet/modules/site_check_mk/manifests/agent/couchdb/plain.pp b/puppet/modules/site_check_mk/manifests/agent/couchdb/plain.pp deleted file mode 100644 index 3ec2267b..00000000 --- a/puppet/modules/site_check_mk/manifests/agent/couchdb/plain.pp +++ /dev/null @@ -1,23 +0,0 @@ -# configure logwatch and nagios checks for plain single couchdb master -class site_check_mk::agent::couchdb::plain { - - # remove bigcouch leftovers - augeas { - 'Bigcouch_epmd_procs': - incl => '/etc/check_mk/mrpe.cfg', - lens => 'Spacevars.lns', - changes => 'rm /files/etc/check_mk/mrpe.cfg/Bigcouch_epmd_procs', - require => File['/etc/check_mk/mrpe.cfg']; - 'Bigcouch_beam_procs': - incl => '/etc/check_mk/mrpe.cfg', - lens => 'Spacevars.lns', - changes => 'rm /files/etc/check_mk/mrpe.cfg/Bigcouch_beam_procs', - require => File['/etc/check_mk/mrpe.cfg']; - 'Bigcouch_open_files': - incl => '/etc/check_mk/mrpe.cfg', - lens => 'Spacevars.lns', - changes => 'rm /files/etc/check_mk/mrpe.cfg/Bigcouch_open_files', - require => File['/etc/check_mk/mrpe.cfg']; - } - -} diff --git a/puppet/modules/site_config/manifests/remove/bigcouch.pp b/puppet/modules/site_config/manifests/remove/bigcouch.pp index 3535c3c1..9fd3e7ee 100644 --- a/puppet/modules/site_config/manifests/remove/bigcouch.pp +++ b/puppet/modules/site_config/manifests/remove/bigcouch.pp @@ -10,6 +10,33 @@ class site_config::remove::bigcouch { ] } + tidy { + '/etc/logrotate/bigcouch':; + '/srv/leap/nagios/plugins/check_unix_open_fds.pl':; + } + + augeas { + 'Couchdb_open_files': + incl => '/etc/check_mk/mrpe.cfg', + lens => 'Spacevars.lns', + changes => [ + 'rm /files/etc/check_mk/mrpe.cfg/Couchdb_open_files', + 'rm /files/etc/check_mk/mrpe.cfg/Bigcouch_epmd_procs', + 'rm /files/etc/check_mk/mrpe.cfg/Bigcouch_beam_procs', + 'rm /files/etc/check_mk/mrpe.cfg/Bigcouch_open_files' ], + require => File['/etc/check_mk/mrpe.cfg']; + } + + # check syslog msg from: + # - empd + # - /usr/local/bin/couch-doc-update + concat::fragment { 'syslog_bigcouch': + ensure => absent, + source => 'puppet:///modules/site_check_mk/agent/logwatch/syslog/bigcouch.cfg', + target => '/etc/check_mk/logwatch.d/syslog.cfg', + order => '02'; + } + exec { 'remove_bigcouch_logwatch_stateline': command => "sed -i '/bigcouch.log/d' /etc/check_mk/logwatch.state", refreshonly => true, diff --git a/puppet/modules/site_couchdb/files/runit_config b/puppet/modules/site_couchdb/files/runit_config deleted file mode 100644 index 169b4832..00000000 --- a/puppet/modules/site_couchdb/files/runit_config +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -exec 2>&1 -export HOME=/home/bigcouch -ulimit -H -n 32768 -ulimit -S -n 32768 -exec chpst -u bigcouch /opt/bigcouch/bin/bigcouch diff --git a/puppet/modules/site_couchdb/manifests/bigcouch.pp b/puppet/modules/site_couchdb/manifests/bigcouch.pp deleted file mode 100644 index 2de3d4d0..00000000 --- a/puppet/modules/site_couchdb/manifests/bigcouch.pp +++ /dev/null @@ -1,50 +0,0 @@ -# sets up bigcouch on couchdb node -class site_couchdb::bigcouch { - - $config = $::site_couchdb::couchdb_config['bigcouch'] - $cookie = $config['cookie'] - $ednp_port = $config['ednp_port'] - - class { 'couchdb': - admin_pw => $::site_couchdb::couchdb_admin_pw, - admin_salt => $::site_couchdb::couchdb_admin_salt, - bigcouch => true, - bigcouch_cookie => $cookie, - ednp_port => $ednp_port, - chttpd_bind_address => '127.0.0.1' - } - - # - # stunnel must running correctly before bigcouch dbs can be set up. - # - Class['site_config::default'] - -> Class['site_config::resolvconf'] - -> Class['couchdb::bigcouch::package::cloudant'] - -> Service['shorewall'] - -> Exec['refresh_stunnel'] - -> Class['site_couchdb::setup'] - -> Class['site_couchdb::bigcouch::add_nodes'] - -> Class['site_couchdb::bigcouch::settle_cluster'] - -> Class['site_couchdb::create_dbs'] - - include site_couchdb::bigcouch::add_nodes - include site_couchdb::bigcouch::settle_cluster - include site_couchdb::bigcouch::compaction - - file { '/var/log/bigcouch': - ensure => directory - } - - file { '/etc/sv/bigcouch/run': - ensure => present, - source => 'puppet:///modules/site_couchdb/runit_config', - owner => root, - group => root, - mode => '0755', - require => Package['couchdb'], - notify => Service['couchdb'] - } - - include site_check_mk::agent::couchdb::bigcouch - -} diff --git a/puppet/modules/site_couchdb/manifests/bigcouch/add_nodes.pp b/puppet/modules/site_couchdb/manifests/bigcouch/add_nodes.pp deleted file mode 100644 index c8c43275..00000000 --- a/puppet/modules/site_couchdb/manifests/bigcouch/add_nodes.pp +++ /dev/null @@ -1,8 +0,0 @@ -class site_couchdb::bigcouch::add_nodes { - # loop through neighbors array and add nodes - $nodes = $::site_couchdb::bigcouch::config['neighbors'] - - couchdb::bigcouch::add_node { $nodes: - require => Couchdb::Query::Setup['localhost'] - } -} diff --git a/puppet/modules/site_couchdb/manifests/bigcouch/compaction.pp b/puppet/modules/site_couchdb/manifests/bigcouch/compaction.pp deleted file mode 100644 index 84aab4ef..00000000 --- a/puppet/modules/site_couchdb/manifests/bigcouch/compaction.pp +++ /dev/null @@ -1,8 +0,0 @@ -class site_couchdb::bigcouch::compaction { - cron { - 'compact_all_shards': - command => '/srv/leap/couchdb/scripts/bigcouch_compact_all_shards.sh >> /var/log/bigcouch/compaction.log', - hour => 3, - minute => 17; - } -} diff --git a/puppet/modules/site_couchdb/manifests/bigcouch/settle_cluster.pp b/puppet/modules/site_couchdb/manifests/bigcouch/settle_cluster.pp deleted file mode 100644 index 820b5be2..00000000 --- a/puppet/modules/site_couchdb/manifests/bigcouch/settle_cluster.pp +++ /dev/null @@ -1,11 +0,0 @@ -class site_couchdb::bigcouch::settle_cluster { - - exec { 'wait_for_couch_nodes': - command => '/srv/leap/bin/run_tests --test CouchDB/Are_configured_nodes_online? --retry 12 --wait 10' - } - - exec { 'settle_cluster_membership': - command => '/srv/leap/bin/run_tests --test CouchDB/Is_cluster_membership_ok? --retry 12 --wait 10', - require => Exec['wait_for_couch_nodes'] - } -} diff --git a/puppet/modules/site_couchdb/manifests/init.pp b/puppet/modules/site_couchdb/manifests/init.pp index c4fe6277..554bf813 100644 --- a/puppet/modules/site_couchdb/manifests/init.pp +++ b/puppet/modules/site_couchdb/manifests/init.pp @@ -1,4 +1,4 @@ -# entry class for configuring couchdb/bigcouch node +# entry class for configuring couchdb node # couchdb node class site_couchdb { tag 'leap_service' @@ -39,12 +39,6 @@ class site_couchdb { $couchdb_backup = $couchdb_config['backup'] $couchdb_mode = $couchdb_config['mode'] - # ensure bigcouch has been purged from the system: - # TODO: remove this check in 0.9 release - if file('/opt/bigcouch/bin/bigcouch', '/dev/null') != '' { - fail 'ERROR: BigCouch appears to be installed. Make sure you have migrated to CouchDB before proceeding. See https://leap.se/upgrade-0-8' - } - include site_couchdb::plain Class['site_config::default'] @@ -60,7 +54,6 @@ class site_couchdb { include site_couchdb::create_dbs include site_couchdb::add_users include site_couchdb::designs - include site_couchdb::logrotate if $couchdb_backup { include site_couchdb::backup } diff --git a/puppet/modules/site_couchdb/manifests/logrotate.pp b/puppet/modules/site_couchdb/manifests/logrotate.pp deleted file mode 100644 index bb8843bb..00000000 --- a/puppet/modules/site_couchdb/manifests/logrotate.pp +++ /dev/null @@ -1,14 +0,0 @@ -# configure couchdb logrotation -class site_couchdb::logrotate { - - augeas { - 'logrotate_bigcouch': - context => '/files/etc/logrotate.d/bigcouch/rule', - changes => [ - 'set file /opt/bigcouch/var/log/*.log', 'set rotate 7', - 'set schedule daily', 'set compress compress', - 'set missingok missingok', 'set ifempty notifempty', - 'set copytruncate copytruncate' ] - } - -} diff --git a/puppet/modules/site_couchdb/manifests/plain.pp b/puppet/modules/site_couchdb/manifests/plain.pp index b40fc100..710ff7ca 100644 --- a/puppet/modules/site_couchdb/manifests/plain.pp +++ b/puppet/modules/site_couchdb/manifests/plain.pp @@ -6,8 +6,6 @@ class site_couchdb::plain { chttpd_bind_address => '127.0.0.1' } - include site_check_mk::agent::couchdb::plain - # remove bigcouch leftovers from previous installations include ::site_config::remove::bigcouch diff --git a/puppet/modules/site_couchdb/manifests/setup.pp b/puppet/modules/site_couchdb/manifests/setup.pp index 710d3c1c..7477d24c 100644 --- a/puppet/modules/site_couchdb/manifests/setup.pp +++ b/puppet/modules/site_couchdb/manifests/setup.pp @@ -3,13 +3,6 @@ # class site_couchdb::setup { - # ensure that we don't have leftovers from previous installations - # where we installed the cloudant bigcouch package - # https://leap.se/code/issues/4971 - class { 'couchdb::bigcouch::package::cloudant': - ensure => absent - } - $user = $site_couchdb::couchdb_admin_user # setup /etc/couchdb/couchdb-admin.netrc for couchdb admin access -- cgit v1.2.3 From 8b4547d844ef904d9591a2a9fe71989e85197714 Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 23 Jun 2016 14:05:20 -0400 Subject: Make sure bind9 doesn't take over unbound (#8213). Change-Id: Icaab817870d005b7a854a3fb8c402705d0b2d77f --- puppet/modules/site_config/manifests/caching_resolver.pp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_config/manifests/caching_resolver.pp b/puppet/modules/site_config/manifests/caching_resolver.pp index 59b135a3..5541472d 100644 --- a/puppet/modules/site_config/manifests/caching_resolver.pp +++ b/puppet/modules/site_config/manifests/caching_resolver.pp @@ -7,10 +7,7 @@ class site_config::caching_resolver { # and then start it, so unbound will never get properly started. So this will # make sure bind9 is removed before. package { 'bind9': - ensure => absent - } - file { [ '/etc/default/bind9', '/etc/bind/named.conf.options' ]: - ensure => absent + ensure => purged } class { 'unbound': -- cgit v1.2.3 From cfb91a199c8c205b99c4424df77b0b6ed20e4288 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 30 Jun 2016 12:15:39 -0700 Subject: fix static site apache config --- puppet/modules/site_static/templates/amber.erb | 8 +- .../modules/site_static/templates/apache.conf.erb | 122 ++++++++++++--------- puppet/modules/site_static/templates/rack.erb | 6 +- 3 files changed, 79 insertions(+), 57 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_static/templates/amber.erb b/puppet/modules/site_static/templates/amber.erb index 694f1136..b34458c3 100644 --- a/puppet/modules/site_static/templates/amber.erb +++ b/puppet/modules/site_static/templates/amber.erb @@ -4,10 +4,10 @@ <%- end -%> /"> AllowOverride FileInfo Indexes Options=All,MultiViews -<% if scope.function_guess_apache_version([]) == '2.4' %> +<%- if scope.function_guess_apache_version([]) == '2.4' -%> Require all granted -<% else %> +<%- else -%> Order deny,allow Allow from all -<% end %> - +<%- end -%> + \ No newline at end of file diff --git a/puppet/modules/site_static/templates/apache.conf.erb b/puppet/modules/site_static/templates/apache.conf.erb index 2013e5ee..af9a520d 100644 --- a/puppet/modules/site_static/templates/apache.conf.erb +++ b/puppet/modules/site_static/templates/apache.conf.erb @@ -11,6 +11,9 @@ end end + # + # document root + # @document_root = begin root = '/var/www' @locations && @locations.each do |name, location| @@ -19,8 +22,52 @@ root.gsub(%r{^/|/$}, '') end + # + # provider.json + # + # if the domain is a bootstrap domain, we need to expose + # a /provider.json file. + # bootstrap_domain = scope.lookupvar('site_static::bootstrap_domain') bootstrap_client = scope.lookupvar('site_static::bootstrap_client') + if ([@aliases]+[@domain]).flatten.include?(bootstrap_domain) + provider_json = \ +%( + Alias /provider.json /srv/static/public/provider.json + + Header set X-Minimum-Client-Version #{bootstrap_client['min']} + +) + else + provider_json = "" + end + + # + # locations + # + locations = "" + @locations && @locations.each do |name, location| + location_path = location['path'].gsub(%r{^/|/$}, '') + directory = location_directory(name, location) + local_vars = {'location_path'=>location_path, 'directory'=>directory, 'location'=>location, 'name'=>name} + template_path = File.join(File.dirname(__FILE__), location['format']) + '.erb' + break unless File.exists?(template_path) + locations += \ +%( + # + # #{name} (#{location['format']}) + # +#{scope.function_templatewlv([template_path, local_vars])} +) + end + + # + # allow custom apache config + # + custom_apache_config = if @apache_config + @apache_config.gsub(':percent:','%') + end + -%> @@ -28,6 +75,9 @@ <%- if @tor -%> +## +## Tor +## ServerName <%= @tor_domain %> ServerAlias www.<%= @tor_domain %> @@ -41,31 +91,15 @@ DocumentRoot "/<%= @document_root %>/" AccessFileName .htaccess -<%- if ([@aliases]+[@domain]).flatten.include?(bootstrap_domain) -%> - Alias /provider.json /srv/leap/provider.json - - Header set X-Minimum-Client-Version <%= bootstrap_client['min'] %> - -<%- end -%> - -<%- if @apache_config -%> -<%= @apache_config.gsub(':percent:','%') %> -<%- end -%> - -<%- @locations && @locations.each do |name, location| -%> -<%- location_path = location['path'].gsub(%r{^/|/$}, '') -%> -<%- directory = location_directory(name, location) -%> -<%- local_vars = {'location_path'=>location_path, 'directory'=>directory, 'location'=>location, 'name'=>name} -%> -<%- template_path = File.join(File.dirname(__FILE__), location['format']) + '.erb' -%> -<%- break unless File.exists?(template_path) -%> - ## - ## <%= name %> (<%= location['format'] %>) - ## -<%= scope.function_templatewlv([template_path, local_vars]) %> -<%- end -%> -<%- end -%> +<%= provider_json %> +<%= custom_apache_config %> +<%= locations %> +<%- end -%> +## +## HTTP +## ServerName <%= @domain %> ServerAlias www.<%= @domain %> @@ -76,9 +110,16 @@ <%- if @tls_only -%> RewriteEngine On RewriteRule ^.*$ https://<%= @domain -%>%{REQUEST_URI} [R=permanent,L] +<%- else -%> +<%= provider_json %> +<%= custom_apache_config %> +<%= locations %> <%- end -%> +## +## HTTPS +## ServerName <%= @domain %> ServerAlias www.<%= @domain %> @@ -90,14 +131,14 @@ #RewriteLogLevel 3 Include include.d/ssl_common.inc - + <%- if @tls_only -%> - Header always set Strict-Transport-Security: "max-age=15768000;includeSubdomains" + Header always set Strict-Transport-Security: "max-age=15768000;includeSubdomains" <%- end -%> - Header set X-Frame-Options "deny" - Header always unset X-Powered-By - Header always unset X-Runtime + Header set X-Frame-Options "deny" + Header always unset X-Powered-By + Header always unset X-Runtime SSLCertificateKeyFile /etc/x509/keys/<%= @domain %>.key @@ -108,26 +149,7 @@ DocumentRoot "/<%= @document_root %>/" AccessFileName .htaccess -<%- if ([@aliases]+[@domain]).flatten.include?(bootstrap_domain) -%> - Alias /provider.json /srv/static/public/provider.json - - Header set X-Minimum-Client-Version <%= bootstrap_client['min'] %> - -<%- end -%> - -<%- if @apache_config -%> -<%= @apache_config.gsub(':percent:','%') %> -<%- end -%> - -<%- @locations && @locations.each do |name, location| -%> -<%- location_path = location['path'].gsub(%r{^/|/$}, '') -%> -<%- directory = location_directory(name, location) -%> -<%- local_vars = {'location_path'=>location_path, 'directory'=>directory, 'location'=>location, 'name'=>name} -%> -<%- template_path = File.join(File.dirname(__FILE__), location['format']) + '.erb' -%> -<%- break unless File.exists?(template_path) -%> - ## - ## <%= name %> (<%= location['format'] %>) - ## -<%= scope.function_templatewlv([template_path, local_vars]) %> -<%- end -%> +<%= provider_json %> +<%= custom_apache_config %> +<%= locations %> diff --git a/puppet/modules/site_static/templates/rack.erb b/puppet/modules/site_static/templates/rack.erb index 431778bb..1cbf84d2 100644 --- a/puppet/modules/site_static/templates/rack.erb +++ b/puppet/modules/site_static/templates/rack.erb @@ -10,10 +10,10 @@ <%- end -%> "> Options -MultiViews -<% if scope.function_guess_apache_version([]) == '2.4' %> +<%- if scope.function_guess_apache_version([]) == '2.4' -%> Require all granted -<% else %> +<%- else -%> Order deny,allow Allow from all -<% end %> +<%- end -%> -- cgit v1.2.3 From 10602f677edc113b64f6a8fde6e9d0b87460967d Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 5 Jul 2016 13:01:21 -0400 Subject: Remove duplicate syslog entry (#8021). In an attempt to resolve #8021, a template error was made, causing duplicated entries to appear in the rsyslog template. Change-Id: Ic41d6ef9aec9865cf64312c1eb96e408b39d441c --- puppet/modules/site_rsyslog/templates/client.conf.erb | 1 - 1 file changed, 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_rsyslog/templates/client.conf.erb b/puppet/modules/site_rsyslog/templates/client.conf.erb index 7f94759d..553b8373 100644 --- a/puppet/modules/site_rsyslog/templates/client.conf.erb +++ b/puppet/modules/site_rsyslog/templates/client.conf.erb @@ -93,7 +93,6 @@ auth,authpriv.* /var/log/secure <% if scope.lookupvar('rsyslog::log_style') == 'debian' -%> # First some standard log files. Log by facility. # -*.*;auth,authpriv.none -/var/log/syslog cron.* /var/log/cron.log daemon.* -/var/log/daemon.log kern.* -/var/log/kern.log -- cgit v1.2.3 From 428f5c4f839650dac8898746ff395fcf50b658bb Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 23 Jun 2016 16:21:02 -0400 Subject: Enable DNSSEC validation in unbound (#8214). Change-Id: Ibdf39a721162b4a5663ef27c27b2db0261c6e8a5 --- puppet/modules/site_config/manifests/caching_resolver.pp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_config/manifests/caching_resolver.pp b/puppet/modules/site_config/manifests/caching_resolver.pp index 5541472d..2b08ab4c 100644 --- a/puppet/modules/site_config/manifests/caching_resolver.pp +++ b/puppet/modules/site_config/manifests/caching_resolver.pp @@ -23,7 +23,8 @@ class site_config::caching_resolver { hide-identity => 'yes', hide-version => 'yes', harden-glue => 'yes', - access-control => [ '127.0.0.0/8 allow', '::1 allow' ] + access-control => [ '127.0.0.0/8 allow', '::1 allow' ], + module-config => '"validator iterator"' } } } -- cgit v1.2.3 From 2cfcb6d073973025f73f37183a0fa21570a922df Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 5 Jul 2016 11:43:59 -0400 Subject: set domain-secure to internal domain. Without this set, dnssec will fail validation for internal domains, which should not be validated Change-Id: I8589332598fe97ad5218dd23825ac77af2d8def6 --- .../modules/site_config/manifests/caching_resolver.pp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_config/manifests/caching_resolver.pp b/puppet/modules/site_config/manifests/caching_resolver.pp index 2b08ab4c..4da13d9c 100644 --- a/puppet/modules/site_config/manifests/caching_resolver.pp +++ b/puppet/modules/site_config/manifests/caching_resolver.pp @@ -1,6 +1,8 @@ # deploy local caching resolver class site_config::caching_resolver { tag 'leap_base' + $domain = hiera('domain') + $internal_domain = $domain['internal_suffix'] # We need to make sure Package['bind9'] isn't installed because when it is, it # keeps unbound from running. Some base debian installs will install bind9, @@ -17,14 +19,15 @@ class site_config::caching_resolver { require => Package['bind9'], settings => { server => { - verbosity => '1', - interface => [ '127.0.0.1', '::1' ], - port => '53', - hide-identity => 'yes', - hide-version => 'yes', - harden-glue => 'yes', - access-control => [ '127.0.0.0/8 allow', '::1 allow' ], - module-config => '"validator iterator"' + verbosity => '1', + interface => [ '127.0.0.1', '::1' ], + port => '53', + hide-identity => 'yes', + hide-version => 'yes', + harden-glue => 'yes', + access-control => [ '127.0.0.0/8 allow', '::1 allow' ], + module-config => '"validator iterator"', + domain-insecure => $internal_domain } } } -- cgit v1.2.3 From f294ddcca7fbe20de788053bfba1cc9c8417ddd8 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 5 Jul 2016 11:50:41 -0400 Subject: Use DANE/TLSA validation in postfix (#8141). Configure DNSSEC validation for client verification, giving us a stronger form of opportunistic TLS Change-Id: Iab92d4f593c4a5a44e3b694295096b0d7f687a37 --- puppet/modules/site_postfix/manifests/mx.pp | 33 +++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_postfix/manifests/mx.pp b/puppet/modules/site_postfix/manifests/mx.pp index 0b760eb4..2dac85f5 100644 --- a/puppet/modules/site_postfix/manifests/mx.pp +++ b/puppet/modules/site_postfix/manifests/mx.pp @@ -57,10 +57,6 @@ class site_postfix::mx { value => 'sha1'; 'relay_clientcerts': value => 'tcp:localhost:2424'; - # Note: we are setting this here, instead of in site_postfix::mx::smtp_tls - # because the satellites need to have a different value - 'smtp_tls_security_level': - value => 'may'; # reject inbound mail to system users # see https://leap.se/code/issues/6829 # this blocks *only* mails to system users, that don't appear in the @@ -90,6 +86,35 @@ class site_postfix::mx { value => 'permit_mynetworks'; 'postscreen_greet_action': value => 'enforce'; + # Level of DNS support in the Postfix SMTP client. Enable DNS lookups + # (default: empty). When empty, then the legacy "disable_dns_lookups" + # (default: no) parameter is used. Setting 'smtp_dns_support_level' to + # enabled sets the previous behavior with the new parameter. When set to + # 'dnssec" this enables DNSSEC lookups. + 'smtp_dns_support_level': + value => 'dnssec'; + + # http://www.postfix.org/TLS_README.html#client_tls_dane The "dane" level is + # a stronger form of opportunistic TLS that is resistant to man in the + # middle and downgrade attacks when the destination domain uses DNSSEC to + # publish DANE TLSA records for its MX hosts. If a remote SMTP server has + # "usable" (see RFC 6698) DANE TLSA records, the server connection will be + # authenticated. When DANE authentication fails, there is no fallback to + # unauthenticated or plaintext delivery. + # + # If TLSA records are published for a given remote SMTP server (implying TLS + # support), but are all "unusable" due to unsupported parameters or + # malformed data, the Postfix SMTP client will use mandatory unauthenticated + # TLS. Otherwise, when no TLSA records are published, the Postfix SMTP + # client behavior is the same as with may. + # + # This requires postfix to be able to send its DNS queries to a recursive + # DNS nameserver that is able to validate the signed records + # + # Note: we are setting this here, instead of in site_postfix::mx::smtp_tls + # because the satellites need to have a different value + 'smtp_tls_security_level': + value => 'dane'; } # Make sure that the cleanup serivce is not chrooted, otherwise it cannot -- cgit v1.2.3 From 7ce3190986cf8e5fe037a7ccd4c1076505b117f4 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:41:59 -0400 Subject: remove submodules in preparation for move to subrepos Change-Id: Ia7655153b556337f676e3d909559c4a7306bedd6 --- puppet/modules/apache | 1 - puppet/modules/apt | 1 - puppet/modules/augeas | 1 - puppet/modules/backupninja | 1 - puppet/modules/bundler | 1 - puppet/modules/check_mk | 1 - puppet/modules/common | 1 - puppet/modules/concat | 1 - puppet/modules/couchdb | 1 - puppet/modules/git | 1 - puppet/modules/haproxy | 1 - puppet/modules/lsb | 1 - puppet/modules/nagios | 1 - puppet/modules/ntp | 1 - puppet/modules/openvpn | 1 - puppet/modules/passenger | 1 - puppet/modules/postfix | 1 - puppet/modules/resolvconf | 1 - puppet/modules/rsyslog | 1 - puppet/modules/ruby | 1 - puppet/modules/rubygems | 1 - puppet/modules/shorewall | 1 - puppet/modules/squid_deb_proxy | 1 - puppet/modules/sshd | 1 - puppet/modules/stdlib | 1 - puppet/modules/stunnel | 1 - puppet/modules/sysctl | 1 - puppet/modules/systemd | 1 - puppet/modules/tor | 1 - puppet/modules/unbound | 1 - puppet/modules/vcsrepo | 1 - puppet/modules/x509 | 1 - 32 files changed, 32 deletions(-) delete mode 160000 puppet/modules/apache delete mode 160000 puppet/modules/apt delete mode 160000 puppet/modules/augeas delete mode 160000 puppet/modules/backupninja delete mode 160000 puppet/modules/bundler delete mode 160000 puppet/modules/check_mk delete mode 160000 puppet/modules/common delete mode 160000 puppet/modules/concat delete mode 160000 puppet/modules/couchdb delete mode 160000 puppet/modules/git delete mode 160000 puppet/modules/haproxy delete mode 160000 puppet/modules/lsb delete mode 160000 puppet/modules/nagios delete mode 160000 puppet/modules/ntp delete mode 160000 puppet/modules/openvpn delete mode 160000 puppet/modules/passenger delete mode 160000 puppet/modules/postfix delete mode 160000 puppet/modules/resolvconf delete mode 160000 puppet/modules/rsyslog delete mode 160000 puppet/modules/ruby delete mode 160000 puppet/modules/rubygems delete mode 160000 puppet/modules/shorewall delete mode 160000 puppet/modules/squid_deb_proxy delete mode 160000 puppet/modules/sshd delete mode 160000 puppet/modules/stdlib delete mode 160000 puppet/modules/stunnel delete mode 160000 puppet/modules/sysctl delete mode 160000 puppet/modules/systemd delete mode 160000 puppet/modules/tor delete mode 160000 puppet/modules/unbound delete mode 160000 puppet/modules/vcsrepo delete mode 160000 puppet/modules/x509 (limited to 'puppet/modules') diff --git a/puppet/modules/apache b/puppet/modules/apache deleted file mode 160000 index 415e9504..00000000 --- a/puppet/modules/apache +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 415e9504f99dca3ccaa4dfd389dde24ad9d0e01c diff --git a/puppet/modules/apt b/puppet/modules/apt deleted file mode 160000 index 33c61e8d..00000000 --- a/puppet/modules/apt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 33c61e8df59db1abbed379a9e9790946060a8f1e diff --git a/puppet/modules/augeas b/puppet/modules/augeas deleted file mode 160000 index 58ab2b90..00000000 --- a/puppet/modules/augeas +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 58ab2b90c52a5d951fa41596827bc3b6f52310e7 diff --git a/puppet/modules/backupninja b/puppet/modules/backupninja deleted file mode 160000 index 5268a87c..00000000 --- a/puppet/modules/backupninja +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5268a87c329f895017f8ea6c6abc377a4f9a6a77 diff --git a/puppet/modules/bundler b/puppet/modules/bundler deleted file mode 160000 index bacec3e0..00000000 --- a/puppet/modules/bundler +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bacec3e072649be4ade56f7df8506b46ae9c5166 diff --git a/puppet/modules/check_mk b/puppet/modules/check_mk deleted file mode 160000 index aa025715..00000000 --- a/puppet/modules/check_mk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit aa02571537af90ac73309e6e216c9417802548c3 diff --git a/puppet/modules/common b/puppet/modules/common deleted file mode 160000 index ae149624..00000000 --- a/puppet/modules/common +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ae149624f9bc551865b93b9b7155af2de8deeb71 diff --git a/puppet/modules/concat b/puppet/modules/concat deleted file mode 160000 index abce1280..00000000 --- a/puppet/modules/concat +++ /dev/null @@ -1 +0,0 @@ -Subproject commit abce1280e07b544d8455f1572dd870bbd2f14892 diff --git a/puppet/modules/couchdb b/puppet/modules/couchdb deleted file mode 160000 index 76ff149a..00000000 --- a/puppet/modules/couchdb +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 76ff149a095023611c05bbb00157d06f87b07c05 diff --git a/puppet/modules/git b/puppet/modules/git deleted file mode 160000 index ba5dd8d5..00000000 --- a/puppet/modules/git +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ba5dd8d5c8e09d521ff49f1ebc753601e449f828 diff --git a/puppet/modules/haproxy b/puppet/modules/haproxy deleted file mode 160000 index af322a73..00000000 --- a/puppet/modules/haproxy +++ /dev/null @@ -1 +0,0 @@ -Subproject commit af322a73c013f80a958ab7d5d31d0c75cf6d0523 diff --git a/puppet/modules/lsb b/puppet/modules/lsb deleted file mode 160000 index 3742c1a0..00000000 --- a/puppet/modules/lsb +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3742c1a00c5602154a81834443ec5b0ca32c4ca0 diff --git a/puppet/modules/nagios b/puppet/modules/nagios deleted file mode 160000 index e6fee3c7..00000000 --- a/puppet/modules/nagios +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e6fee3c731f68ccf8b6add8ada2162c7ad2b8407 diff --git a/puppet/modules/ntp b/puppet/modules/ntp deleted file mode 160000 index 27f2bc72..00000000 --- a/puppet/modules/ntp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 27f2bc72110b1001233eb0907aa07e06cdf33194 diff --git a/puppet/modules/openvpn b/puppet/modules/openvpn deleted file mode 160000 index 25f1fe8d..00000000 --- a/puppet/modules/openvpn +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 25f1fe8d813f6128068d890a40f5e24be78fb47c diff --git a/puppet/modules/passenger b/puppet/modules/passenger deleted file mode 160000 index d1b46de8..00000000 --- a/puppet/modules/passenger +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d1b46de84acf4d9e3582b64e019935fb1125f9bb diff --git a/puppet/modules/postfix b/puppet/modules/postfix deleted file mode 160000 index cce918f7..00000000 --- a/puppet/modules/postfix +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cce918f784ebf8a8875f43c79bc3a1f39ab9456b diff --git a/puppet/modules/resolvconf b/puppet/modules/resolvconf deleted file mode 160000 index c7eca077..00000000 --- a/puppet/modules/resolvconf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c7eca077fdda063edc96d3bea02c4774569e4b10 diff --git a/puppet/modules/rsyslog b/puppet/modules/rsyslog deleted file mode 160000 index b8ef11c2..00000000 --- a/puppet/modules/rsyslog +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b8ef11c23949d12732ad5cdaebb3023ff39a297a diff --git a/puppet/modules/ruby b/puppet/modules/ruby deleted file mode 160000 index 9ccd853c..00000000 --- a/puppet/modules/ruby +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9ccd853c49af7d0b57ebd9c2ea7673b193fce24b diff --git a/puppet/modules/rubygems b/puppet/modules/rubygems deleted file mode 160000 index 510a3693..00000000 --- a/puppet/modules/rubygems +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 510a3693eab5dc78ed27d3728ee4d3b12334ea12 diff --git a/puppet/modules/shorewall b/puppet/modules/shorewall deleted file mode 160000 index e4a54e30..00000000 --- a/puppet/modules/shorewall +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e4a54e30bf2ad7fa45c73cc544e1da4524a287a4 diff --git a/puppet/modules/squid_deb_proxy b/puppet/modules/squid_deb_proxy deleted file mode 160000 index e796aac4..00000000 --- a/puppet/modules/squid_deb_proxy +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e796aac43aa9781069e167459253d040504c2092 diff --git a/puppet/modules/sshd b/puppet/modules/sshd deleted file mode 160000 index 76f4f872..00000000 --- a/puppet/modules/sshd +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 76f4f872f81209a52df2205fd88b5619df58f003 diff --git a/puppet/modules/stdlib b/puppet/modules/stdlib deleted file mode 160000 index 71123634..00000000 --- a/puppet/modules/stdlib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 71123634744b9fe2ec7d6a3e38e9789fd84801e3 diff --git a/puppet/modules/stunnel b/puppet/modules/stunnel deleted file mode 160000 index 523612fb..00000000 --- a/puppet/modules/stunnel +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 523612fb6daff51837423619f5014e62dc835559 diff --git a/puppet/modules/sysctl b/puppet/modules/sysctl deleted file mode 160000 index 975852b7..00000000 --- a/puppet/modules/sysctl +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 975852b7acc1125b4cd9d4d490b9abd8d31217e6 diff --git a/puppet/modules/systemd b/puppet/modules/systemd deleted file mode 160000 index 6d47fd49..00000000 --- a/puppet/modules/systemd +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6d47fd4999fe03eba6fb11c4490dcbb90d937900 diff --git a/puppet/modules/tor b/puppet/modules/tor deleted file mode 160000 index 9981a70f..00000000 --- a/puppet/modules/tor +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9981a70f7ba1f9e4fe33e4eb46654295287c1fc1 diff --git a/puppet/modules/unbound b/puppet/modules/unbound deleted file mode 160000 index a26b91df..00000000 --- a/puppet/modules/unbound +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a26b91dfea3189e6777629fa00d54f51dc41f4d4 diff --git a/puppet/modules/vcsrepo b/puppet/modules/vcsrepo deleted file mode 160000 index 4e23209e..00000000 --- a/puppet/modules/vcsrepo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4e23209eaccf1ab504d35158f4141b3053327c2f diff --git a/puppet/modules/x509 b/puppet/modules/x509 deleted file mode 160000 index 19254a38..00000000 --- a/puppet/modules/x509 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 19254a38c1c372ae7912ea9f15500b9b1cbffe81 -- cgit v1.2.3 From da37dd95c39f3f100020164473eed53a317fb53f Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:26 -0400 Subject: git subrepo clone https://leap.se/git/puppet_openvpn puppet/modules/openvpn subrepo: subdir: "puppet/modules/openvpn" merged: "26d4edc" upstream: origin: "https://leap.se/git/puppet_openvpn" branch: "master" commit: "26d4edc" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I596766ccfb806b3ca2d1c755c4e24c5ad3d997f9 --- puppet/modules/openvpn/.fixtures.yml | 6 + puppet/modules/openvpn/.gitignore | 3 + puppet/modules/openvpn/.gitrepo | 11 + puppet/modules/openvpn/.rvmrc | 38 ++++ puppet/modules/openvpn/.travis.yml | 29 +++ puppet/modules/openvpn/Gemfile | 7 + puppet/modules/openvpn/Gemfile.lock | 36 ++++ puppet/modules/openvpn/LICENSE | 177 ++++++++++++++++ puppet/modules/openvpn/Modulefile | 11 + puppet/modules/openvpn/Rakefile | 2 + puppet/modules/openvpn/Readme.markdown | 54 +++++ puppet/modules/openvpn/Vagrantfile | 42 ++++ puppet/modules/openvpn/manifests/client.pp | 187 +++++++++++++++++ .../openvpn/manifests/client_specific_config.pp | 79 +++++++ puppet/modules/openvpn/manifests/config.pp | 52 +++++ puppet/modules/openvpn/manifests/init.pp | 43 ++++ puppet/modules/openvpn/manifests/install.pp | 46 ++++ puppet/modules/openvpn/manifests/params.pp | 37 ++++ puppet/modules/openvpn/manifests/server.pp | 233 +++++++++++++++++++++ puppet/modules/openvpn/manifests/service.pp | 36 ++++ .../openvpn/spec/classes/openvpn_config_spec.rb | 15 ++ .../openvpn/spec/classes/openvpn_init_spec.rb | 9 + .../openvpn/spec/classes/openvpn_install_spec.rb | 11 + .../openvpn/spec/classes/openvpn_service_spec.rb | 13 ++ .../openvpn/spec/defines/openvpn_client_spec.rb | 88 ++++++++ .../defines/openvpn_client_specific_config_spec.rb | 40 ++++ .../openvpn/spec/defines/openvpn_server_spec.rb | 165 +++++++++++++++ puppet/modules/openvpn/spec/spec_helper.rb | 2 + puppet/modules/openvpn/templates/client.erb | 26 +++ .../openvpn/templates/client_specific_config.erb | 10 + .../openvpn/templates/etc-default-openvpn.erb | 20 ++ puppet/modules/openvpn/templates/server.erb | 37 ++++ puppet/modules/openvpn/templates/vars.erb | 68 ++++++ puppet/modules/openvpn/vagrant/client.pp | 5 + puppet/modules/openvpn/vagrant/server.pp | 23 ++ 35 files changed, 1661 insertions(+) create mode 100644 puppet/modules/openvpn/.fixtures.yml create mode 100644 puppet/modules/openvpn/.gitignore create mode 100644 puppet/modules/openvpn/.gitrepo create mode 100644 puppet/modules/openvpn/.rvmrc create mode 100644 puppet/modules/openvpn/.travis.yml create mode 100644 puppet/modules/openvpn/Gemfile create mode 100644 puppet/modules/openvpn/Gemfile.lock create mode 100644 puppet/modules/openvpn/LICENSE create mode 100644 puppet/modules/openvpn/Modulefile create mode 100644 puppet/modules/openvpn/Rakefile create mode 100644 puppet/modules/openvpn/Readme.markdown create mode 100644 puppet/modules/openvpn/Vagrantfile create mode 100644 puppet/modules/openvpn/manifests/client.pp create mode 100644 puppet/modules/openvpn/manifests/client_specific_config.pp create mode 100644 puppet/modules/openvpn/manifests/config.pp create mode 100644 puppet/modules/openvpn/manifests/init.pp create mode 100644 puppet/modules/openvpn/manifests/install.pp create mode 100644 puppet/modules/openvpn/manifests/params.pp create mode 100644 puppet/modules/openvpn/manifests/server.pp create mode 100644 puppet/modules/openvpn/manifests/service.pp create mode 100644 puppet/modules/openvpn/spec/classes/openvpn_config_spec.rb create mode 100644 puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb create mode 100644 puppet/modules/openvpn/spec/classes/openvpn_install_spec.rb create mode 100644 puppet/modules/openvpn/spec/classes/openvpn_service_spec.rb create mode 100644 puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb create mode 100644 puppet/modules/openvpn/spec/defines/openvpn_client_specific_config_spec.rb create mode 100644 puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb create mode 100644 puppet/modules/openvpn/spec/spec_helper.rb create mode 100644 puppet/modules/openvpn/templates/client.erb create mode 100644 puppet/modules/openvpn/templates/client_specific_config.erb create mode 100644 puppet/modules/openvpn/templates/etc-default-openvpn.erb create mode 100644 puppet/modules/openvpn/templates/server.erb create mode 100644 puppet/modules/openvpn/templates/vars.erb create mode 100644 puppet/modules/openvpn/vagrant/client.pp create mode 100644 puppet/modules/openvpn/vagrant/server.pp (limited to 'puppet/modules') diff --git a/puppet/modules/openvpn/.fixtures.yml b/puppet/modules/openvpn/.fixtures.yml new file mode 100644 index 00000000..1125ecca --- /dev/null +++ b/puppet/modules/openvpn/.fixtures.yml @@ -0,0 +1,6 @@ +fixtures: + repositories: + concat: git://github.com/ripienaar/puppet-concat.git + symlinks: + openvpn: "#{source_dir}" + diff --git a/puppet/modules/openvpn/.gitignore b/puppet/modules/openvpn/.gitignore new file mode 100644 index 00000000..6fd248b3 --- /dev/null +++ b/puppet/modules/openvpn/.gitignore @@ -0,0 +1,3 @@ +pkg +spec/fixtures +.vagrant diff --git a/puppet/modules/openvpn/.gitrepo b/puppet/modules/openvpn/.gitrepo new file mode 100644 index 00000000..0c191cd8 --- /dev/null +++ b/puppet/modules/openvpn/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_openvpn + branch = master + commit = 26d4edc669853a268a65d2cbbfb42c19f1333de7 + parent = 7ce3190986cf8e5fe037a7ccd4c1076505b117f4 + cmdver = 0.3.0 diff --git a/puppet/modules/openvpn/.rvmrc b/puppet/modules/openvpn/.rvmrc new file mode 100644 index 00000000..6fbfb7f1 --- /dev/null +++ b/puppet/modules/openvpn/.rvmrc @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# This is an RVM Project .rvmrc file, used to automatically load the ruby +# development environment upon cd'ing into the directory + +# First we specify our desired [@], the @gemset name is optional, +# Only full ruby name is supported here, for short names use: +# echo "rvm use 1.9.3" > .rvmrc +environment_id="ruby-1.9.3-p194@puppet" + +# Uncomment the following lines if you want to verify rvm version per project +# rvmrc_rvm_version="1.15.8 (stable)" # 1.10.1 seams as a safe start +# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || { +# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading." +# return 1 +# } + +# First we attempt to load the desired environment directly from the environment +# file. This is very fast and efficient compared to running through the entire +# CLI and selector. If you want feedback on which environment was used then +# insert the word 'use' after --create as this triggers verbose mode. +if [[ -d "${rvm_path:-$HOME/.rvm}/environments" + && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]] +then + \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id" + [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] && + \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true + if [[ $- == *i* ]] # check for interactive shells + then echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green + else echo "Using: $GEM_HOME" # don't use colors in non-interactive shells + fi +else + # If the environment file has not yet been created, use the RVM CLI to select. + rvm --create use "$environment_id" || { + echo "Failed to create RVM environment '${environment_id}'." + return 1 + } +fi diff --git a/puppet/modules/openvpn/.travis.yml b/puppet/modules/openvpn/.travis.yml new file mode 100644 index 00000000..da5c389d --- /dev/null +++ b/puppet/modules/openvpn/.travis.yml @@ -0,0 +1,29 @@ +language: ruby +bundler_args: --without development +script: "bundle exec rake spec SPEC_OPTS='--format documentation'" +rvm: + - 1.8.7 + - 1.9.3 + - 2.0.0 +script: + - "rake lint" + - "rake spec SPEC_OPTS='--format documentation'" +env: + - PUPPET_VERSION="~> 2.7.0" + - PUPPET_VERSION="~> 3.0.0" + - PUPPET_VERSION="~> 3.1.0" + - PUPPET_VERSION="~> 3.2.0" +matrix: + exclude: + - rvm: 1.9.3 + env: PUPPET_VERSION="~> 2.7.0" + - rvm: 2.0.0 + env: PUPPET_VERSION="~> 2.7.0" + - rvm: 2.0.0 + env: PUPPET_VERSION="~> 3.0.0" + - rvm: 2.0.0 + env: PUPPET_VERSION="~> 3.1.0" +notifications: + email: false + on_success: always + on_failure: always diff --git a/puppet/modules/openvpn/Gemfile b/puppet/modules/openvpn/Gemfile new file mode 100644 index 00000000..68e10e7d --- /dev/null +++ b/puppet/modules/openvpn/Gemfile @@ -0,0 +1,7 @@ +source :rubygems + +puppetversion = ENV['PUPPET_VERSION'] +gem 'puppet', puppetversion, :require => false +gem 'puppet-lint' +gem 'rspec-puppet' +gem 'puppetlabs_spec_helper' diff --git a/puppet/modules/openvpn/Gemfile.lock b/puppet/modules/openvpn/Gemfile.lock new file mode 100644 index 00000000..9fce3f98 --- /dev/null +++ b/puppet/modules/openvpn/Gemfile.lock @@ -0,0 +1,36 @@ +GEM + remote: http://rubygems.org/ + specs: + diff-lcs (1.1.3) + facter (1.6.17) + hiera (1.0.0) + metaclass (0.0.1) + mocha (0.13.1) + metaclass (~> 0.0.1) + puppet (3.0.2) + facter (~> 1.6.11) + hiera (~> 1.0.0) + puppetlabs_spec_helper (0.4.0) + mocha (>= 0.10.5) + rake + rspec (>= 2.9.0) + rspec-puppet (>= 0.1.1) + rake (10.0.3) + rspec (2.12.0) + rspec-core (~> 2.12.0) + rspec-expectations (~> 2.12.0) + rspec-mocks (~> 2.12.0) + rspec-core (2.12.2) + rspec-expectations (2.12.1) + diff-lcs (~> 1.1.3) + rspec-mocks (2.12.1) + rspec-puppet (0.1.5) + rspec + +PLATFORMS + ruby + +DEPENDENCIES + puppet + puppetlabs_spec_helper + rspec-puppet diff --git a/puppet/modules/openvpn/LICENSE b/puppet/modules/openvpn/LICENSE new file mode 100644 index 00000000..f433b1a5 --- /dev/null +++ b/puppet/modules/openvpn/LICENSE @@ -0,0 +1,177 @@ + + 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 diff --git a/puppet/modules/openvpn/Modulefile b/puppet/modules/openvpn/Modulefile new file mode 100644 index 00000000..679e7e64 --- /dev/null +++ b/puppet/modules/openvpn/Modulefile @@ -0,0 +1,11 @@ +name 'luxflux-openvpn' +version '2.1.0' +source 'https://github.com/luxflux/puppet-openvpn' +author 'luxflux' +license 'Apache 2.0' +summary 'OpenVPN server puppet module' +description 'Puppet module to manage OpenVPN servers' +project_page 'https://github.com/luxflux/puppet-openvpn' + +## Add dependencies, if any: +dependency 'ripienaar/concat', '0.2.0' diff --git a/puppet/modules/openvpn/Rakefile b/puppet/modules/openvpn/Rakefile new file mode 100644 index 00000000..14f1c246 --- /dev/null +++ b/puppet/modules/openvpn/Rakefile @@ -0,0 +1,2 @@ +require 'rubygems' +require 'puppetlabs_spec_helper/rake_tasks' diff --git a/puppet/modules/openvpn/Readme.markdown b/puppet/modules/openvpn/Readme.markdown new file mode 100644 index 00000000..6bcf49ea --- /dev/null +++ b/puppet/modules/openvpn/Readme.markdown @@ -0,0 +1,54 @@ +# OpenVPN Puppet module + +Puppet module to manage OpenVPN servers + +## Features: + +* Client-specific rules and access policies +* Generated client configurations and SSL-Certificates +* Downloadable client configurations and SSL-Certificates for easy client configuration +* Support for multiple server instances + +Tested on Ubuntu Precise Pangolin, CentOS 6, RedHat 6. + + +## Dependencies + - [puppet-concat](https://github.com/ripienaar/puppet-concat) + + +## Example + +```puppet + # add a server instance + openvpn::server { 'winterthur': + country => 'CH', + province => 'ZH', + city => 'Winterthur', + organization => 'example.org', + email => 'root@example.org', + server => '10.200.200.0 255.255.255.0' + } + + # define clients + openvpn::client { 'client1': + server => 'winterthur' + } + openvpn::client { 'client2': + server => 'winterthur' + } + + openvpn::client_specific_config { 'client1': + server => 'winterthur', + ifconfig => '10.200.200.50 255.255.255.0' + } +``` + +Don't forget the [sysctl](https://github.com/luxflux/puppet-sysctl) directive ```net.ipv4.ip_forward```! + + +# Contributors + +These fine folks helped to get this far with this module: +* [@jlambert121](https://github.com/jlambert121) +* [@jlk](https://github.com/jlk) +* [@elisiano](https://github.com/elisiano) diff --git a/puppet/modules/openvpn/Vagrantfile b/puppet/modules/openvpn/Vagrantfile new file mode 100644 index 00000000..88875ff8 --- /dev/null +++ b/puppet/modules/openvpn/Vagrantfile @@ -0,0 +1,42 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +def server_config(config) + config.vm.provision :puppet, :module_path => '..' do |puppet| + puppet.manifests_path = "vagrant" + puppet.manifest_file = "server.pp" + end +end + +def client_config(config) + config.vm.provision :puppet, :module_path => '..' do |puppet| + puppet.manifests_path = "vagrant" + puppet.manifest_file = "client.pp" + end +end + +Vagrant::Config.run do |config| + + config.vm.define :server_ubuntu do |c| + c.vm.box = 'precise64' + server_config c + c.vm.network :hostonly, '10.255.255.10' + end + + config.vm.define :server_centos do |c| + c.vm.box = 'centos63' + + c.vm.provision :shell, :inline => 'if [ ! -f rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm ]; then wget -q http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm; fi' + c.vm.provision :shell, :inline => 'yum install -y rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm || exit 0' + + server_config c + c.vm.network :hostonly, '10.255.255.11' + end + + config.vm.define :client_ubuntu do |c| + c.vm.box = 'precise64' + client_config c + c.vm.network :hostonly, '10.255.255.20' + end + +end diff --git a/puppet/modules/openvpn/manifests/client.pp b/puppet/modules/openvpn/manifests/client.pp new file mode 100644 index 00000000..92c6aa4e --- /dev/null +++ b/puppet/modules/openvpn/manifests/client.pp @@ -0,0 +1,187 @@ +# == Define: openvpn::client +# +# This define creates the client certs for a specified openvpn server as well +# as creating a tarball that can be directly imported into openvpn clients +# +# +# === Parameters +# +# [*server*] +# String. Name of the corresponding openvpn endpoint +# Required +# +# [*compression*] +# String. Which compression algorithim to use +# Default: comp-lzo +# Options: comp-lzo or '' (disable compression) +# +# [*dev*] +# String. Device method +# Default: tun +# Options: tun (routed connections), tap (bridged connections) +# +# [*mute*] +# Integer. Set log mute level +# Default: 20 +# +# [*mute_replay_warnings*] +# Boolean. Silence duplicate packet warnings (common on wireless networks) +# Default: true +# +# [*nobind*] +# Boolean. Whether or not to bind to a specific port number +# Default: true +# +# [*persist_key*] +# Boolean. Try to retain access to resources that may be unavailable +# because of privilege downgrades +# Default: true +# +# [*persist_tun*] +# Boolean. Try to retain access to resources that may be unavailable +# because of privilege downgrades +# Default: true +# +# [*port*] +# Integer. The port the openvpn server service is running on +# Default: 1194 +# +# [*proto*] +# String. What IP protocol is being used. +# Default: tcp +# Options: tcp or udp +# +# [*remote_host*] +# String. The IP or hostname of the openvpn server service +# Default: FQDN +# +# [*resolv_retry*] +# Integer/String. How many seconds should the openvpn client try to resolve +# the server's hostname +# Default: infinite +# Options: Integer or infinite +# +# [*verb*] +# Integer. Level of logging verbosity +# Default: 3 +# +# +# === Examples +# +# openvpn::client { +# 'my_user': +# server => 'contractors', +# remote_host => 'vpn.mycompany.com' +# } +# +# * Removal: +# Manual process right now, todo for the future +# +# +# === Authors +# +# * Raffael Schmid +# * John Kinsella +# * Justin Lambert +# +# === License +# +# Copyright 2013 Raffael Schmid, +# +# 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. +# +define openvpn::client( + $server, + $compression = 'comp-lzo', + $dev = 'tun', + $mute = '20', + $mute_replay_warnings = true, + $nobind = true, + $persist_key = true, + $persist_tun = true, + $port = '1194', + $proto = 'tcp', + $remote_host = $::fqdn, + $resolv_retry = 'infinite', + $verb = '3', +) { + + Openvpn::Server[$server] -> + Openvpn::Client[$name] + + exec { + "generate certificate for ${name} in context of ${server}": + command => ". ./vars && ./pkitool ${name}", + cwd => "/etc/openvpn/${server}/easy-rsa", + creates => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt", + provider => 'shell'; + } + + file { + [ "/etc/openvpn/${server}/download-configs/${name}", + "/etc/openvpn/${server}/download-configs/${name}/keys"]: + ensure => directory; + + "/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt": + ensure => link, + target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt", + require => Exec["generate certificate for ${name} in context of ${server}"]; + + "/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key": + ensure => link, + target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.key", + require => Exec["generate certificate for ${name} in context of ${server}"]; + + "/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt": + ensure => link, + target => "/etc/openvpn/${server}/easy-rsa/keys/ca.crt", + require => Exec["generate certificate for ${name} in context of ${server}"]; + + "/etc/openvpn/${server}/download-configs/${name}/${name}.conf": + owner => root, + group => root, + mode => '0444', + content => template('openvpn/client.erb'), + notify => Exec["tar the thing ${server} with ${name}"]; + } + + exec { + "tar the thing ${server} with ${name}": + cwd => "/etc/openvpn/${server}/download-configs/", + command => "/bin/rm ${name}.tar.gz; tar --exclude=\\*.conf.d -chzvf ${name}.tar.gz ${name}", + refreshonly => true, + require => [ File["/etc/openvpn/${server}/download-configs/${name}/${name}.conf"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt"] + ], + notify => Exec["generate ${name}.ovpn in ${server}"]; + } + + exec { + "generate ${name}.ovpn in ${server}": + cwd => "/etc/openvpn/${server}/download-configs/", + command => "/bin/rm ${name}.ovpn; cat ${name}/${name}.conf|perl -lne 'if(m|^ca keys/ca.crt|){ chomp(\$ca=`cat ${name}/keys/ca.crt`); print \"\n\$ca\n\"} elsif(m|^cert keys/${name}.crt|) { chomp(\$crt=`cat ${name}/keys/${name}.crt`); print \"\n\$crt\n\"} elsif(m|^key keys/${name}.key|){ chomp(\$key=`cat ${name}/keys/${name}.key`); print \"\n\$key\n\"} else { print} ' > ${name}.ovpn", + refreshonly => true, + require => [ File["/etc/openvpn/${server}/download-configs/${name}/${name}.conf"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt"], + ], + } + + file { "/etc/openvpn/${server}/download-configs/${name}.ovpn": + mode => '0400', + require => Exec["generate ${name}.ovpn in ${server}"], + } +} diff --git a/puppet/modules/openvpn/manifests/client_specific_config.pp b/puppet/modules/openvpn/manifests/client_specific_config.pp new file mode 100644 index 00000000..4287421a --- /dev/null +++ b/puppet/modules/openvpn/manifests/client_specific_config.pp @@ -0,0 +1,79 @@ +# == Define: openvpn::client_specific_config +# +# This define configures options which will be pushed by the server to a +# specific client only. This feature is explained here: +# http://openvpn.net/index.php/open-source/documentation/howto.html#policy +# +# === Parameters +# +# All the parameters are explained in the openvpn documentation: +# http://openvpn.net/index.php/open-source/documentation/howto.html#policy +# +# [*server*] +# String. Name of the corresponding openvpn endpoint +# Required +# +# [*iroute*] +# Array. Array of iroute combinations. +# Default: [] +# +# [*ifconfig*] +# String. IP configuration to push to the client. +# Default: false +# +# [*dhcp_options] +# Array. DHCP options to push to the client. +# Default: [] +# +# +# === Examples +# +# openvpn::client_specific_config { +# 'vpn_client': +# server => 'contractors', +# iroute => ['10.0.1.0 255.255.255.0'], +# ifconfig => '10.10.10.1 10.10.10.2', +# dhcp_options => ['DNS 8.8.8.8'] +# } +# +# * Removal: +# Manual process right now, todo for the future +# +# +# === Authors +# +# * Raffael Schmid +# +# === License +# +# Copyright 2013 Raffael Schmid, +# +# 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. +# +define openvpn::client_specific_config( + $server, + $iroute = [], + $ifconfig = false, + $dhcp_options = [] +) { + + Openvpn::Server[$server] -> + Openvpn::Client[$name] -> + Openvpn::Client_specific_config[$name] + + file { "/etc/openvpn/${server}/client-configs/${name}": + ensure => present, + content => template('openvpn/client_specific_config.erb') + } + +} diff --git a/puppet/modules/openvpn/manifests/config.pp b/puppet/modules/openvpn/manifests/config.pp new file mode 100644 index 00000000..32b32094 --- /dev/null +++ b/puppet/modules/openvpn/manifests/config.pp @@ -0,0 +1,52 @@ +# == Class: openvpn::config +# +# This class sets up the openvpn enviornment as well as the default config file +# +# +# === Examples +# +# This class should not be directly invoked +# +# === Authors +# +# * Raffael Schmid +# * John Kinsella +# * Justin Lambert +# +# === License +# +# Copyright 2013 Raffael Schmid, +# +# 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. +# +class openvpn::config { + + if $::osfamily == 'Debian' { + include concat::setup + + concat { + '/etc/default/openvpn': + owner => root, + group => root, + mode => 644, + warn => true; + } + + concat::fragment { + 'openvpn.default.header': + content => template('openvpn/etc-default-openvpn.erb'), + target => '/etc/default/openvpn', + order => 01; + } + } +} diff --git a/puppet/modules/openvpn/manifests/init.pp b/puppet/modules/openvpn/manifests/init.pp new file mode 100644 index 00000000..7e07f025 --- /dev/null +++ b/puppet/modules/openvpn/manifests/init.pp @@ -0,0 +1,43 @@ +# == Class: openvpn +# +# This module installs the openvpn service, configures vpn endpoints, generates +# client certificates, and generates client config files +# +# +# === Examples +# +# * Installation: +# class { 'openvpn': } +# +# +# === Authors +# +# * Raffael Schmid +# * John Kinsella +# * Justin Lambert +# +# === License +# +# Copyright 2013 Raffael Schmid, +# +# 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. +# +class openvpn { + + class {'openvpn::params': } -> + class {'openvpn::install': } -> + class {'openvpn::config': } ~> + class {'openvpn::service': } -> + Class['openvpn'] + +} diff --git a/puppet/modules/openvpn/manifests/install.pp b/puppet/modules/openvpn/manifests/install.pp new file mode 100644 index 00000000..a230373a --- /dev/null +++ b/puppet/modules/openvpn/manifests/install.pp @@ -0,0 +1,46 @@ +# == Class: openvpn +# +# This module installs the openvpn service, configures vpn endpoints, generates +# client certificates, and generates client config files +# +# +# === Examples +# +# This class should not be directly invoked +# +# +# === Authors +# +# * Raffael Schmid +# * John Kinsella +# * Justin Lambert +# +# === License +# +# Copyright 2013 Raffael Schmid, +# +# 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. +# +class openvpn::install { + + package { + 'openvpn': + ensure => installed; + } + + file { + [ '/etc/openvpn', '/etc/openvpn/keys' ]: + ensure => directory, + require => Package['openvpn']; + } +} diff --git a/puppet/modules/openvpn/manifests/params.pp b/puppet/modules/openvpn/manifests/params.pp new file mode 100644 index 00000000..33495270 --- /dev/null +++ b/puppet/modules/openvpn/manifests/params.pp @@ -0,0 +1,37 @@ +# === License +# +# Copyright 2013 Raffael Schmid, +# +# 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. +# +class openvpn::params { + + $group = $::osfamily ? { + 'RedHat' => 'nobody', + default => 'nogroup' + } + + $easyrsa_source = $::osfamily ? { + 'RedHat' => $::operatingsystemmajrelease ? { + 6 => '/usr/share/openvpn/easy-rsa/2.0', + default => '/usr/share/doc/openvpn-2.2.2/easy-rsa/2.0' + }, + default => '/usr/share/doc/openvpn/examples/easy-rsa/2.0' + } + + $link_openssl_cnf = $::osfamily ? { + /(Debian|RedHat)/ => true, + default => false + } + +} diff --git a/puppet/modules/openvpn/manifests/server.pp b/puppet/modules/openvpn/manifests/server.pp new file mode 100644 index 00000000..649048c4 --- /dev/null +++ b/puppet/modules/openvpn/manifests/server.pp @@ -0,0 +1,233 @@ +# == Define: openvpn::server +# +# This define creates the openvpn server instance and ssl certificates +# +# +# === Parameters +# +# [*country*] +# String. Country to be used for the SSL certificate +# +# [*province*] +# String. Province to be used for the SSL certificate +# +# [*city*] +# String. City to be used for the SSL certificate +# +# [*organization*] +# String. Organization to be used for the SSL certificate +# +# [*email*] +# String. Email address to be used for the SSL certificate +# +# [*compression*] +# String. Which compression algorithim to use +# Default: comp-lzo +# Options: comp-lzo or '' (disable compression) +# +# [*dev*] +# String. Device method +# Default: tun +# Options: tun (routed connections), tap (bridged connections) +# +# [*user*] +# String. Group to drop privileges to after startup +# Default: nobody +# +# [*group*] +# String. User to drop privileges to after startup +# Default: depends on your $::osfamily +# +# [*ipp*] +# Boolean. Persist ifconfig information to a file to retain client IP +# addresses between sessions +# Default: false +# +# [*local*] +# String. Interface for openvpn to bind to. +# Default: $::ipaddress_eth0 +# Options: An IP address or '' to bind to all ip addresses +# +# [*logfile*] +# String. Logfile for this openvpn server +# Default: false +# Options: false (syslog) or log file name +# +# [*port*] +# Integer. The port the openvpn server service is running on +# Default: 1194 +# +# [*proto*] +# String. What IP protocol is being used. +# Default: tcp +# Options: tcp or udp +# +# [*status_log*] +# String. Logfile for periodic dumps of the vpn service status +# Default: "${name}/openvpn-status.log" +# +# [*server*] +# String. Network to assign client addresses out of +# Default: None. Required in tun mode, not in tap mode +# +# [*push*] +# Array. Options to push out to the client. This can include routes, DNS +# servers, DNS search domains, and many other options. +# Default: [] +# +# +# === Examples +# +# openvpn::client { +# 'my_user': +# server => 'contractors', +# remote_host => 'vpn.mycompany.com' +# } +# +# * Removal: +# Manual process right now, todo for the future +# +# +# === Authors +# +# * Raffael Schmid +# * John Kinsella +# * Justin Lambert +# +# === License +# +# Copyright 2013 Raffael Schmid, +# +# 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. +# +define openvpn::server( + $country, + $province, + $city, + $organization, + $email, + $compression = 'comp-lzo', + $dev = 'tun0', + $user = 'nobody', + $group = false, + $ipp = false, + $ip_pool = [], + $local = $::ipaddress_eth0, + $logfile = false, + $port = '1194', + $proto = 'tcp', + $status_log = "${name}/openvpn-status.log", + $server = '', + $push = [] +) { + + include openvpn + Class['openvpn::install'] -> + Openvpn::Server[$name] ~> + Class['openvpn::service'] + + $tls_server = $proto ? { + /tcp/ => true, + default => false + } + + $group_to_set = $group ? { + false => $openvpn::params::group, + default => $group + } + + file { + ["/etc/openvpn/${name}", "/etc/openvpn/${name}/client-configs", "/etc/openvpn/${name}/download-configs" ]: + ensure => directory; + } + + exec { + "copy easy-rsa to openvpn config folder ${name}": + command => "/bin/cp -r ${openvpn::params::easyrsa_source} /etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa", + notify => Exec["fix_easyrsa_file_permissions_${name}"], + require => File["/etc/openvpn/${name}"]; + } + + exec { + "fix_easyrsa_file_permissions_${name}": + refreshonly => true, + command => "/bin/chmod 755 /etc/openvpn/${name}/easy-rsa/*"; + } + + file { + "/etc/openvpn/${name}/easy-rsa/vars": + ensure => present, + content => template('openvpn/vars.erb'), + require => Exec["copy easy-rsa to openvpn config folder ${name}"]; + } + + file { + "/etc/openvpn/${name}/easy-rsa/openssl.cnf": + require => Exec["copy easy-rsa to openvpn config folder ${name}"]; + } + + if $openvpn::params::link_openssl_cnf == true { + File["/etc/openvpn/${name}/easy-rsa/openssl.cnf"] { + ensure => link, + target => "/etc/openvpn/${name}/easy-rsa/openssl-1.0.0.cnf" + } + } + + exec { + "generate dh param ${name}": + command => '. ./vars && ./clean-all && ./build-dh', + cwd => "/etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa/keys/dh1024.pem", + provider => 'shell', + require => File["/etc/openvpn/${name}/easy-rsa/vars"]; + + "initca ${name}": + command => '. ./vars && ./pkitool --initca', + cwd => "/etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa/keys/ca.key", + provider => 'shell', + require => [ Exec["generate dh param ${name}"], File["/etc/openvpn/${name}/easy-rsa/openssl.cnf"] ]; + + "generate server cert ${name}": + command => '. ./vars && ./pkitool --server server', + cwd => "/etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa/keys/server.key", + provider => 'shell', + require => Exec["initca ${name}"]; + } + + file { + "/etc/openvpn/${name}/keys": + ensure => link, + target => "/etc/openvpn/${name}/easy-rsa/keys", + require => Exec["copy easy-rsa to openvpn config folder ${name}"]; + } + + if $::osfamily == 'Debian' { + concat::fragment { + "openvpn.default.autostart.${name}": + content => "AUTOSTART=\"\$AUTOSTART ${name}\"\n", + target => '/etc/default/openvpn', + order => 10; + } + } + + file { + "/etc/openvpn/${name}.conf": + owner => root, + group => root, + mode => '0444', + content => template('openvpn/server.erb'); + } +} diff --git a/puppet/modules/openvpn/manifests/service.pp b/puppet/modules/openvpn/manifests/service.pp new file mode 100644 index 00000000..54e8db7d --- /dev/null +++ b/puppet/modules/openvpn/manifests/service.pp @@ -0,0 +1,36 @@ +# == Class: openvpn::config +# +# This class maintains the openvpn service +# +# +# === Examples +# +# This class should not be directly invoked +# +# === Authors +# +# * Raffael Schmid +# * John Kinsella +# * Justin Lambert +# +# === License +# +# Copyright 2013 Raffael Schmid, +# +# 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 +# +# lied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +class openvpn::service { + service { + 'openvpn': + ensure => running, + enable => true, + hasrestart => true, + hasstatus => true; + } +} diff --git a/puppet/modules/openvpn/spec/classes/openvpn_config_spec.rb b/puppet/modules/openvpn/spec/classes/openvpn_config_spec.rb new file mode 100644 index 00000000..bbb63a77 --- /dev/null +++ b/puppet/modules/openvpn/spec/classes/openvpn_config_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe 'openvpn::config', :type => :class do + + it { should create_class('openvpn::config') } + + context "on Debian based machines" do + let (:facts) { { :osfamily => 'Debian', :concat_basedir => '/var/lib/puppet/concat' } } + + it { should contain_class('concat::setup') } + it { should contain_concat('/etc/default/openvpn') } + it { should contain_concat__fragment('openvpn.default.header') } + end + +end diff --git a/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb b/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb new file mode 100644 index 00000000..45dcc9bf --- /dev/null +++ b/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe 'openvpn', :type => :class do + + let (:facts) { { :concat_basedir => '/var/lib/puppet/concat' } } + + it { should create_class('openvpn') } + +end diff --git a/puppet/modules/openvpn/spec/classes/openvpn_install_spec.rb b/puppet/modules/openvpn/spec/classes/openvpn_install_spec.rb new file mode 100644 index 00000000..cdb31358 --- /dev/null +++ b/puppet/modules/openvpn/spec/classes/openvpn_install_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe 'openvpn::install', :type => :class do + + it { should create_class('openvpn::install') } + it { should contain_package('openvpn') } + + it { should contain_file('/etc/openvpn').with('ensure' => 'directory') } + it { should contain_file('/etc/openvpn/keys').with('ensure' => 'directory') } + +end diff --git a/puppet/modules/openvpn/spec/classes/openvpn_service_spec.rb b/puppet/modules/openvpn/spec/classes/openvpn_service_spec.rb new file mode 100644 index 00000000..f427e7f1 --- /dev/null +++ b/puppet/modules/openvpn/spec/classes/openvpn_service_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe 'openvpn::service', :type => :class do + + let (:facts) { { :concat_basedir => '/var/lib/puppet/concat' } } + + it { should create_class('openvpn::service') } + it { should contain_service('openvpn').with( + 'ensure' => 'running', + 'enable' => true + ) } + +end diff --git a/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb new file mode 100644 index 00000000..a4b580e8 --- /dev/null +++ b/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +describe 'openvpn::client', :type => :define do + let(:title) { 'test_client' } + let(:params) { { 'server' => 'test_server' } } + let(:facts) { { :fqdn => 'somehost', :concat_basedir => '/var/lib/puppet/concat' } } + let(:pre_condition) do + 'openvpn::server { "test_server": + country => "CO", + province => "ST", + city => "Some City", + organization => "example.org", + email => "testemail@example.org" + }' + end + + it { should contain_exec('generate certificate for test_client in context of test_server') } + + [ 'test_client', 'test_client/keys'].each do |directory| + it { should contain_file("/etc/openvpn/test_server/download-configs/#{directory}") } + end + + [ 'test_client.crt', 'test_client.key', 'ca.crt' ].each do |file| + it { should contain_file("/etc/openvpn/test_server/download-configs/test_client/keys/#{file}").with( + 'ensure' => 'link', + 'target' => "/etc/openvpn/test_server/easy-rsa/keys/#{file}" + )} + end + + it { should contain_exec('tar the thing test_server with test_client').with( + 'cwd' => '/etc/openvpn/test_server/download-configs/', + 'command' => '/bin/rm test_client.tar.gz; tar --exclude=\*.conf.d -chzvf test_client.tar.gz test_client' + ) } + + context "setting the minimum parameters" do + let(:params) { { 'server' => 'test_server' } } + let(:facts) { { :fqdn => 'somehost', :concat_basedir => '/var/lib/puppet/concat' } } + + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^client$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^ca\s+keys\/ca\.crt$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^cert\s+keys\/test_client.crt$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^key\s+keys\/test_client\.key$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^dev\s+tun$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^proto\s+tcp$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^remote\s+somehost\s+1194$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^comp-lzo$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^resolv-retry\s+infinite$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^nobind$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^persist-key$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^persist-tun$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^mute-replay-warnings$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^ns\-cert\-type\s+server$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^verb\s+3$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^mute\s+20$/)} + end + + context "setting all of the parameters" do + let(:params) { { + 'server' => 'test_server', + 'compression' => 'comp-something', + 'dev' => 'tap', + 'mute' => 10, + 'mute_replay_warnings' => false, + 'nobind' => false, + 'persist_key' => false, + 'persist_tun' => false, + 'port' => '123', + 'proto' => 'udp', + 'remote_host' => 'somewhere', + 'resolv_retry' => '2m', + 'verb' => '1' + } } + let(:facts) { { :fqdn => 'somehost', :concat_basedir => '/var/lib/puppet/concat' } } + + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^client$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^ca\s+keys\/ca\.crt$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^cert\s+keys\/test_client.crt$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^key\s+keys\/test_client\.key$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^dev\s+tap$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^proto\s+udp$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^remote\s+somewhere\s+123$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^comp-something$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^resolv-retry\s+2m$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^verb\s+1$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^mute\s+10$/)} + end + +end diff --git a/puppet/modules/openvpn/spec/defines/openvpn_client_specific_config_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_client_specific_config_spec.rb new file mode 100644 index 00000000..cfdab389 --- /dev/null +++ b/puppet/modules/openvpn/spec/defines/openvpn_client_specific_config_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe 'openvpn::client_specific_config', :type => :define do + let(:title) { 'test_client' } + let(:params) { { 'server' => 'test_server' } } + let(:facts) { { :fqdn => 'somehost', :concat_basedir => '/var/lib/puppet/concat' } } + let(:pre_condition) do + [ + 'openvpn::server { "test_server": + country => "CO", + province => "ST", + city => "Some City", + organization => "example.org", + email => "testemail@example.org" + }', + 'openvpn::client { "test_client": + server => "test_server" + }' + ].join + end + + it { should contain_file('/etc/openvpn/test_server/client-configs/test_client') } + + describe "setting no paramter at all" do + it { should contain_file('/etc/openvpn/test_server/client-configs/test_client').with_content(/\A\n\z/) } + end + + describe "setting all parameters" do + let(:params) do + {:server => 'test_server', + :iroute => ['10.0.1.0 255.255.255.0'], + :ifconfig => '10.10.10.2 255.255.255.0', + :dhcp_options => ['DNS 8.8.8.8']} + end + + it { should contain_file('/etc/openvpn/test_server/client-configs/test_client').with_content(/^iroute 10.0.1.0 255.255.255.0$/) } + it { should contain_file('/etc/openvpn/test_server/client-configs/test_client').with_content(/^ifconfig-push 10.10.10.2 255.255.255.0$/) } + it { should contain_file('/etc/openvpn/test_server/client-configs/test_client').with_content(/^push dhcp-option DNS 8.8.8.8$/) } + end +end diff --git a/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb new file mode 100644 index 00000000..467be6aa --- /dev/null +++ b/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb @@ -0,0 +1,165 @@ +require 'spec_helper' + +describe 'openvpn::server', :type => :define do + + let(:title) { 'test_server' } + + context "creating a server with the minimum parameters" do + let(:params) { { + 'country' => 'CO', + 'province' => 'ST', + 'city' => 'Some City', + 'organization' => 'example.org', + 'email' => 'testemail@example.org' + } } + + let (:facts) { { + :ipaddress_eth0 => '1.2.3.4', + :network_eth0 => '1.2.3.0', + :netmask_eth0 => '255.255.255.0', + :concat_basedir => '/var/lib/puppet/concat', + :osfamily => 'anything_else' + } } + + # Files associated with a server config + it { should contain_file('/etc/openvpn/test_server').with('ensure' => 'directory')} + it { should contain_file('/etc/openvpn/test_server/client-configs').with('ensure' => 'directory')} + it { should contain_file('/etc/openvpn/test_server/download-configs').with('ensure' => 'directory')} + it { should contain_file('/etc/openvpn/test_server/easy-rsa/vars')} + it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf')} + it { should contain_file('/etc/openvpn/test_server/keys').with( + 'ensure' => 'link', + 'target' => '/etc/openvpn/test_server/easy-rsa/keys' + )} + + # Execs to working with certificates + it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with( + 'command' => '/bin/cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa' + )} + it { should contain_exec('generate dh param test_server') } + it { should contain_exec('initca test_server') } + it { should contain_exec('generate server cert test_server') } + + # VPN server config file itself + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^mode\s+server$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^client\-config\-dir\s+\/etc\/openvpn\/test_server\/client\-configs$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^ca\s+\/etc\/openvpn\/test_server\/keys\/ca.crt$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^cert\s+\/etc\/openvpn\/test_server\/keys\/server.crt$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^key\s+\/etc\/openvpn\/test_server\/keys\/server.key$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^dh\s+\/etc\/openvpn\/test_server\/keys\/dh1024.pem$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^proto\s+tcp-server$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^tls-server$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^port\s+1194$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^comp-lzo$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^group\s+nogroup$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^user\s+nobody$/) } + it { should_not contain_file('/etc/openvpn/test_server.conf').with_content(/^log\-append\s+test_server\/openvpn\.log$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^status\s+test_server\/openvpn\-status\.log$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^dev\s+tun0$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^local\s+1\.2\.3\.4$/) } + it { should_not contain_file('/etc/openvpn/test_server.conf').with_content(/^ifconfig-pool-persist/) } + end + + context "creating a server setting all parameters" do + let(:params) { { + 'country' => 'CO', + 'province' => 'ST', + 'city' => 'Some City', + 'organization' => 'example.org', + 'email' => 'testemail@example.org', + 'compression' => 'fake_compression', + 'port' => '123', + 'proto' => 'udp', + 'group' => 'someone', + 'user' => 'someone', + 'logfile' => '/var/log/openvpn/test_server.log', + 'status_log' => '/var/log/openvpn/test_server_status.log', + 'dev' => 'tun1', + 'local' => '2.3.4.5', + 'ipp' => true, + 'server' => '2.3.4.0 255.255.0.0', + 'push' => [ 'dhcp-option DNS 172.31.0.30', 'route 172.31.0.0 255.255.0.0' ] + } } + + let (:facts) { { + :ipaddress_eth0 => '1.2.3.4', + :network_eth0 => '1.2.3.0', + :netmask_eth0 => '255.255.255.0', + :concat_basedir => '/var/lib/puppet/concat' + } } + + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^mode\s+server$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^client\-config\-dir\s+\/etc\/openvpn\/test_server\/client\-configs$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^ca\s+\/etc\/openvpn\/test_server\/keys\/ca.crt$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^cert\s+\/etc\/openvpn\/test_server\/keys\/server.crt$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^key\s+\/etc\/openvpn\/test_server\/keys\/server.key$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^dh\s+\/etc\/openvpn\/test_server\/keys\/dh1024.pem$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^proto\s+udp$/) } + it { should_not contain_file('/etc/openvpn/test_server.conf').with_content(/^proto\s+tls-server$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^port\s+123$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^fake_compression$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^group\s+someone$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^user\s+someone$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^log\-append\s+\/var\/log\/openvpn\/test_server\.log$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^status\s+\/var\/log\/openvpn\/test_server_status\.log$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^dev\s+tun1$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^local\s+2\.3\.4\.5$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^server\s+2\.3\.4\.0\s+255\.255\.0\.0$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^push\s+dhcp-option\s+DNS\s+172\.31\.0\.30$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^push\s+route\s+172\.31\.0\.0\s+255\.255\.0\.0$/) } + end + + context "when RedHat based machine" do + let(:params) { { + 'country' => 'CO', + 'province' => 'ST', + 'city' => 'Some City', + 'organization' => 'example.org', + 'email' => 'testemail@example.org' + } } + + let(:facts) { { :osfamily => 'RedHat', :concat_basedir => '/var/lib/puppet/concat' } } + + it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf').with( + 'ensure' => 'link', + 'target' => '/etc/openvpn/test_server/easy-rsa/openssl-1.0.0.cnf' + )} + + it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with( + 'command' => '/bin/cp -r /usr/share/doc/openvpn-2.2.2/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa' + )} + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^group\s+nobody$/) } + + end + + context "when Debian based machine" do + let(:params) { { + 'country' => 'CO', + 'province' => 'ST', + 'city' => 'Some City', + 'organization' => 'example.org', + 'email' => 'testemail@example.org' + } } + + let(:facts) { { :osfamily => 'Debian', :concat_basedir => '/var/lib/puppet/concat' } } + + it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf').with( + 'ensure' => 'link', + 'target' => '/etc/openvpn/test_server/easy-rsa/openssl-1.0.0.cnf' + )} + + it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with( + 'command' => '/bin/cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa' + )} + + # Configure to start vpn session + it { should contain_concat__fragment('openvpn.default.autostart.test_server').with( + 'content' => "AUTOSTART=\"$AUTOSTART test_server\"\n", + 'target' => '/etc/default/openvpn' + )} + + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^group\s+nogroup$/) } + + end + +end diff --git a/puppet/modules/openvpn/spec/spec_helper.rb b/puppet/modules/openvpn/spec/spec_helper.rb new file mode 100644 index 00000000..dc7e9f4a --- /dev/null +++ b/puppet/modules/openvpn/spec/spec_helper.rb @@ -0,0 +1,2 @@ +require 'rubygems' +require 'puppetlabs_spec_helper/module_spec_helper' diff --git a/puppet/modules/openvpn/templates/client.erb b/puppet/modules/openvpn/templates/client.erb new file mode 100644 index 00000000..021ed617 --- /dev/null +++ b/puppet/modules/openvpn/templates/client.erb @@ -0,0 +1,26 @@ +client +ca keys/ca.crt +cert keys/<%= scope.lookupvar('name') %>.crt +key keys/<%= scope.lookupvar('name') %>.key +dev <%= scope.lookupvar('dev') %> +proto <%= scope.lookupvar('proto') %> +remote <%= scope.lookupvar('remote_host') %> <%= scope.lookupvar('port') %> +<% if scope.lookupvar('compression') != '' -%> +<%= scope.lookupvar('compression') %> +<% end -%> +resolv-retry <%= scope.lookupvar('resolv_retry') %> +<% if scope.lookupvar('nobind') -%> +nobind +<% end -%> +<% if scope.lookupvar('persist_key') -%> +persist-key +<% end -%> +<% if scope.lookupvar('persist_tun') -%> +persist-tun +<% end -%> +<% if scope.lookupvar('mute_replay_warnings') -%> +mute-replay-warnings +<% end -%> +ns-cert-type server +verb <%= scope.lookupvar('verb') %> +mute <%= scope.lookupvar('mute') %> diff --git a/puppet/modules/openvpn/templates/client_specific_config.erb b/puppet/modules/openvpn/templates/client_specific_config.erb new file mode 100644 index 00000000..62cc0e7a --- /dev/null +++ b/puppet/modules/openvpn/templates/client_specific_config.erb @@ -0,0 +1,10 @@ +<% scope.lookupvar('iroute').each do |route| -%> +iroute <%= route %> +<% end -%> +<% if ifconfig = scope.lookupvar('ifconfig') -%> +ifconfig-push <%= ifconfig %> +<% end -%> +<% scope.lookupvar('dhcp_options').each do |option| -%> +push dhcp-option <%= option %> +<% end -%> + diff --git a/puppet/modules/openvpn/templates/etc-default-openvpn.erb b/puppet/modules/openvpn/templates/etc-default-openvpn.erb new file mode 100644 index 00000000..310e462e --- /dev/null +++ b/puppet/modules/openvpn/templates/etc-default-openvpn.erb @@ -0,0 +1,20 @@ +# This is the configuration file for /etc/init.d/openvpn + +# +# Start only these VPNs automatically via init script. +# Allowed values are "all", "none" or space separated list of +# names of the VPNs. If empty, "all" is assumed. +# +#AUTOSTART="all" +#AUTOSTART="none" +#AUTOSTART="home office" +# +# Refresh interval (in seconds) of default status files +# located in /var/run/openvpn.$NAME.status +# Defaults to 10, 0 disables status file generation +# +#STATUSREFRESH=10 +#STATUSREFRESH=0 +# Optional arguments to openvpn's command line +OPTARGS="" +AUTOSTART="" diff --git a/puppet/modules/openvpn/templates/server.erb b/puppet/modules/openvpn/templates/server.erb new file mode 100644 index 00000000..6ef13263 --- /dev/null +++ b/puppet/modules/openvpn/templates/server.erb @@ -0,0 +1,37 @@ +mode server +client-config-dir /etc/openvpn/<%= scope.lookupvar('name') %>/client-configs +ca /etc/openvpn/<%= scope.lookupvar('name') %>/keys/ca.crt +cert /etc/openvpn/<%= scope.lookupvar('name') %>/keys/server.crt +key /etc/openvpn/<%= scope.lookupvar('name') %>/keys/server.key +dh /etc/openvpn/<%= scope.lookupvar('name') %>/keys/dh1024.pem +<% if scope.lookupvar('proto') == 'tcp' -%> +proto <%= scope.lookupvar('proto') %>-server +<% else -%> +proto <%= scope.lookupvar('proto') %> +<% end -%> +port <%= scope.lookupvar('port') %> +<% if scope.lookupvar('tls_server') -%> +tls-server +<% end -%> +<% if scope.lookupvar('compression') != '' -%> +<%= scope.lookupvar('compression') %> +<% end -%> +group <%= scope.lookupvar('group_to_set') %> +user <%= scope.lookupvar('user') %> +<% if scope.lookupvar('logfile') -%> +log-append <%= scope.lookupvar('logfile') %> +<% end -%> +status <%= scope.lookupvar('status_log') %> +dev <%= scope.lookupvar('dev') %> +<% if scope.lookupvar('local') != '' -%> +local <%= scope.lookupvar('local') %> +<% end -%> +<% if scope.lookupvar('ipp') -%> +ifconfig-pool-persist <%= scope.lookupvar('name') %>/vpn-ipp.txt +<% end -%> +<% if scope.lookupvar('server') != '' -%> +server <%= scope.lookupvar('server') %> +<% end -%> +<% scope.lookupvar('push').each do |item| -%> +push <%= item %> +<% end -%> diff --git a/puppet/modules/openvpn/templates/vars.erb b/puppet/modules/openvpn/templates/vars.erb new file mode 100644 index 00000000..20448b8b --- /dev/null +++ b/puppet/modules/openvpn/templates/vars.erb @@ -0,0 +1,68 @@ +# easy-rsa parameter settings + +# NOTE: If you installed from an RPM, +# don't edit this file in place in +# /usr/share/openvpn/easy-rsa -- +# instead, you should copy the whole +# easy-rsa directory to another location +# (such as /etc/openvpn) so that your +# edits will not be wiped out by a future +# OpenVPN package upgrade. + +# This variable should point to +# the top level of the easy-rsa +# tree. +export EASY_RSA="/etc/openvpn/<%= @name %>/easy-rsa" + +# +# This variable should point to +# the requested executables +# +export OPENSSL="openssl" +export PKCS11TOOL="pkcs11-tool" +export GREP="grep" + + +# This variable should point to +# the openssl.cnf file included +# with easy-rsa. +export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA` + +# Edit this variable to point to +# your soon-to-be-created key +# directory. +# +# WARNING: clean-all will do +# a rm -rf on this directory +# so make sure you define +# it correctly! +export KEY_DIR="$EASY_RSA/keys" + +# Issue rm -rf warning +echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR + +# PKCS11 fixes +export PKCS11_MODULE_PATH="dummy" +export PKCS11_PIN="dummy" + +# Increase this to 2048 if you +# are paranoid. This will slow +# down TLS negotiation performance +# as well as the one-time DH parms +# generation process. +export KEY_SIZE=1024 + +# In how many days should the root CA key expire? +export CA_EXPIRE=3650 + +# In how many days should certificates expire? +export KEY_EXPIRE=3650 + +# These are the default values for fields +# which will be placed in the certificate. +# Don't leave any of these fields blank. +export KEY_COUNTRY="<%= @country %>" +export KEY_PROVINCE="<%= @province %>" +export KEY_CITY="<%= @city %>" +export KEY_ORG="<%= @organization %>" +export KEY_EMAIL="<%= @email %>" diff --git a/puppet/modules/openvpn/vagrant/client.pp b/puppet/modules/openvpn/vagrant/client.pp new file mode 100644 index 00000000..7ebeb1d7 --- /dev/null +++ b/puppet/modules/openvpn/vagrant/client.pp @@ -0,0 +1,5 @@ +node default { + + package { 'openvpn': ensure => installed; } + +} diff --git a/puppet/modules/openvpn/vagrant/server.pp b/puppet/modules/openvpn/vagrant/server.pp new file mode 100644 index 00000000..a95def06 --- /dev/null +++ b/puppet/modules/openvpn/vagrant/server.pp @@ -0,0 +1,23 @@ +node default { + openvpn::server { 'winterthur': + country => 'CH', + province => 'ZH', + city => 'Winterthur', + organization => 'example.org', + email => 'root@example.org', + server => '10.200.200.0 255.255.255.0' + } + + openvpn::client { 'client1': + server => 'winterthur'; + } + + openvpn::client_specific_config { 'client1': + server => 'winterthur', + ifconfig => '10.200.200.100 255.255.255.0' + } + + openvpn::client { 'client2': + server => 'winterthur'; + } +} -- cgit v1.2.3 From b85f8c1b914a09b6001d4c1b5c7d07ef17ac766f Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:27 -0400 Subject: git subrepo clone https://leap.se/git/puppet_concat puppet/modules/concat subrepo: subdir: "puppet/modules/concat" merged: "abce128" upstream: origin: "https://leap.se/git/puppet_concat" branch: "master" commit: "abce128" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: Ic28e31bdc5b32fd6c55636bc35d9ca2967daf997 --- puppet/modules/concat/.gitrepo | 11 ++ puppet/modules/concat/CHANGELOG | 29 ++++ puppet/modules/concat/LICENSE | 14 ++ puppet/modules/concat/Modulefile | 8 + puppet/modules/concat/README.markdown | 112 +++++++++++++ puppet/modules/concat/Rakefile | 13 ++ puppet/modules/concat/files/concatfragments.sh | 129 +++++++++++++++ puppet/modules/concat/files/null/.gitignore | 0 puppet/modules/concat/lib/facter/concat_basedir.rb | 5 + puppet/modules/concat/manifests/fragment.pp | 49 ++++++ puppet/modules/concat/manifests/init.pp | 178 +++++++++++++++++++++ puppet/modules/concat/manifests/setup.pp | 49 ++++++ puppet/modules/concat/spec/defines/init_spec.rb | 20 +++ puppet/modules/concat/spec/spec_helper.rb | 9 ++ 14 files changed, 626 insertions(+) create mode 100644 puppet/modules/concat/.gitrepo create mode 100644 puppet/modules/concat/CHANGELOG create mode 100644 puppet/modules/concat/LICENSE create mode 100644 puppet/modules/concat/Modulefile create mode 100644 puppet/modules/concat/README.markdown create mode 100644 puppet/modules/concat/Rakefile create mode 100755 puppet/modules/concat/files/concatfragments.sh create mode 100644 puppet/modules/concat/files/null/.gitignore create mode 100644 puppet/modules/concat/lib/facter/concat_basedir.rb create mode 100644 puppet/modules/concat/manifests/fragment.pp create mode 100644 puppet/modules/concat/manifests/init.pp create mode 100644 puppet/modules/concat/manifests/setup.pp create mode 100644 puppet/modules/concat/spec/defines/init_spec.rb create mode 100644 puppet/modules/concat/spec/spec_helper.rb (limited to 'puppet/modules') diff --git a/puppet/modules/concat/.gitrepo b/puppet/modules/concat/.gitrepo new file mode 100644 index 00000000..89eb24da --- /dev/null +++ b/puppet/modules/concat/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_concat + branch = master + commit = abce1280e07b544d8455f1572dd870bbd2f14892 + parent = da37dd95c39f3f100020164473eed53a317fb53f + cmdver = 0.3.0 diff --git a/puppet/modules/concat/CHANGELOG b/puppet/modules/concat/CHANGELOG new file mode 100644 index 00000000..c506cf1a --- /dev/null +++ b/puppet/modules/concat/CHANGELOG @@ -0,0 +1,29 @@ +KNOWN ISSUES: +- In 0.24.8 you will see inintended notifies, if you build a file + in a run, the next run will also see it as changed. This is due + to how 0.24.8 does the purging of unhandled files, this is improved + in 0.25.x and we cannot work around it in our code. + +CHANGELOG: +- 2010/02/19 - initial release +- 2010/03/12 - add support for 0.24.8 and newer + - make the location of sort configurable + - add the ability to add shell comment based warnings to + top of files + - add the ablity to create empty files +- 2010/04/05 - fix parsing of WARN and change code style to match rest + of the code + - Better and safer boolean handling for warn and force + - Don't use hard coded paths in the shell script, set PATH + top of the script + - Use file{} to copy the result and make all fragments owned + by root. This means we can chnage the ownership/group of the + resulting file at any time. + - You can specify ensure => "/some/other/file" in concat::fragment + to include the contents of a symlink into the final file. +- 2010/04/16 - Add more cleaning of the fragment name - removing / from the $name +- 2010/05/22 - Improve documentation and show the use of ensure => +- 2010/07/14 - Add support for setting the filebucket behavior of files +- 2010/10/04 - Make the warning message configurable +- 2010/12/03 - Add flags to make concat work better on Solaris - thanks Jonathan Boyett +- 2011/02/03 - Make the shell script more portable and add a config option for root group diff --git a/puppet/modules/concat/LICENSE b/puppet/modules/concat/LICENSE new file mode 100644 index 00000000..6a9e9a19 --- /dev/null +++ b/puppet/modules/concat/LICENSE @@ -0,0 +1,14 @@ + Copyright 2012 R.I.Pienaar + + 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/puppet/modules/concat/Modulefile b/puppet/modules/concat/Modulefile new file mode 100644 index 00000000..d6ab2bb0 --- /dev/null +++ b/puppet/modules/concat/Modulefile @@ -0,0 +1,8 @@ +name 'puppet-concat' +version '0.1.0' +source 'git://github.com/ripienaar/puppet-concat.git' +author 'R.I.Pienaar' +license 'Apache' +summary 'Concat module' +description 'Concat module' +project_page 'http://github.com/ripienaar/puppet-concat' diff --git a/puppet/modules/concat/README.markdown b/puppet/modules/concat/README.markdown new file mode 100644 index 00000000..8736d57a --- /dev/null +++ b/puppet/modules/concat/README.markdown @@ -0,0 +1,112 @@ +What is it? +=========== + +A Puppet module that can construct files from fragments. + +Please see the comments in the various .pp files for details +as well as posts on my blog at http://www.devco.net/ + +Released under the Apache 2.0 licence + +Usage: +------ + +Before you can use any of the concat features you should include the class +concat::setup somewhere on your node first. + +If you wanted a /etc/motd file that listed all the major modules +on the machine. And that would be maintained automatically even +if you just remove the include lines for other modules you could +use code like below, a sample /etc/motd would be: + +
+Puppet modules on this server:
+
+    -- Apache
+    -- MySQL
+
+ +Local sysadmins can also append to the file by just editing /etc/motd.local +their changes will be incorporated into the puppet managed motd. + +
+# class to setup basic motd, include on all nodes
+class motd {
+   include concat::setup
+   $motd = "/etc/motd"
+
+   concat{$motd:
+      owner => root,
+      group => root,
+      mode  => 644
+   }
+
+   concat::fragment{"motd_header":
+      target => $motd,
+      content => "\nPuppet modules on this server:\n\n",
+      order   => 01,
+   }
+
+   # local users on the machine can append to motd by just creating
+   # /etc/motd.local
+   concat::fragment{"motd_local":
+      target => $motd,
+      ensure  => "/etc/motd.local",
+      order   => 15
+   }
+}
+
+# used by other modules to register themselves in the motd
+define motd::register($content="", $order=10) {
+   if $content == "" {
+      $body = $name
+   } else {
+      $body = $content
+   }
+
+   concat::fragment{"motd_fragment_$name":
+      target  => "/etc/motd",
+      content => "    -- $body\n"
+   }
+}
+
+# a sample apache module
+class apache {
+   include apache::install, apache::config, apache::service
+
+   motd::register{"Apache": }
+}
+
+ +Known Issues: +------------- +* In 0.24.8 you will see inintended notifies, if you build a file + in a run, the next run will also see it as changed. This is due + to how 0.24.8 does the purging of unhandled files, this is improved + in 0.25.x and we cannot work around it in our code. +* Since puppet-concat now relies on a fact for the concat directory, + you will need to set up pluginsync = true for at least the first run. + You have this issue if puppet fails to run on the client and you have + a message similar to + "err: Failed to apply catalog: Parameter path failed: File + paths must be fully qualified, not 'undef' at [...]/concat/manifests/setup.pp:44". + +Contributors: +------------- +**Paul Elliot** + + * Provided 0.24.8 support, shell warnings and empty file creation support. + +**Chad Netzer** + + * Various patches to improve safety of file operations + * Symlink support + +**David Schmitt** + + * Patch to remove hard coded paths relying on OS path + * Patch to use file{} to copy the resulting file to the final destination. This means Puppet client will show diffs and that hopefully we can change file ownerships now + +Contact: +-------- +You can contact me on rip@devco.net or follow my blog at http://www.devco.net I am also on twitter as ripienaar diff --git a/puppet/modules/concat/Rakefile b/puppet/modules/concat/Rakefile new file mode 100644 index 00000000..764aebd2 --- /dev/null +++ b/puppet/modules/concat/Rakefile @@ -0,0 +1,13 @@ +require 'rake' +require 'rspec/core/rake_task' + +task :default => [:spec] + +desc "Run all module spec tests (Requires rspec-puppet gem)" +RSpec::Core::RakeTask.new(:spec) + +desc "Build package" +task :build do + system("puppet-module build") +end + diff --git a/puppet/modules/concat/files/concatfragments.sh b/puppet/modules/concat/files/concatfragments.sh new file mode 100755 index 00000000..c9397975 --- /dev/null +++ b/puppet/modules/concat/files/concatfragments.sh @@ -0,0 +1,129 @@ +#!/bin/sh + +# Script to concat files to a config file. +# +# Given a directory like this: +# /path/to/conf.d +# |-- fragments +# | |-- 00_named.conf +# | |-- 10_domain.net +# | `-- zz_footer +# +# The script supports a test option that will build the concat file to a temp location and +# use /usr/bin/cmp to verify if it should be run or not. This would result in the concat happening +# twice on each run but gives you the option to have an unless option in your execs to inhibit rebuilds. +# +# Without the test option and the unless combo your services that depend on the final file would end up +# restarting on each run, or in other manifest models some changes might get missed. +# +# OPTIONS: +# -o The file to create from the sources +# -d The directory where the fragments are kept +# -t Test to find out if a build is needed, basically concats the files to a temp +# location and compare with what's in the final location, return codes are designed +# for use with unless on an exec resource +# -w Add a shell style comment at the top of the created file to warn users that it +# is generated by puppet +# -f Enables the creation of empty output files when no fragments are found +# -n Sort the output numerically rather than the default alpha sort +# +# the command: +# +# concatfragments.sh -o /path/to/conffile.cfg -d /path/to/conf.d +# +# creates /path/to/conf.d/fragments.concat and copies the resulting +# file to /path/to/conffile.cfg. The files will be sorted alphabetically +# pass the -n switch to sort numerically. +# +# The script does error checking on the various dirs and files to make +# sure things don't fail. + +OUTFILE="" +WORKDIR="" +TEST="" +FORCE="" +WARN="" +SORTARG="" + +PATH=/sbin:/usr/sbin:/bin:/usr/bin + +## Well, if there's ever a bad way to do things, Nexenta has it. +## http://nexenta.org/projects/site/wiki/Personalities +unset SUN_PERSONALITY + +while getopts "o:s:d:tnw:f" options; do + case $options in + o ) OUTFILE=$OPTARG;; + d ) WORKDIR=$OPTARG;; + n ) SORTARG="-n";; + w ) WARNMSG="$OPTARG";; + f ) FORCE="true";; + t ) TEST="true";; + * ) echo "Specify output file with -o and fragments directory with -d" + exit 1;; + esac +done + +# do we have -o? +if [ x${OUTFILE} = "x" ]; then + echo "Please specify an output file with -o" + exit 1 +fi + +# do we have -d? +if [ x${WORKDIR} = "x" ]; then + echo "Please fragments directory with -d" + exit 1 +fi + +# can we write to -o? +if [ -f ${OUTFILE} ]; then + if [ ! -w ${OUTFILE} ]; then + echo "Cannot write to ${OUTFILE}" + exit 1 + fi +else + if [ ! -w `dirname ${OUTFILE}` ]; then + echo "Cannot write to `dirname ${OUTFILE}` to create ${OUTFILE}" + exit 1 + fi +fi + +# do we have a fragments subdir inside the work dir? +if [ ! -d "${WORKDIR}/fragments" ] && [ ! -x "${WORKDIR}/fragments" ]; then + echo "Cannot access the fragments directory" + exit 1 +fi + +# are there actually any fragments? +if [ ! "$(ls -A ${WORKDIR}/fragments)" ]; then + if [ x${FORCE} = "x" ]; then + echo "The fragments directory is empty, cowardly refusing to make empty config files" + exit 1 + fi +fi + +cd ${WORKDIR} + +if [ x${WARNMSG} = "x" ]; then + : > "fragments.concat" +else + printf '%s\n' "$WARNMSG" > "fragments.concat" +fi + +# find all the files in the fragments directory, sort them numerically and concat to fragments.concat in the working dir +find fragments/ -type f -follow | sort ${SORTARG} | while read fragfile; do + cat "$fragfile" >> "fragments.concat" +done + +if [ x${TEST} = "x" ]; then + # This is a real run, copy the file to outfile + cp fragments.concat ${OUTFILE} + RETVAL=$? +else + # Just compare the result to outfile to help the exec decide + cmp ${OUTFILE} fragments.concat + RETVAL=$? +fi + +exit $RETVAL diff --git a/puppet/modules/concat/files/null/.gitignore b/puppet/modules/concat/files/null/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/puppet/modules/concat/lib/facter/concat_basedir.rb b/puppet/modules/concat/lib/facter/concat_basedir.rb new file mode 100644 index 00000000..02e9c5bf --- /dev/null +++ b/puppet/modules/concat/lib/facter/concat_basedir.rb @@ -0,0 +1,5 @@ +Facter.add("concat_basedir") do + setcode do + File.join(Puppet[:vardir],"concat") + end +end diff --git a/puppet/modules/concat/manifests/fragment.pp b/puppet/modules/concat/manifests/fragment.pp new file mode 100644 index 00000000..943bf671 --- /dev/null +++ b/puppet/modules/concat/manifests/fragment.pp @@ -0,0 +1,49 @@ +# Puts a file fragment into a directory previous setup using concat +# +# OPTIONS: +# - target The file that these fragments belong to +# - content If present puts the content into the file +# - source If content was not specified, use the source +# - order By default all files gets a 10_ prefix in the directory +# you can set it to anything else using this to influence the +# order of the content in the file +# - ensure Present/Absent or destination to a file to include another file +# - mode Mode for the file +# - owner Owner of the file +# - group Owner of the file +# - backup Controls the filebucketing behavior of the final file and +# see File type reference for its use. Defaults to 'puppet' +define concat::fragment($target, $content='', $source='', $order=10, $ensure = 'present', $mode = '0644', $owner = $::id, $group = $concat::setup::root_group, $backup = 'puppet') { + $safe_name = regsubst($name, '/', '_', 'G') + $safe_target_name = regsubst($target, '/', '_', 'G') + $concatdir = $concat::setup::concatdir + $fragdir = "${concatdir}/${safe_target_name}" + + # if content is passed, use that, else if source is passed use that + # if neither passed, but $ensure is in symlink form, make a symlink + case $content { + '': { + case $source { + '': { + case $ensure { + '', 'absent', 'present', 'file', 'directory': { + crit('No content, source or symlink specified') + } + } + } + default: { File{ source => $source } } + } + } + default: { File{ content => $content } } + } + + file{"${fragdir}/fragments/${order}_${safe_name}": + ensure => $ensure, + mode => $mode, + owner => $owner, + group => $group, + backup => $backup, + alias => "concat_fragment_${name}", + notify => Exec["concat_${target}"] + } +} diff --git a/puppet/modules/concat/manifests/init.pp b/puppet/modules/concat/manifests/init.pp new file mode 100644 index 00000000..0b3ed564 --- /dev/null +++ b/puppet/modules/concat/manifests/init.pp @@ -0,0 +1,178 @@ +# A system to construct files using fragments from other files or templates. +# +# This requires at least puppet 0.25 to work correctly as we use some +# enhancements in recursive directory management and regular expressions +# to do the work here. +# +# USAGE: +# The basic use case is as below: +# +# concat{"/etc/named.conf": +# notify => Service["named"] +# } +# +# concat::fragment{"foo.com_config": +# target => "/etc/named.conf", +# order => 10, +# content => template("named_conf_zone.erb") +# } +# +# # add a fragment not managed by puppet so local users +# # can add content to managed file +# concat::fragment{"foo.com_user_config": +# target => "/etc/named.conf", +# order => 12, +# ensure => "/etc/named.conf.local" +# } +# +# This will use the template named_conf_zone.erb to build a single +# bit of config up and put it into the fragments dir. The file +# will have an number prefix of 10, you can use the order option +# to control that and thus control the order the final file gets built in. +# +# SETUP: +# The class concat::setup uses the fact concat_basedir to define the variable +# $concatdir, where all the temporary files and fragments will be +# durably stored. The fact concat_basedir will be set up on the client to +# /concat, so you will be able to run different setup/flavours +# of puppet clients. +# However, since this requires the file lib/facter/concat_basedir.rb to be +# deployed on the clients, so you will have to set "pluginsync = true" on +# both the master and client, at least for the first run. +# +# There's some regular expression magic to figure out the puppet version but +# if you're on an older 0.24 version just set $puppetversion = 24 +# +# Before you can use any of the concat features you should include the +# class concat::setup somewhere on your node first. +# +# DETAIL: +# We use a helper shell script called concatfragments.sh that gets placed +# in /concat/bin to do the concatenation. While this might +# seem more complex than some of the one-liner alternatives you might find on +# the net we do a lot of error checking and safety checks in the script to avoid +# problems that might be caused by complex escaping errors etc. +# +# LICENSE: +# Apache Version 2 +# +# LATEST: +# http://github.com/ripienaar/puppet-concat/ +# +# CONTACT: +# R.I.Pienaar +# Volcane on freenode +# @ripienaar on twitter +# www.devco.net + + +# Sets up so that you can use fragments to build a final config file, +# +# OPTIONS: +# - mode The mode of the final file +# - owner Who will own the file +# - group Who will own the file +# - force Enables creating empty files if no fragments are present +# - warn Adds a normal shell style comment top of the file indicating +# that it is built by puppet +# - backup Controls the filebucketing behavior of the final file and +# see File type reference for its use. Defaults to 'puppet' +# +# ACTIONS: +# - Creates fragment directories if it didn't exist already +# - Executes the concatfragments.sh script to build the final file, this script will create +# directory/fragments.concat. Execution happens only when: +# * The directory changes +# * fragments.concat != final destination, this means rebuilds will happen whenever +# someone changes or deletes the final file. Checking is done using /usr/bin/cmp. +# * The Exec gets notified by something else - like the concat::fragment define +# - Copies the file over to the final destination using a file resource +# +# ALIASES: +# - The exec can notified using Exec["concat_/path/to/file"] or Exec["concat_/path/to/directory"] +# - The final file can be referened as File["/path/to/file"] or File["concat_/path/to/file"] +define concat($mode = '0644', $owner = $::id, $group = $concat::setup::root_group, $warn = false, $force = false, $backup = 'puppet', $gnu = undef, $order='alpha') { + $safe_name = regsubst($name, '/', '_', 'G') + $concatdir = $concat::setup::concatdir + $version = $concat::setup::majorversion + $fragdir = "${concatdir}/${safe_name}" + $concat_name = 'fragments.concat.out' + $default_warn_message = '# This file is managed by Puppet. DO NOT EDIT.' + + case $warn { + 'true',true,yes,on: { $warnmsg = $default_warn_message } + 'false',false,no,off: { $warnmsg = '' } + default: { $warnmsg = $warn } + } + + $warnmsg_escaped = regsubst($warnmsg, "'", "'\\\\''", 'G') + $warnflag = $warnmsg_escaped ? { + '' => '', + default => "-w '${warnmsg_escaped}'" + } + + case $force { + 'true',true,yes,on: { $forceflag = '-f' } + 'false',false,no,off: { $forceflag = '' } + default: { fail("Improper 'force' value given to concat: ${force}") } + } + + case $order { + numeric: { $orderflag = '-n' } + alpha: { $orderflag = '' } + default: { fail("Improper 'order' value given to concat: ${order}") } + } + + File{ + owner => $::id, + group => $group, + mode => $mode, + backup => $backup + } + + file{$fragdir: + ensure => directory; + + "${fragdir}/fragments": + ensure => directory, + recurse => true, + purge => true, + force => true, + ignore => ['.svn', '.git', '.gitignore'], + source => $version ? { + 24 => 'puppet:///concat/null', + default => undef, + }, + notify => Exec["concat_${name}"]; + + "${fragdir}/fragments.concat": + ensure => present; + + "${fragdir}/${concat_name}": + ensure => present; + + $name: + ensure => present, + source => "${fragdir}/${concat_name}", + owner => $owner, + group => $group, + checksum => md5, + mode => $mode, + alias => "concat_${name}"; + } + + exec{"concat_${name}": + notify => File[$name], + subscribe => File[$fragdir], + alias => "concat_${fragdir}", + require => [ File[$fragdir], File["${fragdir}/fragments"], File["${fragdir}/fragments.concat"] ], + unless => "${concat::setup::concatdir}/bin/concatfragments.sh -o ${fragdir}/${concat_name} -d ${fragdir} -t ${warnflag} ${forceflag} ${orderflag}", + command => "${concat::setup::concatdir}/bin/concatfragments.sh -o ${fragdir}/${concat_name} -d ${fragdir} ${warnflag} ${forceflag} ${orderflag}", + } + if $::id == 'root' { + Exec["concat_${name}"]{ + user => root, + group => $group, + } + } +} diff --git a/puppet/modules/concat/manifests/setup.pp b/puppet/modules/concat/manifests/setup.pp new file mode 100644 index 00000000..38aeb964 --- /dev/null +++ b/puppet/modules/concat/manifests/setup.pp @@ -0,0 +1,49 @@ +# Sets up the concat system. +# +# $concatdir is where the fragments live and is set on the fact concat_basedir. +# Since puppet should always manage files in $concatdir and they should +# not be deleted ever, /tmp is not an option. +# +# $puppetversion should be either 24 or 25 to enable a 24 compatible +# mode, in 24 mode you might see phantom notifies this is a side effect +# of the method we use to clear the fragments directory. +# +# The regular expression below will try to figure out your puppet version +# but this code will only work in 0.24.8 and newer. +# +# It also copies out the concatfragments.sh file to ${concatdir}/bin +class concat::setup { + $id = $::id + $root_group = $id ? { + root => 0, + default => $id + } + + if $::concat_basedir { + $concatdir = $::concat_basedir + } else { + fail ("\$concat_basedir not defined. Try running again with pluginsync enabled") + } + + $majorversion = regsubst($::puppetversion, '^[0-9]+[.]([0-9]+)[.][0-9]+$', '\1') + + file{"${concatdir}/bin/concatfragments.sh": + owner => $id, + group => $root_group, + mode => '0755', + source => $majorversion ? { + 24 => 'puppet:///concat/concatfragments.sh', + default => 'puppet:///modules/concat/concatfragments.sh' + }; + + [ $concatdir, "${concatdir}/bin" ]: + ensure => directory, + owner => $id, + group => $root_group, + mode => '0750'; + + ## Old versions of this module used a different path. + '/usr/local/bin/concatfragments.sh': + ensure => absent; + } +} diff --git a/puppet/modules/concat/spec/defines/init_spec.rb b/puppet/modules/concat/spec/defines/init_spec.rb new file mode 100644 index 00000000..d968a26c --- /dev/null +++ b/puppet/modules/concat/spec/defines/init_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe 'concat' do + basedir = '/var/lib/puppet/concat' + let(:title) { '/etc/foo.bar' } + let(:facts) { { :concat_basedir => '/var/lib/puppet/concat' } } + let :pre_condition do + 'include concat::setup' + end + it { should contain_file("#{basedir}/_etc_foo.bar").with('ensure' => 'directory') } + it { should contain_file("#{basedir}/_etc_foo.bar/fragments").with('ensure' => 'directory') } + + it { should contain_file("#{basedir}/_etc_foo.bar/fragments.concat").with('ensure' => 'present') } + it { should contain_file("/etc/foo.bar").with('ensure' => 'present') } + it { should contain_exec("concat_/etc/foo.bar").with_command( + "#{basedir}/bin/concatfragments.sh "+ + "-o #{basedir}/_etc_foo.bar/fragments.concat.out "+ + "-d #{basedir}/_etc_foo.bar ") + } +end diff --git a/puppet/modules/concat/spec/spec_helper.rb b/puppet/modules/concat/spec/spec_helper.rb new file mode 100644 index 00000000..e6e9309b --- /dev/null +++ b/puppet/modules/concat/spec/spec_helper.rb @@ -0,0 +1,9 @@ +require 'puppet' +require 'rspec' +require 'rspec-puppet' + +RSpec.configure do |c| + c.module_path = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures/modules/')) + # Using an empty site.pp file to avoid: https://github.com/rodjek/rspec-puppet/issues/15 + c.manifest_dir = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures/manifests')) +end -- cgit v1.2.3 From 4ccae8700fb136bfbc6b7ef7bb0ab482e632139f Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:28 -0400 Subject: git subrepo clone https://leap.se/git/puppet_sshd puppet/modules/sshd subrepo: subdir: "puppet/modules/sshd" merged: "76f4f87" upstream: origin: "https://leap.se/git/puppet_sshd" branch: "master" commit: "76f4f87" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: Icf616796837cdbe40deb188d2b72f1c726c9e807 --- puppet/modules/sshd/.fixtures.yml | 3 + puppet/modules/sshd/.gitignore | 4 + puppet/modules/sshd/.gitrepo | 11 + puppet/modules/sshd/.rspec | 4 + puppet/modules/sshd/.travis.yml | 27 + puppet/modules/sshd/Gemfile | 14 + puppet/modules/sshd/Gemfile.lock | 116 ++++ puppet/modules/sshd/LICENSE | 674 +++++++++++++++++++++ puppet/modules/sshd/Modulefile | 10 + puppet/modules/sshd/Puppetfile | 3 + puppet/modules/sshd/Puppetfile.lock | 8 + puppet/modules/sshd/README.md | 247 ++++++++ puppet/modules/sshd/Rakefile | 16 + puppet/modules/sshd/files/autossh.init.d | 164 +++++ puppet/modules/sshd/lib/facter/ssh_version.rb | 5 + .../sshd/lib/puppet/parser/functions/ssh_keygen.rb | 30 + puppet/modules/sshd/manifests/autossh.pp | 40 ++ puppet/modules/sshd/manifests/base.pp | 41 ++ puppet/modules/sshd/manifests/client.pp | 22 + puppet/modules/sshd/manifests/client/base.pp | 15 + puppet/modules/sshd/manifests/client/debian.pp | 5 + puppet/modules/sshd/manifests/client/linux.pp | 5 + puppet/modules/sshd/manifests/debian.pp | 13 + puppet/modules/sshd/manifests/gentoo.pp | 5 + puppet/modules/sshd/manifests/init.pp | 92 +++ puppet/modules/sshd/manifests/libssh2.pp | 7 + puppet/modules/sshd/manifests/libssh2/devel.pp | 7 + puppet/modules/sshd/manifests/linux.pp | 8 + puppet/modules/sshd/manifests/nagios.pp | 24 + puppet/modules/sshd/manifests/openbsd.pp | 8 + puppet/modules/sshd/manifests/redhat.pp | 5 + .../modules/sshd/manifests/ssh_authorized_key.pp | 85 +++ puppet/modules/sshd/manifests/sshkey.pp | 21 + puppet/modules/sshd/spec/classes/client_spec.rb | 42 ++ puppet/modules/sshd/spec/classes/init_spec.rb | 122 ++++ .../sshd/spec/defines/ssh_authorized_key_spec.rb | 45 ++ .../modules/sshd/spec/functions/ssh_keygen_spec.rb | 116 ++++ puppet/modules/sshd/spec/spec_helper.rb | 21 + puppet/modules/sshd/spec/spec_helper_system.rb | 25 + .../sshd/templates/sshd_config/CentOS_5.erb | 1 + .../sshd/templates/sshd_config/CentOS_6.erb | 172 ++++++ .../sshd/templates/sshd_config/CentOS_7.erb | 186 ++++++ .../sshd/templates/sshd_config/Debian_jessie.erb | 124 ++++ .../sshd/templates/sshd_config/Debian_sid.erb | 124 ++++ .../sshd/templates/sshd_config/Debian_squeeze.erb | 127 ++++ .../sshd/templates/sshd_config/Debian_wheezy.erb | 132 ++++ .../modules/sshd/templates/sshd_config/FreeBSD.erb | 168 +++++ .../modules/sshd/templates/sshd_config/Gentoo.erb | 164 +++++ .../modules/sshd/templates/sshd_config/OpenBSD.erb | 144 +++++ .../modules/sshd/templates/sshd_config/Ubuntu.erb | 133 ++++ .../sshd/templates/sshd_config/Ubuntu_lucid.erb | 136 +++++ .../sshd/templates/sshd_config/Ubuntu_oneiric.erb | 1 + .../sshd/templates/sshd_config/Ubuntu_precise.erb | 1 + .../sshd_config/XenServer_xenenterprise.erb | 1 + 54 files changed, 3724 insertions(+) create mode 100644 puppet/modules/sshd/.fixtures.yml create mode 100644 puppet/modules/sshd/.gitignore create mode 100644 puppet/modules/sshd/.gitrepo create mode 100644 puppet/modules/sshd/.rspec create mode 100644 puppet/modules/sshd/.travis.yml create mode 100644 puppet/modules/sshd/Gemfile create mode 100644 puppet/modules/sshd/Gemfile.lock create mode 100644 puppet/modules/sshd/LICENSE create mode 100644 puppet/modules/sshd/Modulefile create mode 100644 puppet/modules/sshd/Puppetfile create mode 100644 puppet/modules/sshd/Puppetfile.lock create mode 100644 puppet/modules/sshd/README.md create mode 100644 puppet/modules/sshd/Rakefile create mode 100644 puppet/modules/sshd/files/autossh.init.d create mode 100644 puppet/modules/sshd/lib/facter/ssh_version.rb create mode 100644 puppet/modules/sshd/lib/puppet/parser/functions/ssh_keygen.rb create mode 100644 puppet/modules/sshd/manifests/autossh.pp create mode 100644 puppet/modules/sshd/manifests/base.pp create mode 100644 puppet/modules/sshd/manifests/client.pp create mode 100644 puppet/modules/sshd/manifests/client/base.pp create mode 100644 puppet/modules/sshd/manifests/client/debian.pp create mode 100644 puppet/modules/sshd/manifests/client/linux.pp create mode 100644 puppet/modules/sshd/manifests/debian.pp create mode 100644 puppet/modules/sshd/manifests/gentoo.pp create mode 100644 puppet/modules/sshd/manifests/init.pp create mode 100644 puppet/modules/sshd/manifests/libssh2.pp create mode 100644 puppet/modules/sshd/manifests/libssh2/devel.pp create mode 100644 puppet/modules/sshd/manifests/linux.pp create mode 100644 puppet/modules/sshd/manifests/nagios.pp create mode 100644 puppet/modules/sshd/manifests/openbsd.pp create mode 100644 puppet/modules/sshd/manifests/redhat.pp create mode 100644 puppet/modules/sshd/manifests/ssh_authorized_key.pp create mode 100644 puppet/modules/sshd/manifests/sshkey.pp create mode 100644 puppet/modules/sshd/spec/classes/client_spec.rb create mode 100644 puppet/modules/sshd/spec/classes/init_spec.rb create mode 100644 puppet/modules/sshd/spec/defines/ssh_authorized_key_spec.rb create mode 100644 puppet/modules/sshd/spec/functions/ssh_keygen_spec.rb create mode 100644 puppet/modules/sshd/spec/spec_helper.rb create mode 100644 puppet/modules/sshd/spec/spec_helper_system.rb create mode 120000 puppet/modules/sshd/templates/sshd_config/CentOS_5.erb create mode 100644 puppet/modules/sshd/templates/sshd_config/CentOS_6.erb create mode 100644 puppet/modules/sshd/templates/sshd_config/CentOS_7.erb create mode 100644 puppet/modules/sshd/templates/sshd_config/Debian_jessie.erb create mode 100644 puppet/modules/sshd/templates/sshd_config/Debian_sid.erb create mode 100644 puppet/modules/sshd/templates/sshd_config/Debian_squeeze.erb create mode 100644 puppet/modules/sshd/templates/sshd_config/Debian_wheezy.erb create mode 100644 puppet/modules/sshd/templates/sshd_config/FreeBSD.erb create mode 100644 puppet/modules/sshd/templates/sshd_config/Gentoo.erb create mode 100644 puppet/modules/sshd/templates/sshd_config/OpenBSD.erb create mode 100644 puppet/modules/sshd/templates/sshd_config/Ubuntu.erb create mode 100644 puppet/modules/sshd/templates/sshd_config/Ubuntu_lucid.erb create mode 120000 puppet/modules/sshd/templates/sshd_config/Ubuntu_oneiric.erb create mode 120000 puppet/modules/sshd/templates/sshd_config/Ubuntu_precise.erb create mode 120000 puppet/modules/sshd/templates/sshd_config/XenServer_xenenterprise.erb (limited to 'puppet/modules') diff --git a/puppet/modules/sshd/.fixtures.yml b/puppet/modules/sshd/.fixtures.yml new file mode 100644 index 00000000..42598a65 --- /dev/null +++ b/puppet/modules/sshd/.fixtures.yml @@ -0,0 +1,3 @@ +fixtures: + symlinks: + sshd: "#{source_dir}" \ No newline at end of file diff --git a/puppet/modules/sshd/.gitignore b/puppet/modules/sshd/.gitignore new file mode 100644 index 00000000..5ebb01fb --- /dev/null +++ b/puppet/modules/sshd/.gitignore @@ -0,0 +1,4 @@ +.librarian/* +.tmp/* +*.log +spec/fixtures/* diff --git a/puppet/modules/sshd/.gitrepo b/puppet/modules/sshd/.gitrepo new file mode 100644 index 00000000..70f55711 --- /dev/null +++ b/puppet/modules/sshd/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_sshd + branch = master + commit = 76f4f872f81209a52df2205fd88b5619df58f003 + parent = b85f8c1b914a09b6001d4c1b5c7d07ef17ac766f + cmdver = 0.3.0 diff --git a/puppet/modules/sshd/.rspec b/puppet/modules/sshd/.rspec new file mode 100644 index 00000000..f07c903a --- /dev/null +++ b/puppet/modules/sshd/.rspec @@ -0,0 +1,4 @@ +--format documentation +--color +--pattern "spec/*/*_spec.rb" +#--backtrace diff --git a/puppet/modules/sshd/.travis.yml b/puppet/modules/sshd/.travis.yml new file mode 100644 index 00000000..7bd2a2bc --- /dev/null +++ b/puppet/modules/sshd/.travis.yml @@ -0,0 +1,27 @@ +before_install: + - gem update --system 2.1.11 + - gem --version +rvm: + - 1.8.7 + - 1.9.3 + - 2.0.0 +script: 'bundle exec rake spec' +env: + - PUPPET_VERSION="~> 2.7.0" + - PUPPET_VERSION="~> 3.0.0" + - PUPPET_VERSION="~> 3.1.0" + - PUPPET_VERSION="~> 3.2.0" + - PUPPET_VERSION="~> 3.3.0" + - PUPPET_VERSION="~> 3.4.0" +matrix: + exclude: + # No support for Ruby 1.9 before Puppet 2.7 + - rvm: 1.9.3 + env: PUPPET_VERSION=2.6.0 + # No support for Ruby 2.0 before Puppet 3.2 + - rvm: 2.0.0 + env: PUPPET_VERSION="~> 2.7.0" + - rvm: 2.0.0 + env: PUPPET_VERSION="~> 3.0.0" + - rvm: 2.0.0 + env: PUPPET_VERSION="~> 3.1.0" diff --git a/puppet/modules/sshd/Gemfile b/puppet/modules/sshd/Gemfile new file mode 100644 index 00000000..ef74f90e --- /dev/null +++ b/puppet/modules/sshd/Gemfile @@ -0,0 +1,14 @@ +source 'https://rubygems.org' + +group :development, :test do + gem 'puppet', '>= 2.7.0' + gem 'puppet-lint', '>=0.3.2' + gem 'puppetlabs_spec_helper', '>=0.2.0' + gem 'rake', '>=0.9.2.2' + gem 'librarian-puppet', '>=0.9.10' + gem 'rspec-system-puppet', :require => false + gem 'serverspec', :require => false + gem 'rspec-system-serverspec', :require => false + gem 'rspec-hiera-puppet' + gem 'rspec-puppet', :git => 'https://github.com/rodjek/rspec-puppet.git' +end \ No newline at end of file diff --git a/puppet/modules/sshd/Gemfile.lock b/puppet/modules/sshd/Gemfile.lock new file mode 100644 index 00000000..0c2c58e9 --- /dev/null +++ b/puppet/modules/sshd/Gemfile.lock @@ -0,0 +1,116 @@ +GIT + remote: https://github.com/rodjek/rspec-puppet.git + revision: c44381a240ec420d4ffda7bffc55ee4d9c08d682 + specs: + rspec-puppet (1.0.1) + rspec + +GEM + remote: https://rubygems.org/ + specs: + builder (3.2.2) + diff-lcs (1.2.5) + excon (0.31.0) + facter (1.7.4) + fog (1.19.0) + builder + excon (~> 0.31.0) + formatador (~> 0.2.0) + mime-types + multi_json (~> 1.0) + net-scp (~> 1.1) + net-ssh (>= 2.1.3) + nokogiri (~> 1.5) + ruby-hmac + formatador (0.2.4) + hiera (1.3.1) + json_pure + hiera-puppet (1.0.0) + hiera (~> 1.0) + highline (1.6.20) + json (1.8.1) + json_pure (1.8.1) + kwalify (0.7.2) + librarian-puppet (0.9.10) + json + thor (~> 0.15) + metaclass (0.0.2) + mime-types (1.25.1) + mocha (1.0.0) + metaclass (~> 0.0.1) + multi_json (1.8.4) + net-scp (1.1.2) + net-ssh (>= 2.6.5) + net-ssh (2.7.0) + nokogiri (1.5.11) + puppet (3.4.2) + facter (~> 1.6) + hiera (~> 1.0) + rgen (~> 0.6.5) + puppet-lint (0.3.2) + puppetlabs_spec_helper (0.4.1) + mocha (>= 0.10.5) + rake + rspec (>= 2.9.0) + rspec-puppet (>= 0.1.1) + rake (10.1.1) + rbvmomi (1.8.1) + builder + nokogiri (>= 1.4.1) + trollop + rgen (0.6.6) + rspec (2.14.1) + rspec-core (~> 2.14.0) + rspec-expectations (~> 2.14.0) + rspec-mocks (~> 2.14.0) + rspec-core (2.14.7) + rspec-expectations (2.14.4) + diff-lcs (>= 1.1.3, < 2.0) + rspec-hiera-puppet (1.0.0) + hiera (>= 1.0) + hiera-puppet (>= 1.0) + puppet (>= 3.0) + rspec + rspec-puppet + rspec-mocks (2.14.4) + rspec-system (2.8.0) + fog (~> 1.18) + kwalify (~> 0.7.2) + mime-types (~> 1.16) + net-scp (~> 1.1) + net-ssh (~> 2.7) + nokogiri (~> 1.5.10) + rbvmomi (~> 1.6) + rspec (~> 2.14) + systemu (~> 2.5) + rspec-system-puppet (2.2.1) + rspec-system (~> 2.0) + rspec-system-serverspec (2.0.1) + rspec-system (~> 2.0) + serverspec (~> 0.0) + specinfra (~> 0.0) + ruby-hmac (0.4.0) + serverspec (0.14.4) + highline + net-ssh + rspec (>= 2.13.0) + specinfra (>= 0.1.0) + specinfra (0.4.1) + systemu (2.6.0) + thor (0.18.1) + trollop (2.0) + +PLATFORMS + ruby + +DEPENDENCIES + librarian-puppet (>= 0.9.10) + puppet (>= 2.7.0) + puppet-lint (>= 0.3.2) + puppetlabs_spec_helper (>= 0.2.0) + rake (>= 0.9.2.2) + rspec-hiera-puppet + rspec-puppet! + rspec-system-puppet + rspec-system-serverspec + serverspec diff --git a/puppet/modules/sshd/LICENSE b/puppet/modules/sshd/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/puppet/modules/sshd/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/puppet/modules/sshd/Modulefile b/puppet/modules/sshd/Modulefile new file mode 100644 index 00000000..5e4f92d6 --- /dev/null +++ b/puppet/modules/sshd/Modulefile @@ -0,0 +1,10 @@ +name 'puppet-sshd' +version '0.1.0' +source 'https://github.com/duritong/puppet-sshd' +author 'duritong' +license 'Apache License, Version 2.0' +summary 'ssh daemon configuration' +description 'Manages sshd_config' +project_page 'https://github.com/duritong/puppet-sshd' + +dependency 'puppetlabs/stdlib', '>= 2.0.0' \ No newline at end of file diff --git a/puppet/modules/sshd/Puppetfile b/puppet/modules/sshd/Puppetfile new file mode 100644 index 00000000..166d3b4d --- /dev/null +++ b/puppet/modules/sshd/Puppetfile @@ -0,0 +1,3 @@ +forge 'http://forge.puppetlabs.com' + +mod 'puppetlabs/stdlib', '>=2.0.0' \ No newline at end of file diff --git a/puppet/modules/sshd/Puppetfile.lock b/puppet/modules/sshd/Puppetfile.lock new file mode 100644 index 00000000..f9381858 --- /dev/null +++ b/puppet/modules/sshd/Puppetfile.lock @@ -0,0 +1,8 @@ +FORGE + remote: http://forge.puppetlabs.com + specs: + puppetlabs/stdlib (4.1.0) + +DEPENDENCIES + puppetlabs/stdlib (>= 2.0.0) + diff --git a/puppet/modules/sshd/README.md b/puppet/modules/sshd/README.md new file mode 100644 index 00000000..77e4d29b --- /dev/null +++ b/puppet/modules/sshd/README.md @@ -0,0 +1,247 @@ +# Puppet SSH Module + +[![Build Status](https://travis-ci.org/duritong/puppet-sshd.png?branch=master)](https://travis-ci.org/duritong/puppet-sshd) + +This puppet module manages OpenSSH configuration and services. + +**!! Upgrade Notice (05/2015) !!** + +The hardened_ssl parameter name was changed to simply 'hardened'. + +**!! Upgrade Notice (01/2013) !!** + +This module now uses parameterized classes, where it used global variables +before. So please whatch out before pulling, you need to change the +class declarations in your manifest ! + + +### Dependencies + +This module requires puppet => 2.6, and the following modules are required +pre-dependencies: + +- [puppetlabs/stdlib](https://github.com/puppetlabs/puppetlabs-stdlib) >= 2.x + +## OpenSSH Server + +On a node where you wish to have an openssh server installed, you should +include + +```puppet +class { 'sshd': } +``` + +on that node. If you need to configure any aspects of sshd_config, set the variables before the include. Or you can adjust many parameters: + +```puppet +class { 'sshd': + ports => [ 20002 ], + permit_root_login => 'no', +} +``` + +See Configurable Variables below for what you can set. + +### Nagios + +To have nagios checks setup automatically for sshd services, simply set +`manage_nagios` to `true` for that class. If you want to disable ssh +nagios checking for a particular node (such as when ssh is firewalled), then you +can set the class parameter `nagios_check_ssh` to `false` and that node will not be +monitored. + +Nagios will automatically check the ports defined in `ports`, and the +hostname specified by `nagios_check_ssh_hostname`. + +Note that if you need to use some specific logic to decide whether or not to +create a nagios service check, you should set $manage_nagios to false, and +use sshd::nagios from within your own manifests. You'll also need to manually +specify the port to that define. By default, if the $port parameter is not +specified, it will use the resource name as the port (e.g. if you call it like +this: `sshd::nagios { '22': }` ) + +NOTE: this requires that you are using the shared-nagios puppet module which +supports the nagios native types via `nagios::service`: + +https://gitlab.com/shared-puppet-modules-group/sshd + +### Firewall + +If you wish to have firewall rules setup automatically for you, using shorewall, +you will need to set: `use_shorewall => true`. The `ports` that you have +specified will automatically be used. + +NOTE: This requires that you are using the shared-shorewall puppet module: +git://labs.riseup.net/shared-shorewall + + +### Configurable variables + +Configuration of sshd is strict, and may not fit all needs, however there are a +number of variables that you can consider configuring. The defaults are set to +the distribution shipped sshd_config file defaults. + +To set any of these variables, simply set them as variables in your manifests, +before the class is included, for example: + +```puppet +class {'sshd': + listen_address => ['10.0.0.1', '192.168.0.1'], + use_pam => yes +} +``` + +If you need to install a version of the ssh daemon or client package other than +the default one that would be installed by `ensure => installed`, then you can +set the following variables: + +```puppet +class {'sshd': + ensure_version => "1:5.2p2-6" +} +``` + +The following is a list of the currently available variables: + + - `listen_address` + specify the addresses sshd should listen on set this to `['10.0.0.1', '192.168.0.1']` to have it listen on both addresses, or leave it unset to listen on all Default: empty -> results in listening on `0.0.0.0` + - `allowed_users` + list of usernames separated by spaces. set this for example to `"foobar + root"` to ensure that only user foobar and root might login. Default: empty + -> no restriction is set + - `allowed_groups` + list of groups separated by spaces. set this for example to `"wheel sftponly"` + to ensure that only users in the groups wheel and sftponly might login. + Default: empty -> no restriction is set Note: This is set after + `allowed_users`, take care of the behaviour if you use these 2 options + together. + - `use_pam` if you want to use pam or not for authenticaton. Values: + - `no` (default) + - `yes` + - `permit_root_login` If you want to allow root logins or not. Valid values: + - `yes` + - `no` + - `without-password` (default) + - `forced-commands-only` + - `password_authentication` + If you want to enable password authentication or not. Valid values: + - `yes` + - `no` (default) + - `kerberos_authentication` + If you want the password that is provided by the user to be validated + through the Kerberos KDC. To use this option the server needs a Kerberos + servtab which allows the verification of the KDC's identity. Valid values: + - `yes` + - `no` (default) + - `kerberos_orlocalpasswd` If password authentication through Kerberos fails, then the password will be validated via any additional local mechanism. Valid values: + - `yes` (default) + - `no` + - `kerberos_ticketcleanup` Destroy the user's ticket cache file on logout? Valid values: + - `yes` (default) + - `no` + - `gssapi_authentication` Authenticate users based on GSSAPI? Valid values: + - `yes` + - `no` (default) + - `gssapi_cleanupcredentials` Destroy user's credential cache on logout? Valid values: + - `yes` (default) + - `no` + - `challenge_response_authentication` If you want to enable ChallengeResponseAuthentication or not When disabled, s/key passwords are disabled. Valid values: + - `yes` + - `no` (default) + - `tcp_forwarding` If you want to enable TcpForwarding. Valid values: + - `yes` + - `no` (default) + - `x11_forwarding` If you want to enable x11 forwarding. Valid values: + - `yes` + - `no` (default) + - `agent_forwarding` If you want to allow ssh-agent forwarding. Valid values: + - `yes` + - `no` (default) + - `pubkey_authentication` If you want to enable public key authentication. Valid values: + - `yes` (default) + - `no` + - `rsa_authentication` If you want to enable RSA Authentication. Valid values: + - `yes` + - `no` (default) + - `rhosts_rsa_authentication` + If you want to enable rhosts RSA Authentication. Valid values: + - `yes` + - `no` (default) + - `hostbased_authentication` If you want to enable `HostbasedAuthentication`. Valid values: + - `yes` + - `no` (default) + - `strict_modes` If you want to set `StrictModes` (check file modes/ownership before accepting login). Valid values: + - `yes` (default) + - `no` + - `permit_empty_passwords` + If you want enable PermitEmptyPasswords to allow empty passwords. Valid + Values: + - `yes` + - `no` (default) + - `ports` If you want to specify a list of ports other than the default `22`; Default: `[22]` + - `authorized_keys_file` + Set this to the location of the AuthorizedKeysFile + (e.g. `/etc/ssh/authorized_keys/%u`). Default: `AuthorizedKeysFile + %h/.ssh/authorized_keys` + - `hardened` + Use only strong ciphers, MAC, KexAlgorithms, etc. + Values: + - `no` (default) + - `yes` + - `print_motd` + Show the Message of the day when a user logs in. + - `sftp_subsystem` + Set a different sftp-subystem than the default one. Might be interesting for + sftponly usage. Default: empty -> no change of the default + - `head_additional_options` + Set this to any additional sshd_options which aren't listed above. Anything + set here will be added to the beginning of the sshd_config file. This option + might be useful to define complicated Match Blocks. This string is going to + be included, like it is defined. So take care! Default: empty -> not added. + - `tail_additional_options` Set this to any additional sshd_options which aren't listed above. Anything set here will be added to the end of the sshd_config file. This option might be useful to define complicated Match Blocks. This string is going to be included, like it is defined. So take care! Default: empty -> not added. + - `shared_ip` Whether the server uses a shared network IP address. If it does, then we don't want it to export an rsa key for its IP address. Values: + - `no` (default) + - `yes` + + +### Defines and functions + +Deploy authorized_keys file with the define `authorized_key`. + +Generate a public/private keypair with the ssh_keygen function. For example, the +following will generate ssh keys and put the different parts of the key into +variables: + +```puppet +$ssh_keys = ssh_keygen("${$ssh_key_basepath}/backup/keys/${::fqdn}/${backup_host}") +$public_key = split($ssh_keys[1],' ') +$sshkey_type => $public_key[0] +$sshkey => $public_key[1] +``` + +## Client + + +On a node where you wish to have the ssh client managed, you can do: + +```puppet +class{'sshd::client': + +} +``` + +in the node definition. This will install the appropriate package. + +## License + + - Copyright 2008-2011, Riseup Labs micah@riseup.net + - Copyright 2008, admin(at)immerda.ch + - Copyright 2008, Puzzle ITC GmbH + - Marcel Härry haerry+puppet(at)puzzle.ch + - Simon Josi josi+puppet(at)puzzle.ch + +This program is free software; you can redistribute +it and/or modify it under the terms of the GNU +General Public License version 3 as published by +the Free Software Foundation. + diff --git a/puppet/modules/sshd/Rakefile b/puppet/modules/sshd/Rakefile new file mode 100644 index 00000000..e3213518 --- /dev/null +++ b/puppet/modules/sshd/Rakefile @@ -0,0 +1,16 @@ +require 'bundler' +Bundler.require(:rake) + +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' +require 'rspec-system/rake_task' + +PuppetLint.configuration.log_format = '%{path}:%{linenumber}:%{KIND}: %{message}' +PuppetLint.configuration.send("disable_80chars") + +puppet_module='sshd' +task :librarian_spec_prep do + sh 'librarian-puppet install --path=spec/fixtures/modules/' +end +task :spec_prep => :librarian_spec_prep +task :default => [:spec, :lint] diff --git a/puppet/modules/sshd/files/autossh.init.d b/puppet/modules/sshd/files/autossh.init.d new file mode 100644 index 00000000..92bd5f43 --- /dev/null +++ b/puppet/modules/sshd/files/autossh.init.d @@ -0,0 +1,164 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: AutoSSH +# Required-Start: $local_fs $network $remote_fs $syslog +# Required-Stop: $local_fs $network $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: start the autossh daemon +# Description: start the autossh daemon +### END INIT INFO + +# Author: Antoine Beaupré + +# Do NOT "set -e" + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC="autossh" +NAME=autossh +USER=$NAME +DAEMON=/usr/bin/autossh +DAEMON_ARGS="-f" +PIDFILE=/var/run/$NAME.pid +SCRIPTNAME=/etc/init.d/$NAME + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +AUTOSSH_PIDFILE=$PIDFILE +export AUTOSSH_PIDFILE + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.2-14) to ensure that this file is present +# and status_of_proc is working. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --user $USER --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --user $USER --chuid $USER --pidfile $PIDFILE --exec $DAEMON -- \ + $DAEMON_ARGS \ + || return 2 + # The above code will not work for interpreted scripts, use the next + # six lines below instead (Ref: #643337, start-stop-daemon(8) ) + #start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON \ + # --name $NAME --test > /dev/null \ + # || return 1 + #start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON \ + # --name $NAME -- $DAEMON_ARGS \ + # || return 2 + + # Add code here, if necessary, that waits for the process to be ready + # to handle requests from services started subsequently which depend + # on this one. As a last resort, sleep for some time. +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --user $USER --name $NAME + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --user $USER --exec $DAEMON + [ "$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME + return 0 +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + reload|force-reload) + log_daemon_msg "Reloading $DESC" "$NAME" + do_reload + log_end_msg $? + ;; + restart) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 + echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 + exit 3 + ;; +esac + +: diff --git a/puppet/modules/sshd/lib/facter/ssh_version.rb b/puppet/modules/sshd/lib/facter/ssh_version.rb new file mode 100644 index 00000000..51d8a00f --- /dev/null +++ b/puppet/modules/sshd/lib/facter/ssh_version.rb @@ -0,0 +1,5 @@ +Facter.add("ssh_version") do + setcode do + ssh_version = Facter::Util::Resolution.exec('ssh -V 2>&1 1>/dev/null').chomp.split(' ')[0].split('_')[1] + end +end diff --git a/puppet/modules/sshd/lib/puppet/parser/functions/ssh_keygen.rb b/puppet/modules/sshd/lib/puppet/parser/functions/ssh_keygen.rb new file mode 100644 index 00000000..e304f242 --- /dev/null +++ b/puppet/modules/sshd/lib/puppet/parser/functions/ssh_keygen.rb @@ -0,0 +1,30 @@ +Puppet::Parser::Functions::newfunction(:ssh_keygen, :type => :rvalue, :doc => + "Returns an array containing the ssh private and public (in this order) key + for a certain private key path. + It will generate the keypair if both do not exist. It will also generate + the directory hierarchy if required. + It accepts only fully qualified paths, everything else will fail.") do |args| + raise Puppet::ParseError, "Wrong number of arguments" unless args.to_a.length == 1 + private_key_path = args.to_a[0] + raise Puppet::ParseError, "Only fully qualified paths are accepted (#{private_key_path})" unless private_key_path =~ /^\/.+/ + public_key_path = "#{private_key_path}.pub" + raise Puppet::ParseError, "Either only the private or only the public key exists" if File.exists?(private_key_path) ^ File.exists?(public_key_path) + [private_key_path,public_key_path].each do |path| + raise Puppet::ParseError, "#{path} is a directory" if File.directory?(path) + end + + dir = File.dirname(private_key_path) + unless File.directory?(dir) + require 'fileutils' + FileUtils.mkdir_p(dir, :mode => 0700) + end + unless [private_key_path,public_key_path].all?{|path| File.exists?(path) } + executor = (Facter.value(:puppetversion).to_i < 3) ? Puppet::Util : Puppet::Util::Execution + output = executor.execute( + ['/usr/bin/ssh-keygen','-t', 'rsa', '-b', '4096', + '-f', private_key_path, '-P', '', '-q']) + raise Puppet::ParseError, "Something went wrong during key generation! Output: #{output}" unless output.empty? + end + [File.read(private_key_path),File.read(public_key_path)] +end + diff --git a/puppet/modules/sshd/manifests/autossh.pp b/puppet/modules/sshd/manifests/autossh.pp new file mode 100644 index 00000000..5650584a --- /dev/null +++ b/puppet/modules/sshd/manifests/autossh.pp @@ -0,0 +1,40 @@ +class sshd::autossh($host, + $port = undef, # this should be a remote->local hash + $remote_user = undef, + $user = 'root', + $pidfile = '/var/run/autossh.pid', +) { + if $port { + $port_ensure = $port + } + else { + # random port between 10000 and 20000 + $port_ensure = fqdn_rand(10000) + 10000 + } + if $remote_user { + $remote_user_ensure = $remote_user + } + else { + $remote_user_ensure = "host-$fqdn" + } + file { + '/etc/init.d/autossh': + mode => '0555', + source => 'puppet:///modules/sshd/autossh.init.d'; + '/etc/default/autossh': + mode => '0444', + content => "USER=$user\nPIDFILE=$pidfile\nDAEMON_ARGS='-M0 -f -o ServerAliveInterval=15 -o ServerAliveCountMax=4 -q -N -R $port_ensure:localhost:22 $remote_user_ensure@$host'\n"; + } + package { 'autossh': + ensure => present, + } + service { 'autossh': + ensure => running, + enable => true, + subscribe => [ + File['/etc/init.d/autossh'], + File['/etc/default/autossh'], + Package['autossh'], + ], + } +} diff --git a/puppet/modules/sshd/manifests/base.pp b/puppet/modules/sshd/manifests/base.pp new file mode 100644 index 00000000..dda9f26c --- /dev/null +++ b/puppet/modules/sshd/manifests/base.pp @@ -0,0 +1,41 @@ +# The base class to setup the common things. +# This is a private class and will always be used +# throught the sshd class itself. +class sshd::base { + + $sshd_config_content = $::operatingsystem ? { + 'CentOS' => template("sshd/sshd_config/${::operatingsystem}_${::operatingsystemmajrelease}.erb"), + default => $::lsbdistcodename ? { + '' => template("sshd/sshd_config/${::operatingsystem}.erb"), + default => template("sshd/sshd_config/${::operatingsystem}_${::lsbdistcodename}.erb") + } + } + + file { 'sshd_config': + ensure => present, + path => '/etc/ssh/sshd_config', + content => $sshd_config_content, + notify => Service[sshd], + owner => root, + group => 0, + mode => '0600'; + } + + # Now add the key, if we've got one + case $::sshrsakey { + '': { info("no sshrsakey on ${::fqdn}") } + default: { + # only export sshkey when storedconfigs is enabled + if $::sshd::use_storedconfigs { + include ::sshd::sshkey + } + } + } + service{'sshd': + ensure => running, + name => 'sshd', + enable => true, + hasstatus => true, + require => File[sshd_config], + } +} diff --git a/puppet/modules/sshd/manifests/client.pp b/puppet/modules/sshd/manifests/client.pp new file mode 100644 index 00000000..84dd7abc --- /dev/null +++ b/puppet/modules/sshd/manifests/client.pp @@ -0,0 +1,22 @@ +# manifests/client.pp + +class sshd::client( + $shared_ip = 'no', + $ensure_version = 'installed', + $manage_shorewall = false +) { + + case $::operatingsystem { + debian,ubuntu: { include sshd::client::debian } + default: { + case $::kernel { + linux: { include sshd::client::linux } + default: { include sshd::client::base } + } + } + } + + if $manage_shorewall{ + include shorewall::rules::out::ssh + } +} diff --git a/puppet/modules/sshd/manifests/client/base.pp b/puppet/modules/sshd/manifests/client/base.pp new file mode 100644 index 00000000..4925c2d0 --- /dev/null +++ b/puppet/modules/sshd/manifests/client/base.pp @@ -0,0 +1,15 @@ +class sshd::client::base { + # this is needed because the gid might have changed + file { '/etc/ssh/ssh_known_hosts': + ensure => present, + mode => '0644', + owner => root, + group => 0; + } + + # Now collect all server keys + case $sshd::client::shared_ip { + no: { Sshkey <<||>> } + yes: { Sshkey <<| tag == fqdn |>> } + } +} diff --git a/puppet/modules/sshd/manifests/client/debian.pp b/puppet/modules/sshd/manifests/client/debian.pp new file mode 100644 index 00000000..2aaf3fb1 --- /dev/null +++ b/puppet/modules/sshd/manifests/client/debian.pp @@ -0,0 +1,5 @@ +class sshd::client::debian inherits sshd::client::linux { + Package['openssh-clients']{ + name => 'openssh-client', + } +} diff --git a/puppet/modules/sshd/manifests/client/linux.pp b/puppet/modules/sshd/manifests/client/linux.pp new file mode 100644 index 00000000..0c420be2 --- /dev/null +++ b/puppet/modules/sshd/manifests/client/linux.pp @@ -0,0 +1,5 @@ +class sshd::client::linux inherits sshd::client::base { + package {'openssh-clients': + ensure => $sshd::client::ensure_version, + } +} diff --git a/puppet/modules/sshd/manifests/debian.pp b/puppet/modules/sshd/manifests/debian.pp new file mode 100644 index 00000000..d827078a --- /dev/null +++ b/puppet/modules/sshd/manifests/debian.pp @@ -0,0 +1,13 @@ +class sshd::debian inherits sshd::linux { + + Package[openssh]{ + name => 'openssh-server', + } + + Service[sshd]{ + name => 'ssh', + pattern => 'sshd', + hasstatus => true, + hasrestart => true, + } +} diff --git a/puppet/modules/sshd/manifests/gentoo.pp b/puppet/modules/sshd/manifests/gentoo.pp new file mode 100644 index 00000000..631f3d19 --- /dev/null +++ b/puppet/modules/sshd/manifests/gentoo.pp @@ -0,0 +1,5 @@ +class sshd::gentoo inherits sshd::linux { + Package[openssh]{ + category => 'net-misc', + } +} diff --git a/puppet/modules/sshd/manifests/init.pp b/puppet/modules/sshd/manifests/init.pp new file mode 100644 index 00000000..b4157418 --- /dev/null +++ b/puppet/modules/sshd/manifests/init.pp @@ -0,0 +1,92 @@ +# manage an sshd installation +class sshd( + $manage_nagios = false, + $nagios_check_ssh_hostname = 'absent', + $ports = [ 22 ], + $shared_ip = 'no', + $ensure_version = 'installed', + $listen_address = [ '0.0.0.0', '::' ], + $allowed_users = '', + $allowed_groups = '', + $use_pam = 'no', + $permit_root_login = 'without-password', + $password_authentication = 'no', + $kerberos_authentication = 'no', + $kerberos_orlocalpasswd = 'yes', + $kerberos_ticketcleanup = 'yes', + $gssapi_authentication = 'no', + $gssapi_cleanupcredentials = 'yes', + $tcp_forwarding = 'no', + $x11_forwarding = 'no', + $agent_forwarding = 'no', + $challenge_response_authentication = 'no', + $pubkey_authentication = 'yes', + $rsa_authentication = 'no', + $strict_modes = 'yes', + $ignore_rhosts = 'yes', + $rhosts_rsa_authentication = 'no', + $hostbased_authentication = 'no', + $permit_empty_passwords = 'no', + $authorized_keys_file = $::osfamily ? { + Debian => $::lsbmajdistrelease ? { + 6 => '%h/.ssh/authorized_keys', + default => '%h/.ssh/authorized_keys %h/.ssh/authorized_keys2', + }, + RedHat => $::operatingsystemmajrelease ? { + 5 => '%h/.ssh/authorized_keys', + 6 => '%h/.ssh/authorized_keys', + default => '%h/.ssh/authorized_keys %h/.ssh/authorized_keys2', + }, + OpenBSD => '%h/.ssh/authorized_keys', + default => '%h/.ssh/authorized_keys %h/.ssh/authorized_keys2', + }, + $hardened = 'no', + $sftp_subsystem = '', + $head_additional_options = '', + $tail_additional_options = '', + $print_motd = 'yes', + $manage_shorewall = false, + $shorewall_source = 'net', + $sshkey_ipaddress = $::ipaddress, + $manage_client = true, + $hostkey_type = versioncmp($::ssh_version, '6.5') ? { + /(^1|0)/ => [ 'rsa', 'ed25519' ], + /-1/ => [ 'rsa', 'dsa' ] + }, + $use_storedconfigs = true +) { + + validate_bool($manage_shorewall) + validate_bool($manage_client) + validate_array($listen_address) + validate_array($ports) + + if $manage_client { + class{'sshd::client': + shared_ip => $shared_ip, + ensure_version => $ensure_version, + manage_shorewall => $manage_shorewall, + } + } + + case $::operatingsystem { + gentoo: { include sshd::gentoo } + redhat,centos: { include sshd::redhat } + openbsd: { include sshd::openbsd } + debian,ubuntu: { include sshd::debian } + default: { include sshd::base } + } + + if $manage_nagios { + sshd::nagios{$ports: + check_hostname => $nagios_check_ssh_hostname + } + } + + if $manage_shorewall { + class{'shorewall::rules::ssh': + ports => $ports, + source => $shorewall_source + } + } +} diff --git a/puppet/modules/sshd/manifests/libssh2.pp b/puppet/modules/sshd/manifests/libssh2.pp new file mode 100644 index 00000000..403ac7be --- /dev/null +++ b/puppet/modules/sshd/manifests/libssh2.pp @@ -0,0 +1,7 @@ +# manifests/libssh2.pp + +class sshd::libssh2 { + package{'libssh2': + ensure => present, + } +} diff --git a/puppet/modules/sshd/manifests/libssh2/devel.pp b/puppet/modules/sshd/manifests/libssh2/devel.pp new file mode 100644 index 00000000..261e34c8 --- /dev/null +++ b/puppet/modules/sshd/manifests/libssh2/devel.pp @@ -0,0 +1,7 @@ +# manifests/libssh2/devel.pp + +class sshd::libssh2::devel inherits sshd::libssh2 { + package{"libssh2-devel.${::architecture}": + ensure => installed, + } +} diff --git a/puppet/modules/sshd/manifests/linux.pp b/puppet/modules/sshd/manifests/linux.pp new file mode 100644 index 00000000..8628ff5e --- /dev/null +++ b/puppet/modules/sshd/manifests/linux.pp @@ -0,0 +1,8 @@ +class sshd::linux inherits sshd::base { + package{'openssh': + ensure => $sshd::ensure_version, + } + File[sshd_config]{ + require +> Package[openssh], + } +} diff --git a/puppet/modules/sshd/manifests/nagios.pp b/puppet/modules/sshd/manifests/nagios.pp new file mode 100644 index 00000000..6921de91 --- /dev/null +++ b/puppet/modules/sshd/manifests/nagios.pp @@ -0,0 +1,24 @@ +define sshd::nagios( + $port = 'absent', + $ensure = 'present', + $check_hostname = 'absent' +) { + $real_port = $port ? { + 'absent' => $name, + default => $port, + } + case $check_hostname { + 'absent': { + nagios::service{"ssh_port_${name}": + ensure => $ensure, + check_command => "check_ssh_port!${real_port}" + } + } + default: { + nagios::service{"ssh_port_host_${name}": + ensure => $ensure, + check_command => "check_ssh_port_host!${real_port}!${check_hostname}" + } + } + } +} diff --git a/puppet/modules/sshd/manifests/openbsd.pp b/puppet/modules/sshd/manifests/openbsd.pp new file mode 100644 index 00000000..cb6dbba6 --- /dev/null +++ b/puppet/modules/sshd/manifests/openbsd.pp @@ -0,0 +1,8 @@ +class sshd::openbsd inherits sshd::base { + Service[sshd]{ + restart => '/bin/kill -HUP `/bin/cat /var/run/sshd.pid`', + stop => '/bin/kill `/bin/cat /var/run/sshd.pid`', + start => '/usr/sbin/sshd', + status => '/usr/bin/pgrep -f /usr/sbin/sshd', + } +} diff --git a/puppet/modules/sshd/manifests/redhat.pp b/puppet/modules/sshd/manifests/redhat.pp new file mode 100644 index 00000000..d7201774 --- /dev/null +++ b/puppet/modules/sshd/manifests/redhat.pp @@ -0,0 +1,5 @@ +class sshd::redhat inherits sshd::linux { + Package[openssh]{ + name => 'openssh-server', + } +} diff --git a/puppet/modules/sshd/manifests/ssh_authorized_key.pp b/puppet/modules/sshd/manifests/ssh_authorized_key.pp new file mode 100644 index 00000000..80cb3b70 --- /dev/null +++ b/puppet/modules/sshd/manifests/ssh_authorized_key.pp @@ -0,0 +1,85 @@ +# wrapper to have some defaults. +define sshd::ssh_authorized_key( + $ensure = 'present', + $type = 'ssh-dss', + $key = 'absent', + $user = '', + $target = undef, + $options = 'absent', + $override_builtin = undef +){ + + if ($ensure=='present') and ($key=='absent') { + fail("You have to set \$key for Sshd::Ssh_authorized_key[${name}]!") + } + + $real_user = $user ? { + false => $name, + '' => $name, + default => $user, + } + + case $target { + undef,'': { + case $real_user { + 'root': { $real_target = '/root/.ssh/authorized_keys' } + default: { $real_target = "/home/${real_user}/.ssh/authorized_keys" } + } + } + default: { + $real_target = $target + } + } + + # The ssh_authorized_key built-in function (in 2.7.23 at least) + # will not write an authorized_keys file for a mortal user to + # a directory they don't have write permission to, puppet attempts to + # create the file as the user specified with the user parameter and fails. + # Since ssh will refuse to use authorized_keys files not owned by the + # user, or in files/directories that allow other users to write, this + # behavior is deliberate in order to prevent typical non-working + # configurations. However, it also prevents the case of puppet, running + # as root, writing a file owned by a mortal user to a common + # authorized_keys directory such as one might specify in sshd_config with + # something like + # 'AuthorizedKeysFile /etc/ssh/authorized_keys/%u' + # So we provide a way to override the built-in and instead just install + # via a file resource. There is no additional security risk here, it's + # nothing a user can't already do by writing their own file resources, + # we still depend on the filesystem permissions to keep things safe. + if $override_builtin { + $header = "# HEADER: This file is managed by Puppet.\n" + + if $options == 'absent' { + info("not setting any option for ssh_authorized_key: ${name}") + $content = "${header}${type} ${key}\n" + } else { + $content = "${header}${options} ${type} ${key}\n" + } + + file { $real_target: + ensure => $ensure, + content => $content, + owner => $real_user, + mode => '0600', + } + + } else { + + if $options == 'absent' { + info("not setting any option for ssh_authorized_key: ${name}") + } else { + $real_options = $options + } + + ssh_authorized_key{$name: + ensure => $ensure, + type => $type, + key => $key, + user => $real_user, + target => $real_target, + options => $real_options, + } + } + +} diff --git a/puppet/modules/sshd/manifests/sshkey.pp b/puppet/modules/sshd/manifests/sshkey.pp new file mode 100644 index 00000000..df37a66c --- /dev/null +++ b/puppet/modules/sshd/manifests/sshkey.pp @@ -0,0 +1,21 @@ +# deploys the +class sshd::sshkey { + + @@sshkey{$::fqdn: + ensure => present, + tag => 'fqdn', + type => 'ssh-rsa', + key => $::sshrsakey, + } + + # In case the node has uses a shared network address, + # we don't define a sshkey resource using an IP address + if $sshd::shared_ip == 'no' { + @@sshkey{$::sshd::sshkey_ipaddress: + ensure => present, + tag => 'ipaddress', + type => 'ssh-rsa', + key => $::sshrsakey, + } + } +} diff --git a/puppet/modules/sshd/spec/classes/client_spec.rb b/puppet/modules/sshd/spec/classes/client_spec.rb new file mode 100644 index 00000000..bd3e35af --- /dev/null +++ b/puppet/modules/sshd/spec/classes/client_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe 'sshd::client' do + + shared_examples "a Linux OS" do + it { should contain_file('/etc/ssh/ssh_known_hosts').with( + { + 'ensure' => 'present', + 'owner' => 'root', + 'group' => '0', + 'mode' => '0644', + } + )} + end + + context "Debian OS" do + let :facts do + { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'wheezy', + } + end + it_behaves_like "a Linux OS" + it { should contain_package('openssh-clients').with({ + 'name' => 'openssh-client' + }) } + end + + context "CentOS" do + it_behaves_like "a Linux OS" do + let :facts do + { + :operatingsystem => 'CentOS', + :osfamily => 'RedHat', + :lsbdistcodename => 'Final', + } + end + end + end + +end \ No newline at end of file diff --git a/puppet/modules/sshd/spec/classes/init_spec.rb b/puppet/modules/sshd/spec/classes/init_spec.rb new file mode 100644 index 00000000..e3003d14 --- /dev/null +++ b/puppet/modules/sshd/spec/classes/init_spec.rb @@ -0,0 +1,122 @@ +require 'spec_helper' + +describe 'sshd' do + + shared_examples "a Linux OS" do + it { should compile.with_all_deps } + it { should contain_class('sshd') } + it { should contain_class('sshd::client') } + + it { should contain_service('sshd').with({ + :ensure => 'running', + :enable => true, + :hasstatus => true + })} + + it { should contain_file('sshd_config').with( + { + 'ensure' => 'present', + 'owner' => 'root', + 'group' => '0', + 'mode' => '0600', + } + )} + + context 'change ssh port' do + let(:params){{ + :ports => [ 22222], + }} + it { should contain_file( + 'sshd_config' + ).with_content(/Port 22222/)} + end + end + + context "Debian OS" do + let :facts do + { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'wheezy', + } + end + it_behaves_like "a Linux OS" + it { should contain_package('openssh') } + it { should contain_class('sshd::debian') } + it { should contain_service('sshd').with( + :hasrestart => true + )} + + context "Ubuntu" do + let :facts do + { + :operatingsystem => 'Ubuntu', + :lsbdistcodename => 'precise', + } + end + it_behaves_like "a Linux OS" + it { should contain_package('openssh') } + it { should contain_service('sshd').with({ + :hasrestart => true + })} + end + end + + +# context "RedHat OS" do +# it_behaves_like "a Linux OS" do +# let :facts do +# { +# :operatingsystem => 'RedHat', +# :osfamily => 'RedHat', +# } +# end +# end +# end + + context "CentOS" do + it_behaves_like "a Linux OS" do + let :facts do + { + :operatingsystem => 'CentOS', + :osfamily => 'RedHat', + :lsbdistcodename => 'Final', + } + end + end + end + + context "Gentoo" do + let :facts do + { + :operatingsystem => 'Gentoo', + :osfamily => 'Gentoo', + } + end + it_behaves_like "a Linux OS" + it { should contain_class('sshd::gentoo') } + end + + context "OpenBSD" do + let :facts do + { + :operatingsystem => 'OpenBSD', + :osfamily => 'OpenBSD', + } + end + it_behaves_like "a Linux OS" + it { should contain_class('sshd::openbsd') } + end + +# context "FreeBSD" do +# it_behaves_like "a Linux OS" do +# let :facts do +# { +# :operatingsystem => 'FreeBSD', +# :osfamily => 'FreeBSD', +# } +# end +# end +# end + +end \ No newline at end of file diff --git a/puppet/modules/sshd/spec/defines/ssh_authorized_key_spec.rb b/puppet/modules/sshd/spec/defines/ssh_authorized_key_spec.rb new file mode 100644 index 00000000..c73a91cc --- /dev/null +++ b/puppet/modules/sshd/spec/defines/ssh_authorized_key_spec.rb @@ -0,0 +1,45 @@ +require 'spec_helper' + +describe 'sshd::ssh_authorized_key' do + + context 'manage authorized key' do + let(:title) { 'foo' } + let(:ssh_key) { 'some_secret_ssh_key' } + + let(:params) {{ + :key => ssh_key, + }} + + it { should contain_ssh_authorized_key('foo').with({ + 'ensure' => 'present', + 'type' => 'ssh-dss', + 'user' => 'foo', + 'target' => '/home/foo/.ssh/authorized_keys', + 'key' => ssh_key, + }) + } + end + context 'manage authoried key with options' do + let(:title) { 'foo2' } + let(:ssh_key) { 'some_secret_ssh_key' } + + let(:params) {{ + :key => ssh_key, + :options => ['command="/usr/bin/date"', + 'no-pty','no-X11-forwarding','no-agent-forwarding', + 'no-port-forwarding'] + }} + + it { should contain_ssh_authorized_key('foo2').with({ + 'ensure' => 'present', + 'type' => 'ssh-dss', + 'user' => 'foo2', + 'target' => '/home/foo2/.ssh/authorized_keys', + 'key' => ssh_key, + 'options' => ['command="/usr/bin/date"', + 'no-pty','no-X11-forwarding','no-agent-forwarding', + 'no-port-forwarding'] + }) + } + end +end diff --git a/puppet/modules/sshd/spec/functions/ssh_keygen_spec.rb b/puppet/modules/sshd/spec/functions/ssh_keygen_spec.rb new file mode 100644 index 00000000..a6b51173 --- /dev/null +++ b/puppet/modules/sshd/spec/functions/ssh_keygen_spec.rb @@ -0,0 +1,116 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' +require 'rspec-puppet' +require 'mocha' +require 'fileutils' + +describe 'ssh_keygen' do + + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it 'should exist' do + Puppet::Parser::Functions.function("ssh_keygen").should == "function_ssh_keygen" + end + + it 'should raise a ParseError if no argument is passed' do + lambda { + scope.function_ssh_keygen([]) + }.should(raise_error(Puppet::ParseError)) + end + + it 'should raise a ParseError if there is more than 1 arguments' do + lambda { + scope.function_ssh_keygen(["foo", "bar"]) + }.should( raise_error(Puppet::ParseError)) + end + + it 'should raise a ParseError if the argument is not fully qualified' do + lambda { + scope.function_ssh_keygen(["foo"]) + }.should( raise_error(Puppet::ParseError)) + end + + it "should raise a ParseError if the private key path is a directory" do + File.stubs(:directory?).with("/some_dir").returns(true) + lambda { + scope.function_ssh_keygen(["/some_dir"]) + }.should( raise_error(Puppet::ParseError)) + end + + it "should raise a ParseError if the public key path is a directory" do + File.stubs(:directory?).with("/some_dir.pub").returns(true) + lambda { + scope.function_ssh_keygen(["/some_dir.pub"]) + }.should( raise_error(Puppet::ParseError)) + end + + describe 'when executing properly' do + before do + File.stubs(:directory?).with('/tmp/a/b/c').returns(false) + File.stubs(:directory?).with('/tmp/a/b/c.pub').returns(false) + File.stubs(:read).with('/tmp/a/b/c').returns('privatekey') + File.stubs(:read).with('/tmp/a/b/c.pub').returns('publickey') + end + + it 'should fail if the public but not the private key exists' do + File.stubs(:exists?).with('/tmp/a/b/c').returns(true) + File.stubs(:exists?).with('/tmp/a/b/c.pub').returns(false) + lambda { + scope.function_ssh_keygen(['/tmp/a/b/c']) + }.should( raise_error(Puppet::ParseError)) + end + + it "should fail if the private but not the public key exists" do + File.stubs(:exists?).with("/tmp/a/b/c").returns(false) + File.stubs(:exists?).with("/tmp/a/b/c.pub").returns(true) + lambda { + scope.function_ssh_keygen(["/tmp/a/b/c"]) + }.should( raise_error(Puppet::ParseError)) + end + + + it "should return an array of size 2 with the right conent if the keyfiles exists" do + File.stubs(:exists?).with("/tmp/a/b/c").returns(true) + File.stubs(:exists?).with("/tmp/a/b/c.pub").returns(true) + File.stubs(:directory?).with('/tmp/a/b').returns(true) + Puppet::Util.expects(:execute).never + result = scope.function_ssh_keygen(['/tmp/a/b/c']) + result.length.should == 2 + result[0].should == 'privatekey' + result[1].should == 'publickey' + end + + it "should create the directory path if it does not exist" do + File.stubs(:exists?).with("/tmp/a/b/c").returns(false) + File.stubs(:exists?).with("/tmp/a/b/c.pub").returns(false) + File.stubs(:directory?).with("/tmp/a/b").returns(false) + FileUtils.expects(:mkdir_p).with("/tmp/a/b", :mode => 0700) + Puppet::Util::Execution.expects(:execute).returns("") + result = scope.function_ssh_keygen(['/tmp/a/b/c']) + result.length.should == 2 + result[0].should == 'privatekey' + result[1].should == 'publickey' + end + + it "should generate the key if the keyfiles do not exist" do + File.stubs(:exists?).with("/tmp/a/b/c").returns(false) + File.stubs(:exists?).with("/tmp/a/b/c.pub").returns(false) + File.stubs(:directory?).with("/tmp/a/b").returns(true) + Puppet::Util::Execution.expects(:execute).with(['/usr/bin/ssh-keygen','-t', 'rsa', '-b', '4096', '-f', '/tmp/a/b/c', '-P', '', '-q']).returns("") + result = scope.function_ssh_keygen(['/tmp/a/b/c']) + result.length.should == 2 + result[0].should == 'privatekey' + result[1].should == 'publickey' + end + + it "should fail if something goes wrong during generation" do + File.stubs(:exists?).with("/tmp/a/b/c").returns(false) + File.stubs(:exists?).with("/tmp/a/b/c.pub").returns(false) + File.stubs(:directory?).with("/tmp/a/b").returns(true) + Puppet::Util::Execution.expects(:execute).with(['/usr/bin/ssh-keygen','-t', 'rsa', '-b', '4096', '-f', '/tmp/a/b/c', '-P', '', '-q']).returns("something is wrong") + lambda { + scope.function_ssh_keygen(["/tmp/a/b/c"]) + }.should( raise_error(Puppet::ParseError)) + end + end +end diff --git a/puppet/modules/sshd/spec/spec_helper.rb b/puppet/modules/sshd/spec/spec_helper.rb new file mode 100644 index 00000000..b4123fde --- /dev/null +++ b/puppet/modules/sshd/spec/spec_helper.rb @@ -0,0 +1,21 @@ +dir = File.expand_path(File.dirname(__FILE__)) +$LOAD_PATH.unshift File.join(dir, 'lib') +require 'puppet' +require 'rspec' +require 'puppetlabs_spec_helper/module_spec_helper' +#require 'rspec-hiera-puppet' +require 'rspec-puppet/coverage' +require 'rspec/autorun' + +fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures')) + +RSpec.configure do |c| + c.module_path = File.join(fixture_path, 'modules') + c.manifest_dir = File.join(fixture_path, 'manifests') + c.pattern = "spec/*/*_spec.rb" +end + +Puppet::Util::Log.level = :warning +Puppet::Util::Log.newdestination(:console) + +at_exit { RSpec::Puppet::Coverage.report! } \ No newline at end of file diff --git a/puppet/modules/sshd/spec/spec_helper_system.rb b/puppet/modules/sshd/spec/spec_helper_system.rb new file mode 100644 index 00000000..2c6812fc --- /dev/null +++ b/puppet/modules/sshd/spec/spec_helper_system.rb @@ -0,0 +1,25 @@ +require 'rspec-system/spec_helper' +require 'rspec-system-puppet/helpers' +require 'rspec-system-serverspec/helpers' +include Serverspec::Helper::RSpecSystem +include Serverspec::Helper::DetectOS +include RSpecSystemPuppet::Helpers + +RSpec.configure do |c| + # Project root + proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + # Enable colour + c.tty = true + + c.include RSpecSystemPuppet::Helpers + + # This is where we 'setup' the nodes before running our tests + c.before :suite do + # Install puppet + puppet_install + # Install modules and dependencies + puppet_module_install(:source => proj_root, :module_name => 'sshd') + shell('puppet module install puppetlabs-stdlib') + end +end diff --git a/puppet/modules/sshd/templates/sshd_config/CentOS_5.erb b/puppet/modules/sshd/templates/sshd_config/CentOS_5.erb new file mode 120000 index 00000000..71b767a5 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/CentOS_5.erb @@ -0,0 +1 @@ +CentOS_6.erb \ No newline at end of file diff --git a/puppet/modules/sshd/templates/sshd_config/CentOS_6.erb b/puppet/modules/sshd/templates/sshd_config/CentOS_6.erb new file mode 100644 index 00000000..4593a91a --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/CentOS_6.erb @@ -0,0 +1,172 @@ +# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options change a +# default value. + +<% unless (s=scope.lookupvar('::sshd::head_additional_options')).empty? -%> +<%= s %> +<% end -%> + +<% scope.lookupvar('::sshd::ports').to_a.each do |port| -%> +<% if port == 'off' -%> +#Port -- disabled by puppet +<% else -%> +Port <%= port %> +<% end -%> +<% end -%> + +# Use these options to restrict which interfaces/protocols sshd will bind to +<% scope.lookupvar('::sshd::listen_address').to_a.each do |address| -%> +ListenAddress <%= address %> +<% end -%> + +# Disable legacy (protocol version 1) support in the server for new +# installations. In future the default will change to require explicit +# activation of protocol 1 +Protocol 2 + +# HostKey for protocol version 1 +#HostKey /etc/ssh/ssh_host_key +# HostKeys for protocol version 2 +#HostKey /etc/ssh/ssh_host_rsa_key +#HostKey /etc/ssh/ssh_host_dsa_key + +# Lifetime and size of ephemeral version 1 server key +#KeyRegenerationInterval 1h +#ServerKeyBits 1024 + +# Logging +# obsoletes QuietMode and FascistLogging +#SyslogFacility AUTH +SyslogFacility AUTHPRIV +#LogLevel INFO + +# Authentication: + +#LoginGraceTime 2m +PermitRootLogin <%= scope.lookupvar('::sshd::permit_root_login') %> + +StrictModes <%= scope.lookupvar('::sshd::strict_modes') %> + +#MaxAuthTries 6 + +RSAAuthentication <%= scope.lookupvar('::sshd::rsa_authentication') %> +PubkeyAuthentication <%= scope.lookupvar('::sshd::pubkey_authentication') %> +AuthorizedKeysFile <%= scope.lookupvar('::sshd::authorized_keys_file') %> +#AuthorizedKeysCommand none +#AuthorizedKeysCommandRunAs nobody + +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts +RhostsRSAAuthentication <%= scope.lookupvar('::sshd::rhosts_rsa_authentication') %> + +# similar for protocol version 2 +HostbasedAuthentication <%= scope.lookupvar('::sshd::hostbased_authentication') %> + +# Change to yes if you don't trust ~/.ssh/known_hosts for +# RhostsRSAAuthentication and HostbasedAuthentication +#IgnoreUserKnownHosts no + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts <%= scope.lookupvar('::sshd::ignore_rhosts') %> + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication <%= scope.lookupvar('::sshd::password_authentication') %> + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords <%= scope.lookupvar('::sshd::permit_empty_passwords') %> + +# Change to no to disable s/key passwords +ChallengeResponseAuthentication <%= scope.lookupvar('::sshd::challenge_response_authentication') %> + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no +#KerberosUseKuserok yes + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +#UsePAM no +UsePAM <%= scope.lookupvar('::sshd::use_pam') %> + +# Accept locale-related environment variables +AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES +AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT +AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE +AcceptEnv XMODIFIERS + +#AllowAgentForwarding yes +AllowTcpForwarding <%= scope.lookupvar('::sshd::tcp_forwarding') %> +#GatewayPorts no +#X11Forwarding no +X11Forwarding <%= scope.lookupvar('::sshd::x11_forwarding') %> +#X11DisplayOffset 10 +#X11UseLocalhost yes +PrintMotd <%= scope.lookupvar('::sshd::print_motd') %> +#PrintLastLog yes +#TCPKeepAlive yes +#UseLogin no +#UsePrivilegeSeparation yes +#PermitUserEnvironment no +#Compression delayed +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#ShowPatchLevel no +#UseDNS yes +#PidFile /var/run/sshd.pid +#MaxStartups 10:30:100 +#PermitTunnel no +#ChrootDirectory none + +# no default banner path +#Banner /some/path + +# override default of no subsystems +Subsystem sftp <%= (s=scope.lookupvar('::sshd::sftp_subsystem')).empty? ? '/usr/libexec/openssh/sftp-server' : s %> + +<% unless (s=scope.lookupvar('::sshd::allowed_users')).empty? -%> +AllowUsers <%= s %> +<% end -%> +<% unless (s=scope.lookupvar('::sshd::allowed_groups')).empty? -%> +AllowGroups <%= s %> +<%- end -%> + +<% if scope.lookupvar('::sshd::hardened') == 'yes' -%> +<% if (scope.function_versioncmp([scope.lookupvar('::ssh_version'),'6.5'])) >= 0 -%> +KexAlgorithms curve25519-sha256@libssh.org +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com +<% else -%> +Ciphers aes256-ctr +MACs hmac-sha1 +<% end -%> +<% end -%> + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# ForceCommand cvs server +# +<% unless (s=scope.lookupvar('::sshd::tail_additional_options')).empty? -%> +<%= s %> +<% end -%> diff --git a/puppet/modules/sshd/templates/sshd_config/CentOS_7.erb b/puppet/modules/sshd/templates/sshd_config/CentOS_7.erb new file mode 100644 index 00000000..f55fb9d0 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/CentOS_7.erb @@ -0,0 +1,186 @@ +# $OpenBSD: sshd_config,v 1.90 2013/05/16 04:09:14 dtucker Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options change a +# default value. + +<% unless (s=scope.lookupvar('::sshd::head_additional_options')).empty? -%> +<%= s %> +<% end -%> + +# If you want to change the port on a SELinux system, you have to tell +# SELinux about this change. +# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER +# +<% scope.lookupvar('::sshd::ports').to_a.each do |port| -%> +<% if port == 'off' -%> +#Port -- disabled by puppet +<% else -%> +Port <%= port %> +<% end -%> +<% end -%> +<% scope.lookupvar('::sshd::listen_address').to_a.each do |address| -%> +ListenAddress <%= address %> +<% end -%> + +# The default requires explicit activation of protocol 1 +#Protocol 2 + +# HostKey for protocol version 1 +#HostKey /etc/ssh/ssh_host_key +# HostKeys for protocol version 2 +<% scope.lookupvar('::sshd::hostkey_type').to_a.each do |hostkey_type| -%> +HostKey /etc/ssh/ssh_host_<%=hostkey_type %>_key +<% end -%> + +# Lifetime and size of ephemeral version 1 server key +#KeyRegenerationInterval 1h +#ServerKeyBits 1024 + +# Ciphers and keying +#RekeyLimit default none + +# Logging +# obsoletes QuietMode and FascistLogging +#SyslogFacility AUTH +SyslogFacility AUTHPRIV +#LogLevel INFO + +# Authentication: + +#LoginGraceTime 2m +PermitRootLogin <%= scope.lookupvar('::sshd::permit_root_login') %> +StrictModes <%= scope.lookupvar('::sshd::strict_modes') %> +#MaxAuthTries 6 +#MaxSessions 10 + +RSAAuthentication <%= scope.lookupvar('::sshd::rsa_authentication') %> +PubkeyAuthentication <%= scope.lookupvar('::sshd::pubkey_authentication') %> +AuthorizedKeysFile <%= scope.lookupvar('::sshd::authorized_keys_file') %> +#AuthorizedPrincipalsFile none +#AuthorizedKeysCommand none +#AuthorizedKeysCommandRunAs nobody + +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts +RhostsRSAAuthentication <%= scope.lookupvar('::sshd::rhosts_rsa_authentication') %> + +# similar for protocol version 2 +HostbasedAuthentication <%= scope.lookupvar('::sshd::hostbased_authentication') %> + +# Change to yes if you don't trust ~/.ssh/known_hosts for +# RhostsRSAAuthentication and HostbasedAuthentication +#IgnoreUserKnownHosts no + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts <%= scope.lookupvar('::sshd::ignore_rhosts') %> + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication <%= scope.lookupvar('::sshd::password_authentication') %> + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords <%= scope.lookupvar('::sshd::permit_empty_passwords') %> + +# Change to no to disable s/key passwords +ChallengeResponseAuthentication <%= scope.lookupvar('::sshd::challenge_response_authentication') %> + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no +#KerberosUseKuserok yes + +# GSSAPI options +GSSAPIAuthentication no +GSSAPICleanupCredentials yes +#GSSAPIStrictAcceptorCheck yes +#GSSAPIKeyExchange no + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +# WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several +# problems. +#UsePAM no +UsePAM <%= scope.lookupvar('::sshd::use_pam') %> + +#AllowAgentForwarding yes +AllowTcpForwarding <%= scope.lookupvar('::sshd::tcp_forwarding') %> +#GatewayPorts no +#X11Forwarding no +X11Forwarding <%= scope.lookupvar('::sshd::x11_forwarding') %> +#X11DisplayOffset 10 +#X11UseLocalhost yes +PrintMotd <%= scope.lookupvar('::sshd::print_motd') %> +#PrintLastLog yes +#TCPKeepAlive yes +#UseLogin no +UsePrivilegeSeparation sandbox # Default for new installations. +#PermitUserEnvironment no +#Compression delayed +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#ShowPatchLevel no +#UseDNS yes +#PidFile /var/run/sshd.pid +#MaxStartups 10:30:100 +#PermitTunnel no +#ChrootDirectory none +#VersionAddendum none + +# no default banner path +#Banner none + +# Accept locale-related environment variables +AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES +AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT +AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE +AcceptEnv XMODIFIERS + + +# override default of no subsystems +Subsystem sftp <%= (s=scope.lookupvar('::sshd::sftp_subsystem')).empty? ? '/usr/libexec/openssh/sftp-server' : s %> + +<% unless (s=scope.lookupvar('::sshd::allowed_users')).empty? -%> +AllowUsers <%= s %> +<% end -%> +<% unless (s=scope.lookupvar('::sshd::allowed_groups')).empty? -%> +AllowGroups <%= s %> +<%- end -%> + +# Uncomment this if you want to use .local domain +#Host *.local +# CheckHostIP no + +<% if scope.lookupvar('::sshd::hardened') == 'yes' -%> +<% if (scope.function_versioncmp([scope.lookupvar('::ssh_version'),'6.5'])) >= 0 -%> +KexAlgorithms curve25519-sha256@libssh.org +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com +<% else -%> +Ciphers aes256-ctr +MACs hmac-sha1 +<% end -%> +<% end -%> + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# ForceCommand cvs server + +<% unless (s=scope.lookupvar('::sshd::tail_additional_options')).empty? -%> +<%= s %> +<% end -%> diff --git a/puppet/modules/sshd/templates/sshd_config/Debian_jessie.erb b/puppet/modules/sshd/templates/sshd_config/Debian_jessie.erb new file mode 100644 index 00000000..91dbfff0 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/Debian_jessie.erb @@ -0,0 +1,124 @@ +# This file is managed by Puppet, all local modifications will be overwritten +# +# Package generated configuration file +# See the sshd_config(5) manpage for details + +<% unless (s=scope.lookupvar('::sshd::head_additional_options')).empty? -%> +<%= s %> +<% end -%> + +# What ports, IPs and protocols we listen for +<% scope.lookupvar('::sshd::ports').to_a.each do |port| -%> +<% if port == 'off' -%> +#Port -- disabled by puppet +<% else -%> +Port <%= port %> +<% end -%> +<% end -%> + +# Use these options to restrict which interfaces/protocols sshd will bind to +<% scope.lookupvar('::sshd::listen_address').to_a.each do |address| -%> +ListenAddress <%= address %> +<% end -%> +Protocol 2 +# HostKeys for protocol version 2 +<% scope.lookupvar('::sshd::hostkey_type').to_a.each do |hostkey_type| -%> +HostKey /etc/ssh/ssh_host_<%=hostkey_type %>_key +<% end -%> +#Privilege Separation is turned on for security +UsePrivilegeSeparation yes + +# Lifetime and size of ephemeral version 1 server key +KeyRegenerationInterval 3600 +ServerKeyBits 1024 + +# Logging +SyslogFacility AUTH +LogLevel INFO + +# Authentication: +LoginGraceTime 120 +PermitRootLogin <%= scope.lookupvar('::sshd::permit_root_login') %> +StrictModes <%= scope.lookupvar('::sshd::strict_modes') %> + +RSAAuthentication <%= scope.lookupvar('::sshd::rsa_authentication') %> +PubkeyAuthentication <%= scope.lookupvar('::sshd::pubkey_authentication') %> +AuthorizedKeysFile <%= scope.lookupvar('::sshd::authorized_keys_file') %> + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts <%= scope.lookupvar('::sshd::ignore_rhosts') %> +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication <%= scope.lookupvar('::sshd::rhosts_rsa_authentication') %> +# similar for protocol version 2 +HostbasedAuthentication <%= scope.lookupvar('::sshd::hostbased_authentication') %> +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords <%= scope.lookupvar('::sshd::permit_empty_passwords') %> + +# Change to yes to enable challenge-response passwords (beware issues with +# some PAM modules and threads) +ChallengeResponseAuthentication <%= scope.lookupvar('::sshd::challenge_response_authentication') %> + +# Change to no to disable tunnelled clear text passwords +PasswordAuthentication <%= scope.lookupvar('::sshd::password_authentication') %> + +# Kerberos options +KerberosAuthentication <%= scope.lookupvar('::sshd::kerberos_authentication') %> +#KerberosGetAFSToken no +KerberosOrLocalPasswd <%= scope.lookupvar('::sshd::kerberos_orlocalpasswd') %> +KerberosTicketCleanup <%= scope.lookupvar('::sshd::kerberos_ticketcleanup') %> + +# GSSAPI options +GSSAPIAuthentication <%= scope.lookupvar('::sshd::gssapi_authentication') %> +GSSAPICleanupCredentials <%= scope.lookupvar('::sshd::gssapi_cleanupcredentials') %> + +X11Forwarding <%= scope.lookupvar('::sshd::x11_forwarding') %> +X11DisplayOffset 10 +PrintMotd <%= scope.lookupvar('::sshd::print_motd') %> +PrintLastLog yes +TCPKeepAlive yes +#UseLogin no + +#MaxStartups 10:30:60 +#Banner /etc/issue.net +# do not reveal debian version (default is yes) +DebianBanner no + +# Allow client to pass locale environment variables +AcceptEnv LANG LC_* + +Subsystem sftp <%= (s=scope.lookupvar('::sshd::sftp_subsystem')).empty? ? '/usr/lib/openssh/sftp-server' : s %> + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM <%= scope.lookupvar('::sshd::use_pam') %> + +AllowTcpForwarding <%= scope.lookupvar('::sshd::tcp_forwarding') %> + +AllowAgentForwarding <%= scope.lookupvar('::sshd::agent_forwarding') %> + +<% unless (s=scope.lookupvar('::sshd::allowed_users')).empty? -%> +AllowUsers <%= s %> +<% end -%> +<% unless (s=scope.lookupvar('::sshd::allowed_groups')).empty? -%> +AllowGroups <%= s %> +<%- end -%> + +<% if scope.lookupvar('::sshd::hardened') == 'yes' -%> +KexAlgorithms curve25519-sha256@libssh.org +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com +<% end -%> + +<% unless (s=scope.lookupvar('::sshd::tail_additional_options')).empty? -%> +<%= s %> +<% end -%> diff --git a/puppet/modules/sshd/templates/sshd_config/Debian_sid.erb b/puppet/modules/sshd/templates/sshd_config/Debian_sid.erb new file mode 100644 index 00000000..91dbfff0 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/Debian_sid.erb @@ -0,0 +1,124 @@ +# This file is managed by Puppet, all local modifications will be overwritten +# +# Package generated configuration file +# See the sshd_config(5) manpage for details + +<% unless (s=scope.lookupvar('::sshd::head_additional_options')).empty? -%> +<%= s %> +<% end -%> + +# What ports, IPs and protocols we listen for +<% scope.lookupvar('::sshd::ports').to_a.each do |port| -%> +<% if port == 'off' -%> +#Port -- disabled by puppet +<% else -%> +Port <%= port %> +<% end -%> +<% end -%> + +# Use these options to restrict which interfaces/protocols sshd will bind to +<% scope.lookupvar('::sshd::listen_address').to_a.each do |address| -%> +ListenAddress <%= address %> +<% end -%> +Protocol 2 +# HostKeys for protocol version 2 +<% scope.lookupvar('::sshd::hostkey_type').to_a.each do |hostkey_type| -%> +HostKey /etc/ssh/ssh_host_<%=hostkey_type %>_key +<% end -%> +#Privilege Separation is turned on for security +UsePrivilegeSeparation yes + +# Lifetime and size of ephemeral version 1 server key +KeyRegenerationInterval 3600 +ServerKeyBits 1024 + +# Logging +SyslogFacility AUTH +LogLevel INFO + +# Authentication: +LoginGraceTime 120 +PermitRootLogin <%= scope.lookupvar('::sshd::permit_root_login') %> +StrictModes <%= scope.lookupvar('::sshd::strict_modes') %> + +RSAAuthentication <%= scope.lookupvar('::sshd::rsa_authentication') %> +PubkeyAuthentication <%= scope.lookupvar('::sshd::pubkey_authentication') %> +AuthorizedKeysFile <%= scope.lookupvar('::sshd::authorized_keys_file') %> + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts <%= scope.lookupvar('::sshd::ignore_rhosts') %> +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication <%= scope.lookupvar('::sshd::rhosts_rsa_authentication') %> +# similar for protocol version 2 +HostbasedAuthentication <%= scope.lookupvar('::sshd::hostbased_authentication') %> +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords <%= scope.lookupvar('::sshd::permit_empty_passwords') %> + +# Change to yes to enable challenge-response passwords (beware issues with +# some PAM modules and threads) +ChallengeResponseAuthentication <%= scope.lookupvar('::sshd::challenge_response_authentication') %> + +# Change to no to disable tunnelled clear text passwords +PasswordAuthentication <%= scope.lookupvar('::sshd::password_authentication') %> + +# Kerberos options +KerberosAuthentication <%= scope.lookupvar('::sshd::kerberos_authentication') %> +#KerberosGetAFSToken no +KerberosOrLocalPasswd <%= scope.lookupvar('::sshd::kerberos_orlocalpasswd') %> +KerberosTicketCleanup <%= scope.lookupvar('::sshd::kerberos_ticketcleanup') %> + +# GSSAPI options +GSSAPIAuthentication <%= scope.lookupvar('::sshd::gssapi_authentication') %> +GSSAPICleanupCredentials <%= scope.lookupvar('::sshd::gssapi_cleanupcredentials') %> + +X11Forwarding <%= scope.lookupvar('::sshd::x11_forwarding') %> +X11DisplayOffset 10 +PrintMotd <%= scope.lookupvar('::sshd::print_motd') %> +PrintLastLog yes +TCPKeepAlive yes +#UseLogin no + +#MaxStartups 10:30:60 +#Banner /etc/issue.net +# do not reveal debian version (default is yes) +DebianBanner no + +# Allow client to pass locale environment variables +AcceptEnv LANG LC_* + +Subsystem sftp <%= (s=scope.lookupvar('::sshd::sftp_subsystem')).empty? ? '/usr/lib/openssh/sftp-server' : s %> + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM <%= scope.lookupvar('::sshd::use_pam') %> + +AllowTcpForwarding <%= scope.lookupvar('::sshd::tcp_forwarding') %> + +AllowAgentForwarding <%= scope.lookupvar('::sshd::agent_forwarding') %> + +<% unless (s=scope.lookupvar('::sshd::allowed_users')).empty? -%> +AllowUsers <%= s %> +<% end -%> +<% unless (s=scope.lookupvar('::sshd::allowed_groups')).empty? -%> +AllowGroups <%= s %> +<%- end -%> + +<% if scope.lookupvar('::sshd::hardened') == 'yes' -%> +KexAlgorithms curve25519-sha256@libssh.org +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com +<% end -%> + +<% unless (s=scope.lookupvar('::sshd::tail_additional_options')).empty? -%> +<%= s %> +<% end -%> diff --git a/puppet/modules/sshd/templates/sshd_config/Debian_squeeze.erb b/puppet/modules/sshd/templates/sshd_config/Debian_squeeze.erb new file mode 100644 index 00000000..649b320a --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/Debian_squeeze.erb @@ -0,0 +1,127 @@ +# This file is managed by Puppet, all local modifications will be overwritten +# +# Package generated configuration file +# See the sshd(8) manpage for details + +<% unless (s=scope.lookupvar('::sshd::head_additional_options')).empty? -%> +<%= s %> +<% end -%> + +# What ports, IPs and protocols we listen for +<% scope.lookupvar('::sshd::ports').to_a.each do |port| -%> +<% if port == 'off' -%> +#Port -- disabled by puppet +<% else -%> +Port <%= port %> +<% end -%> +<% end -%> + +# Use these options to restrict which interfaces/protocols sshd will bind to +<% scope.lookupvar('::sshd::listen_address').to_a.each do |address| -%> +ListenAddress <%= address %> +<% end -%> +Protocol 2 +# HostKeys for protocol version 2 +<% scope.lookupvar('::sshd::hostkey_type').to_a.each do |hostkey_type| -%> +HostKey /etc/ssh/ssh_host_<%=hostkey_type %>_key +<% end -%> + +#Privilege Separation is turned on for security +UsePrivilegeSeparation yes + +# Lifetime and size of ephemeral version 1 server key +KeyRegenerationInterval 3600 +ServerKeyBits 768 + +# Logging +SyslogFacility AUTH +LogLevel INFO + +# Authentication: +LoginGraceTime 120 +PermitRootLogin <%= scope.lookupvar('::sshd::permit_root_login') %> + +StrictModes <%= scope.lookupvar('::sshd::strict_modes') %> + +RSAAuthentication <%= scope.lookupvar('::sshd::rsa_authentication') %> + +PubkeyAuthentication <%= scope.lookupvar('::sshd::pubkey_authentication') %> + +AuthorizedKeysFile <%= scope.lookupvar('::sshd::authorized_keys_file') %> + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts <%= scope.lookupvar('::sshd::ignore_rhosts') %> +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication <%= scope.lookupvar('::sshd::rhosts_rsa_authentication') %> +# similar for protocol version 2 +HostbasedAuthentication <%= scope.lookupvar('::sshd::hostbased_authentication') %> +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords <%= scope.lookupvar('::sshd::permit_empty_passwords') %> + +# Change to yes to enable challenge-response passwords (beware issues with +# some PAM modules and threads) +ChallengeResponseAuthentication <%= scope.lookupvar('::sshd::challenge_response_authentication') %> + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication <%= scope.lookupvar('::sshd::password_authentication') %> + +# Kerberos options +KerberosAuthentication <%= scope.lookupvar('::sshd::kerberos_authentication') %> +KerberosOrLocalPasswd <%= scope.lookupvar('::sshd::kerberos_orlocalpasswd') %> +KerberosTicketCleanup <%= scope.lookupvar('::sshd::kerberos_ticketcleanup') %> + +# GSSAPI options +GSSAPIAuthentication <%= scope.lookupvar('::sshd::gssapi_authentication') %> +GSSAPICleanupCredentials <%= scope.lookupvar('::sshd::gssapi_cleanupcredentials') %> + +X11Forwarding <%= scope.lookupvar('::sshd::x11_forwarding') %> +X11DisplayOffset 10 +PrintMotd <%= scope.lookupvar('::sshd::print_motd') %> +PrintLastLog yes +TCPKeepAlive yes + +#UseLogin no + +#MaxStartups 10:30:60 +#Banner /etc/issue.net +# do not reveal debian version (default is yes) +DebianBanner no + +# Allow client to pass locale environment variables +AcceptEnv LANG LC_* + +Subsystem sftp <%= (s=scope.lookupvar('::sshd::sftp_subsystem')).empty? ? '/usr/lib/openssh/sftp-server' : s %> + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM <%= scope.lookupvar('::sshd::use_pam') %> + +AllowTcpForwarding <%= scope.lookupvar('::sshd::tcp_forwarding') %> + +AllowAgentForwarding <%= scope.lookupvar('::sshd::agent_forwarding') %> + +<% unless (s=scope.lookupvar('::sshd::allowed_users')).empty? -%> +AllowUsers <%= s %> +<% end -%> +<% unless (s=scope.lookupvar('::sshd::allowed_groups')).empty? -%> +AllowGroups <%= s %> +<%- end -%> + +<% if scope.lookupvar('::sshd::hardened') == 'yes' -%> +Ciphers aes256-ctr +MACs hmac-sha2-512 +<% end -%> + +<% unless (s=scope.lookupvar('::sshd::tail_additional_options')).empty? -%> +<%= s %> +<% end -%> diff --git a/puppet/modules/sshd/templates/sshd_config/Debian_wheezy.erb b/puppet/modules/sshd/templates/sshd_config/Debian_wheezy.erb new file mode 100644 index 00000000..bcb15286 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/Debian_wheezy.erb @@ -0,0 +1,132 @@ +# This file is managed by Puppet, all local modifications will be overwritten +# +# Package generated configuration file +# See the sshd(8) manpage for details + +<% unless (s=scope.lookupvar('::sshd::head_additional_options')).empty? -%> +<%= s %> +<% end -%> + +# What ports, IPs and protocols we listen for +<% scope.lookupvar('::sshd::ports').to_a.each do |port| -%> +<% if port == 'off' -%> +#Port -- disabled by puppet +<% else -%> +Port <%= port %> +<% end -%> +<% end -%> + +# Use these options to restrict which interfaces/protocols sshd will bind to +<% scope.lookupvar('::sshd::listen_address').to_a.each do |address| -%> +ListenAddress <%= address %> +<% end -%> +Protocol 2 +# HostKeys for protocol version 2 +<% scope.lookupvar('::sshd::hostkey_type').to_a.each do |hostkey_type| -%> +HostKey /etc/ssh/ssh_host_<%=hostkey_type %>_key +<% end -%> +#Privilege Separation is turned on for security +UsePrivilegeSeparation yes + +# Lifetime and size of ephemeral version 1 server key +KeyRegenerationInterval 3600 +ServerKeyBits 768 + +# Logging +SyslogFacility AUTH +LogLevel INFO + +# Authentication: +LoginGraceTime 120 +PermitRootLogin <%= scope.lookupvar('::sshd::permit_root_login') %> + +StrictModes <%= scope.lookupvar('::sshd::strict_modes') %> + +RSAAuthentication <%= scope.lookupvar('::sshd::rsa_authentication') %> + +PubkeyAuthentication <%= scope.lookupvar('::sshd::pubkey_authentication') %> + +AuthorizedKeysFile <%= scope.lookupvar('::sshd::authorized_keys_file') %> + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts <%= scope.lookupvar('::sshd::ignore_rhosts') %> +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication <%= scope.lookupvar('::sshd::rhosts_rsa_authentication') %> +# similar for protocol version 2 +HostbasedAuthentication <%= scope.lookupvar('::sshd::hostbased_authentication') %> +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords <%= scope.lookupvar('::sshd::permit_empty_passwords') %> + +# Change to yes to enable challenge-response passwords (beware issues with +# some PAM modules and threads) +ChallengeResponseAuthentication <%= scope.lookupvar('::sshd::challenge_response_authentication') %> + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication <%= scope.lookupvar('::sshd::password_authentication') %> + +# Kerberos options +KerberosAuthentication <%= scope.lookupvar('::sshd::kerberos_authentication') %> +KerberosOrLocalPasswd <%= scope.lookupvar('::sshd::kerberos_orlocalpasswd') %> +KerberosTicketCleanup <%= scope.lookupvar('::sshd::kerberos_ticketcleanup') %> + +# GSSAPI options +GSSAPIAuthentication <%= scope.lookupvar('::sshd::gssapi_authentication') %> +GSSAPICleanupCredentials <%= scope.lookupvar('::sshd::gssapi_cleanupcredentials') %> + +X11Forwarding <%= scope.lookupvar('::sshd::x11_forwarding') %> +X11DisplayOffset 10 +PrintMotd <%= scope.lookupvar('::sshd::print_motd') %> +PrintLastLog yes +TCPKeepAlive yes + +#UseLogin no + +#MaxStartups 10:30:60 +#Banner /etc/issue.net +# do not reveal debian version (default is yes) +DebianBanner no + +# Allow client to pass locale environment variables +AcceptEnv LANG LC_* + +Subsystem sftp <%= (s=scope.lookupvar('::sshd::sftp_subsystem')).empty? ? '/usr/lib/openssh/sftp-server' : s %> + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM <%= scope.lookupvar('::sshd::use_pam') %> + +AllowTcpForwarding <%= scope.lookupvar('::sshd::tcp_forwarding') %> + +AllowAgentForwarding <%= scope.lookupvar('::sshd::agent_forwarding') %> + +<% unless (s=scope.lookupvar('::sshd::allowed_users')).empty? -%> +AllowUsers <%= s %> +<% end -%> +<% unless (s=scope.lookupvar('::sshd::allowed_groups')).empty? -%> +AllowGroups <%= s %> +<%- end -%> + +<% if scope.lookupvar('::sshd::hardened') == 'yes' -%> +<% if (scope.function_versioncmp([scope.lookupvar('::ssh_version'),'6.5'])) >= 0 -%> +KexAlgorithms curve25519-sha256@libssh.org +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com +<% else -%> +Ciphers aes256-ctr +MACs hmac-sha2-512 +<% end -%> +<% end -%> + +<% unless (s=scope.lookupvar('::sshd::tail_additional_options')).empty? -%> +<%= s %> +<% end -%> diff --git a/puppet/modules/sshd/templates/sshd_config/FreeBSD.erb b/puppet/modules/sshd/templates/sshd_config/FreeBSD.erb new file mode 100644 index 00000000..5298ade9 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/FreeBSD.erb @@ -0,0 +1,168 @@ +# $OpenBSD: sshd_config,v 1.81 2009/10/08 14:03:41 markus Exp $ +# $FreeBSD: src/crypto/openssh/sshd_config,v 1.49.2.2.2.1 2010/06/14 02:09:06 kensmith Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options change a +# default value. + +# Note that some of FreeBSD's defaults differ from OpenBSD's, and +# FreeBSD has a few additional options. + +#VersionAddendum FreeBSD-20100308 + +<% unless (s=scope.lookupvar('::sshd::head_additional_options')).empty? -%> +<%= s %> +<% end -%> + +# What ports, IPs and protocols we listen for +<% scope.lookupvar('::sshd::ports').to_a.each do |port| -%> +<% if port == 'off' -%> +#Port -- disabled by puppet +<% else -%> +Port <%= port %> +<% end -%> +<% end -%> + +#AddressFamily any +<% scope.lookupvar('::sshd::listen_address').to_a.each do |address| -%> +ListenAddress <%= address %> +<% end -%> + +# The default requires explicit activation of protocol 1 +Protocol 2 + +# HostKey for protocol version 1 +#HostKey /etc/ssh/ssh_host_key +# HostKeys for protocol version 2 +<% scope.lookupvar('::sshd::hostkey_type').to_a.each do |hostkey_type| -%> +HostKey /etc/ssh/ssh_host_<%=hostkey_type %>_key +<% end -%> + +# Lifetime and size of ephemeral version 1 server key +#KeyRegenerationInterval 1h +#ServerKeyBits 1024 + +# Logging +# obsoletes QuietMode and FascistLogging +SyslogFacility AUTH +LogLevel INFO + +# Authentication: + +LoginGraceTime 600 +PermitRootLogin <%= scope.lookupvar('::sshd::permit_root_login') %> + +StrictModes <%= scope.lookupvar('::sshd::strict_modes') %> + +#MaxAuthTries 6 +#MaxSessions 10 + +RSAAuthentication <%= scope.lookupvar('::sshd::rsa_authentication') %> + +PubkeyAuthentication <%= scope.lookupvar('::sshd::pubkey_authentication') %> + +AuthorizedKeysFile <%= scope.lookupvar('::sshd::authorized_keys_file') %> + +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts +RhostsRSAAuthentication <%= scope.lookupvar('::sshd::rhosts_rsa_authentication') %> + +# similar for protocol version 2 +HostbasedAuthentication <%= scope.lookupvar('::sshd::hostbased_authentication') %> + +# Change to yes if you don't trust ~/.ssh/known_hosts for +# RhostsRSAAuthentication and HostbasedAuthentication +#IgnoreUserKnownHosts no +# Don't read the user's ~/.rhosts and ~/.shosts files +#IgnoreRhosts yes + +# Change to yes to enable built-in password authentication. +PasswordAuthentication <%= scope.lookupvar('::sshd::password_authentication') %> + +PermitEmptyPasswords <%= scope.lookupvar('::sshd::permit_empty_passwords') %> + +# Change to no to disable PAM authentication +ChallengeResponseAuthentication <%= scope.lookupvar('::sshd::challenge_response_authentication') %> + +# Kerberos options +KerberosAuthentication <%= scope.lookupvar('::sshd::kerberos_authentication') %> +KerberosOrLocalPasswd <%= scope.lookupvar('::sshd::kerberos_orlocalpasswd') %> +KerberosTicketCleanup <%= scope.lookupvar('::sshd::kerberos_ticketcleanup') %> + +# GSSAPI options +GSSAPIAuthentication <%= scope.lookupvar('::sshd::gssapi_authentication') %> +GSSAPICleanupCredentials <%= scope.lookupvar('::sshd::gssapi_cleanupcredentials') %> + +# Set this to 'no' to disable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM <%= scope.lookupvar('::sshd::use_pam') %> + +AllowAgentForwarding <%= scope.lookupvar('::sshd::agent_forwarding') %> + +AllowTcpForwarding <%= scope.lookupvar('::sshd::tcp_forwarding') %> + +#GatewayPorts no +X11Forwarding <%= scope.lookupvar('::sshd::x11_forwarding') %> + +X11DisplayOffset 10 +#X11UseLocalhost yes +PrintMotd <%= sshd_print_motd %> +#PrintLastLog yes +TCPKeepAlive yes +#UseLogin no +#UsePrivilegeSeparation yes +#PermitUserEnvironment no +#Compression delayed +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#UseDNS yes +#PidFile /var/run/sshd.pid +#MaxStartups 10 +#PermitTunnel no +#ChrootDirectory none + +# no default banner path +#Banner none + +# override default of no subsystems +Subsystem sftp <%= (s=scope.lookupvar('::sshd::sftp_subsystem')).empty? ? '/usr/libexec/sftp-server' : s %> + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# ForceCommand cvs server + +<% unless (s=scope.lookupvar('::sshd::allowed_users')).empty? -%> +AllowUsers <%= s %> +<% end -%> +<% unless (s=scope.lookupvar('::sshd::allowed_groups')).empty? -%> +AllowGroups <%= s %> +<%- end -%> + +<% if scope.lookupvar('::sshd::hardened') == 'yes' -%> +<% if (scope.function_versioncmp([scope.lookupvar('::ssh_version'),'6.5'])) >= 0 -%> +KexAlgorithms curve25519-sha256@libssh.org +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com +<% else -%> +Ciphers aes256-ctr +MACs hmac-sha1 +<% end -%> +<% end -%> + +<% unless (s=scope.lookupvar('::sshd::tail_additional_options')).empty? -%> +<%= s %> +<% end -%> diff --git a/puppet/modules/sshd/templates/sshd_config/Gentoo.erb b/puppet/modules/sshd/templates/sshd_config/Gentoo.erb new file mode 100644 index 00000000..022a26e7 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/Gentoo.erb @@ -0,0 +1,164 @@ +# $OpenBSD: sshd_config,v 1.75 2007/03/19 01:01:29 djm Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options change a +# default value. + +<% unless (s=scope.lookupvar('::sshd::head_additional_options')).empty? -%> +<%= s %> +<% end -%> + +<% scope.lookupvar('::sshd::ports').to_a.each do |port| -%> +<% if port == 'off' -%> +#Port -- disabled by puppet +<% else -%> +Port <%= port %> +<% end -%> +<% end -%> + +# Use these options to restrict which interfaces/protocols sshd will bind to +<% scope.lookupvar('::sshd::listen_address').to_a.each do |address| -%> +ListenAddress <%= address %> +<% end -%> +#AddressFamily any + +# Disable legacy (protocol version 1) support in the server for new +# installations. In future the default will change to require explicit +# activation of protocol 1 +Protocol 2 + +# HostKey for protocol version 1 +#HostKey /etc/ssh/ssh_host_key +# HostKeys for protocol version 2 +#HostKey /etc/ssh/ssh_host_rsa_key +#HostKey /etc/ssh/ssh_host_dsa_key + +# Lifetime and size of ephemeral version 1 server key +#KeyRegenerationInterval 1h +#ServerKeyBits 768 + +# Logging +# obsoletes QuietMode and FascistLogging +#SyslogFacility AUTH +#LogLevel INFO + +# Authentication: + +#LoginGraceTime 2m +PermitRootLogin <%= scope.lookupvar('::sshd::permit_root_login') %> + +StrictModes <%= scope.lookupvar('::sshd::strict_modes') %> + +#MaxAuthTries 6 + +RSAAuthentication <%= scope.lookupvar('::sshd::rsa_authentication') %> + +PubkeyAuthentication <%= scope.lookupvar('::sshd::pubkey_authentication') %> + +AuthorizedKeysFile <%= scope.lookupvar('::sshd::authorized_keys_file') %> + +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts +RhostsRSAAuthentication <%= scope.lookupvar('::sshd::rhosts_rsa_authentication') %> + +# similar for protocol version 2 +HostbasedAuthentication <%= scope.lookupvar('::sshd::hostbased_authentication') %> + +# Change to yes if you don't trust ~/.ssh/known_hosts for +# RhostsRSAAuthentication and HostbasedAuthentication +#IgnoreUserKnownHosts no + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts <%= scope.lookupvar('::sshd::ignore_rhosts') %> + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication <%= scope.lookupvar('::sshd::password_authentication') %> + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords <%= scope.lookupvar('::sshd::permit_empty_passwords') %> + +# Change to no to disable s/key passwords +ChallengeResponseAuthentication <%= scope.lookupvar('::sshd::challenge_response_authentication') %> + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes +#GSSAPIStrictAcceptorCheck yes +#GSSAPIKeyExchange no + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM <%= scope.lookupvar('::sshd::use_pam') %> + +AllowTcpForwarding <%= scope.lookupvar('::sshd::tcp_forwarding') %> + +#GatewayPorts no +X11Forwarding <%= scope.lookupvar('::sshd::x11_forwarding') %> +#X11DisplayOffset 10 +#X11UseLocalhost yes +PrintMotd <%= scope.lookupvar('::sshd::print_motd') %> +#PrintLastLog yes +#TCPKeepAlive yes +#UseLogin no +#UsePrivilegeSeparation yes +#PermitUserEnvironment no +#Compression delayed +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#UseDNS yes +#PidFile /var/run/sshd.pid +#MaxStartups 10 +#PermitTunnel no + +# no default banner path +#Banner /some/path + +# override default of no subsystems +Subsystem sftp <%= (s=scope.lookupvar('::sshd::sftp_subsystem')).empty? ? '/usr/lib/misc/sftp-server' : s %> + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# ForceCommand cvs server + +<% unless (s=scope.lookupvar('::sshd::allowed_users')).empty? -%> +AllowUsers <%= s %> +<% end -%> +<% unless (s=scope.lookupvar('::sshd::allowed_groups')).empty? -%> +AllowGroups <%= s %> +<%- end -%> + +<% if scope.lookupvar('::sshd::hardened') == 'yes' -%> +<% if (scope.function_versioncmp([scope.lookupvar('::ssh_version'),'6.5'])) >= 0 -%> +KexAlgorithms curve25519-sha256@libssh.org +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com +<% else -%> +Ciphers aes256-ctr +MACs hmac-sha1 +<% end -%> +<% end -%> + +<% unless (s=scope.lookupvar('::sshd::tail_additional_options')).empty? -%> +<%= s %> +<% end -%> + diff --git a/puppet/modules/sshd/templates/sshd_config/OpenBSD.erb b/puppet/modules/sshd/templates/sshd_config/OpenBSD.erb new file mode 100644 index 00000000..db730300 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/OpenBSD.erb @@ -0,0 +1,144 @@ +# $OpenBSD: sshd_config,v 1.74 2006/07/19 13:07:10 dtucker Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options change a +# default value. + +<% unless (s=scope.lookupvar('::sshd::head_additional_options')).empty? -%> +<%= s %> +<% end -%> + +<% scope.lookupvar('::sshd::ports').to_a.each do |port| -%> +<% if port == 'off' -%> +#Port -- disabled by puppet +<% else -%> +Port <%= port %> +<% end -%> +<% end -%> + +# Use these options to restrict which interfaces/protocols sshd will bind to +<% scope.lookupvar('::sshd::listen_address').to_a.each do |address| -%> +ListenAddress <%= address %> +<% end -%> +#Protocol 2,1 +#AddressFamily any + +# HostKey for protocol version 1 +#HostKey /etc/ssh/ssh_host_key +# HostKeys for protocol version 2 +#HostKey /etc/ssh/ssh_host_rsa_key +#HostKey /etc/ssh/ssh_host_dsa_key + +# Lifetime and size of ephemeral version 1 server key +#KeyRegenerationInterval 1h +#ServerKeyBits 768 + +# Logging +# obsoletes QuietMode and FascistLogging +#SyslogFacility AUTH +#LogLevel INFO + +# Authentication: + +#LoginGraceTime 2m +PermitRootLogin <%= scope.lookupvar('::sshd::permit_root_login') %> + +StrictModes <%= scope.lookupvar('::sshd::strict_modes') %> + +#MaxAuthTries 6 + +RSAAuthentication <%= scope.lookupvar('::sshd::rsa_authentication') %> + +PubkeyAuthentication <%= scope.lookupvar('::sshd::pubkey_authentication') %> + +AuthorizedKeysFile <%= scope.lookupvar('::sshd::authorized_keys_file') %> + +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts +RhostsRSAAuthentication <%= scope.lookupvar('::sshd::rhosts_rsa_authentication') %> + +# similar for protocol version 2 +HostbasedAuthentication <%= scope.lookupvar('::sshd::hostbased_authentication') %> + +# Change to yes if you don't trust ~/.ssh/known_hosts for +# RhostsRSAAuthentication and HostbasedAuthentication +#IgnoreUserKnownHosts no + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts <%= scope.lookupvar('::sshd::ignore_rhosts') %> + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication <%= scope.lookupvar('::sshd::password_authentication') %> + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords <%= scope.lookupvar('::sshd::permit_empty_passwords') %> + +# Change to no to disable s/key passwords +ChallengeResponseAuthentication <%= scope.lookupvar('::sshd::challenge_response_authentication') %> + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes + +AllowTcpForwarding <%= scope.lookupvar('::sshd::tcp_forwarding') %> + +#GatewayPorts no +X11Forwarding <%= scope.lookupvar('::sshd::x11_forwarding') %> +#X11DisplayOffset 10 +#X11UseLocalhost yes +PrintMotd <%= scope.lookupvar('::sshd::print_motd') %> +#PrintLastLog yes +#TCPKeepAlive yes +#UseLogin no +#UsePrivilegeSeparation yes +#PermitUserEnvironment no +#Compression delayed +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#UseDNS yes +#PidFile /var/run/sshd.pid +#MaxStartups 10 +#PermitTunnel no + +# no default banner path +#Banner /some/path + +# override default of no subsystems +Subsystem sftp <%= (s=scope.lookupvar('::sshd::sftp_subsystem')).empty? ? '/usr/libexec/sftp-server' : s %> + +<% unless (s=scope.lookupvar('::sshd::allowed_users')).empty? -%> +AllowUsers <%= s %> +<% end -%> +<% unless (s=scope.lookupvar('::sshd::allowed_groups')).empty? -%> +AllowGroups <%= s %> +<%- end -%> + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# ForceCommand cvs server + +<% if scope.lookupvar('::sshd::hardened') == 'yes' -%> +<% if (scope.function_versioncmp([scope.lookupvar('::ssh_version'),'6.5'])) >= 0 -%> +KexAlgorithms curve25519-sha256@libssh.org +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com +<% else -%> +Ciphers aes256-ctr +MACs hmac-sha1 +<% end -%> +<% end -%> + +<% unless (s=scope.lookupvar('::sshd::tail_additional_options')).empty? -%> +<%= s %> +<% end -%> diff --git a/puppet/modules/sshd/templates/sshd_config/Ubuntu.erb b/puppet/modules/sshd/templates/sshd_config/Ubuntu.erb new file mode 100644 index 00000000..a326ab87 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/Ubuntu.erb @@ -0,0 +1,133 @@ +# This file is managed by Puppet, all local modifications will be overwritten +# +# Package generated configuration file +# See the sshd(8) manpage for details + +<% unless (s=scope.lookupvar('::sshd::head_additional_options')).empty? -%> +<%= s %> +<% end -%> + +# What ports, IPs and protocols we listen for +<% scope.lookupvar('::sshd::ports').to_a.each do |port| -%> +<% if port == 'off' -%> +#Port -- disabled by puppet +<% else -%> +Port <%= port %> +<% end -%> +<% end -%> + +# Use these options to restrict which interfaces/protocols sshd will bind to +<% scope.lookupvar('::sshd::listen_address').to_a.each do |address| -%> +ListenAddress <%= address %> +<% end -%> +Protocol 2 +# HostKeys for protocol version 2 +<% scope.lookupvar('::sshd::hostkey_type').to_a.each do |hostkey_type| -%> +HostKey /etc/ssh/ssh_host_<%=hostkey_type %>_key +<% end -%> + +#Privilege Separation is turned on for security +UsePrivilegeSeparation yes + +# Lifetime and size of ephemeral version 1 server key +KeyRegenerationInterval 3600 +ServerKeyBits 768 + +# Logging +SyslogFacility AUTH +LogLevel INFO + +# Authentication: +LoginGraceTime 120 +PermitRootLogin <%= scope.lookupvar('::sshd::permit_root_login') %> + +StrictModes <%= scope.lookupvar('::sshd::strict_modes') %> + +RSAAuthentication <%= scope.lookupvar('::sshd::rsa_authentication') %> + +PubkeyAuthentication <%= scope.lookupvar('::sshd::pubkey_authentication') %> + +AuthorizedKeysFile <%= scope.lookupvar('::sshd::authorized_keys_file') %> + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts <%= scope.lookupvar('::sshd::ignore_rhosts') %> +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication <%= scope.lookupvar('::sshd::rhosts_rsa_authentication') %> +# similar for protocol version 2 +HostbasedAuthentication <%= scope.lookupvar('::sshd::hostbased_authentication') %> +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords <%= scope.lookupvar('::sshd::permit_empty_passwords') %> + +# Change to yes to enable challenge-response passwords (beware issues with +# some PAM modules and threads) +ChallengeResponseAuthentication <%= scope.lookupvar('::sshd::challenge_response_authentication') %> + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication <%= scope.lookupvar('::sshd::password_authentication') %> + +# Kerberos options +KerberosAuthentication <%= scope.lookupvar('::sshd::kerberos_authentication') %> +KerberosOrLocalPasswd <%= scope.lookupvar('::sshd::kerberos_orlocalpasswd') %> +KerberosTicketCleanup <%= scope.lookupvar('::sshd::kerberos_ticketcleanup') %> + +# GSSAPI options +GSSAPIAuthentication <%= scope.lookupvar('::sshd::gssapi_authentication') %> +GSSAPICleanupCredentials <%= scope.lookupvar('::sshd::gssapi_cleanupcredentials') %> + +X11Forwarding <%= scope.lookupvar('::sshd::x11_forwarding') %> +X11DisplayOffset 10 +PrintMotd <%= scope.lookupvar('::sshd::print_motd') %> +PrintLastLog yes +TCPKeepAlive yes + +#UseLogin no + +#MaxStartups 10:30:60 +#Banner /etc/issue.net +# do not reveal debian version (default is yes) +DebianBanner no + +# Allow client to pass locale environment variables +AcceptEnv LANG LC_* + +Subsystem sftp <%= (s=scope.lookupvar('::sshd::sftp_subsystem')).empty? ? '/usr/lib/openssh/sftp-server' : s %> + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM <%= scope.lookupvar('::sshd::use_pam') %> + +AllowTcpForwarding <%= scope.lookupvar('::sshd::tcp_forwarding') %> + +AllowAgentForwarding <%= scope.lookupvar('::sshd::agent_forwarding') %> + +<% unless (s=scope.lookupvar('::sshd::allowed_users')).empty? -%> +AllowUsers <%= s %> +<% end -%> +<% unless (s=scope.lookupvar('::sshd::allowed_groups')).empty? -%> +AllowGroups <%= s %> +<%- end -%> + +<% if scope.lookupvar('::sshd::hardened') == 'yes' -%> +<% if (scope.function_versioncmp([scope.lookupvar('::ssh_version'),'6.5'])) >= 0 -%> +KexAlgorithms curve25519-sha256@libssh.org +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com +<% else -%> +Ciphers aes256-ctr +MACs hmac-sha1 +<% end -%> +<% end -%> + +<% unless (s=scope.lookupvar('::sshd::tail_additional_options')).empty? -%> +<%= s %> +<% end -%> diff --git a/puppet/modules/sshd/templates/sshd_config/Ubuntu_lucid.erb b/puppet/modules/sshd/templates/sshd_config/Ubuntu_lucid.erb new file mode 100644 index 00000000..be7c56d0 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/Ubuntu_lucid.erb @@ -0,0 +1,136 @@ +# Package generated configuration file +# See the sshd(8) manpage for details + +<% unless (s=scope.lookupvar('::sshd::head_additional_options')).empty? -%> +<%= s %> +<% end -%> + +# What ports, IPs and protocols we listen for +<% scope.lookupvar('::sshd::ports').to_a.each do |port| -%> +<% if port == 'off' -%> +#Port -- disabled by puppet +<% else -%> +Port <%= port %> +<% end -%> +<% end -%> + +# Use these options to restrict which interfaces/protocols sshd will bind to +<% scope.lookupvar('::sshd::listen_address').to_a.each do |address| -%> +ListenAddress <%= address %> +<% end -%> +Protocol 2 +# HostKeys for protocol version 2 +<% scope.lookupvar('::sshd::hostkey_type').to_a.each do |hostkey_type| -%> +HostKey /etc/ssh/ssh_host_<%=hostkey_type %>_key +<% end -%> + +#Privilege Separation is turned on for security +UsePrivilegeSeparation yes + +# ...but breaks Pam auth via kbdint, so we have to turn it off +# Use PAM authentication via keyboard-interactive so PAM modules can +# properly interface with the user (off due to PrivSep) +#PAMAuthenticationViaKbdInt no +# Lifetime and size of ephemeral version 1 server key +KeyRegenerationInterval 3600 +ServerKeyBits 768 + +# Logging +SyslogFacility AUTH +LogLevel INFO + +# Authentication: +LoginGraceTime 600 +PermitRootLogin <%= scope.lookupvar('::sshd::permit_root_login') %> + +StrictModes <%= scope.lookupvar('::sshd::strict_modes') %> + +RSAAuthentication <%= scope.lookupvar('::sshd::rsa_authentication') %> + +PubkeyAuthentication <%= scope.lookupvar('::sshd::pubkey_authentication') %> + +AuthorizedKeysFile <%= scope.lookupvar('::sshd::authorized_keys_file') %> + +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication <%= scope.lookupvar('::sshd::rhosts_rsa_authentication') %> + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts <%= scope.lookupvar('::sshd::ignore_rhosts') %> + +# similar for protocol version 2 +HostbasedAuthentication <%= scope.lookupvar('::sshd::hostbased_authentication') %> + +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords <%= scope.lookupvar('::sshd::permit_empty_passwords') %> + +# Change to no to disable s/key passwords +ChallengeResponseAuthentication <%= scope.lookupvar('::sshd::challenge_response_authentication') %> + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication <%= scope.lookupvar('::sshd::password_authentication') %> + +# To change Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#AFSTokenPassing no +#KerberosTicketCleanup no + +# Kerberos TGT Passing does only work with the AFS kaserver +#KerberosTgtPassing yes + +X11Forwarding <%= scope.lookupvar('::sshd::x11_forwarding') %> +X11DisplayOffset 10 +KeepAlive yes +#UseLogin no + +#MaxStartups 10:30:60 +#Banner /etc/issue.net +# do not reveal debian version (default is yes) +DebianBanner no +#ReverseMappingCheck yes + +Subsystem sftp <%= (s=scope.lookupvar('::sshd::sftp_subsystem')).empty? ? '/usr/lib/openssh/sftp-server' : s %> + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM <%= scope.lookupvar('::sshd::use_pam') %> + +HostbasedUsesNameFromPacketOnly yes + +AllowTcpForwarding <%= scope.lookupvar('::sshd::tcp_forwarding') %> + +AllowAgentForwarding <%= scope.lookupvar('::sshd::agent_forwarding') %> + +<% unless (s=scope.lookupvar('::sshd::allowed_users')).empty? -%> +AllowUsers <%= s %> +<% end -%> +<% unless (s=scope.lookupvar('::sshd::allowed_groups')).empty? -%> +AllowGroups <%= s %> +<%- end -%> + +PrintMotd <%= scope.lookupvar('::sshd::print_motd') %> + +<% if scope.lookupvar('::sshd::hardened') == 'yes' -%> +<% if (scope.function_versioncmp([scope.lookupvar('::ssh_version'),'6.5'])) >= 0 -%> +KexAlgorithms curve25519-sha256@libssh.org +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com +<% else -%> +Ciphers aes256-ctr +MACs hmac-sha1 +<% end -%> +<% end -%> + +<% unless (s=scope.lookupvar('::sshd::tail_additional_options')).empty? -%> +<%= s %> +<% end -%> diff --git a/puppet/modules/sshd/templates/sshd_config/Ubuntu_oneiric.erb b/puppet/modules/sshd/templates/sshd_config/Ubuntu_oneiric.erb new file mode 120000 index 00000000..ccfb67c8 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/Ubuntu_oneiric.erb @@ -0,0 +1 @@ +Ubuntu_lucid.erb \ No newline at end of file diff --git a/puppet/modules/sshd/templates/sshd_config/Ubuntu_precise.erb b/puppet/modules/sshd/templates/sshd_config/Ubuntu_precise.erb new file mode 120000 index 00000000..6502bfce --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/Ubuntu_precise.erb @@ -0,0 +1 @@ +Ubuntu.erb \ No newline at end of file diff --git a/puppet/modules/sshd/templates/sshd_config/XenServer_xenenterprise.erb b/puppet/modules/sshd/templates/sshd_config/XenServer_xenenterprise.erb new file mode 120000 index 00000000..71b767a5 --- /dev/null +++ b/puppet/modules/sshd/templates/sshd_config/XenServer_xenenterprise.erb @@ -0,0 +1 @@ +CentOS_6.erb \ No newline at end of file -- cgit v1.2.3 From 2e384e68fb867d8ba7178c4398e35653ab567538 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:30 -0400 Subject: git subrepo clone https://leap.se/git/puppet_apt puppet/modules/apt subrepo: subdir: "puppet/modules/apt" merged: "33c61e8" upstream: origin: "https://leap.se/git/puppet_apt" branch: "master" commit: "33c61e8" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I6515ec49bbacdffd9f3729d486d2868162f9ac78 --- puppet/modules/apt/.gitignore | 12 + puppet/modules/apt/.gitlab-ci.yml | 12 + puppet/modules/apt/.gitrepo | 11 + puppet/modules/apt/Gemfile | 13 + puppet/modules/apt/LICENSE | 674 +++++++++++++++++++++ puppet/modules/apt/README | 602 ++++++++++++++++++ puppet/modules/apt/Rakefile | 19 + puppet/modules/apt/files/02show_upgraded | 4 + puppet/modules/apt/files/03clean | 4 + puppet/modules/apt/files/03clean_vserver | 4 + puppet/modules/apt/files/upgrade_initiator | 1 + puppet/modules/apt/lib/facter/apt_running.rb | 7 + puppet/modules/apt/lib/facter/debian_codename.rb | 42 ++ puppet/modules/apt/lib/facter/debian_lts.rb | 16 + .../modules/apt/lib/facter/debian_nextcodename.rb | 23 + .../modules/apt/lib/facter/debian_nextrelease.rb | 23 + puppet/modules/apt/lib/facter/debian_release.rb | 38 ++ puppet/modules/apt/lib/facter/ubuntu_codename.rb | 8 + .../modules/apt/lib/facter/ubuntu_nextcodename.rb | 20 + puppet/modules/apt/lib/facter/util/debian.rb | 18 + puppet/modules/apt/lib/facter/util/ubuntu.rb | 21 + puppet/modules/apt/manifests/apt_conf.pp | 45 ++ puppet/modules/apt/manifests/apticron.pp | 24 + puppet/modules/apt/manifests/cron/base.pp | 20 + puppet/modules/apt/manifests/cron/dist_upgrade.pp | 29 + puppet/modules/apt/manifests/cron/download.pp | 27 + puppet/modules/apt/manifests/dist_upgrade.pp | 9 + .../apt/manifests/dist_upgrade/initiator.pp | 23 + puppet/modules/apt/manifests/dot_d_directories.pp | 15 + puppet/modules/apt/manifests/dselect.pp | 11 + puppet/modules/apt/manifests/init.pp | 150 +++++ puppet/modules/apt/manifests/key.pp | 13 + puppet/modules/apt/manifests/key/plain.pp | 13 + puppet/modules/apt/manifests/listchanges.pp | 19 + puppet/modules/apt/manifests/params.pp | 22 + puppet/modules/apt/manifests/preferences.pp | 20 + puppet/modules/apt/manifests/preferences/absent.pp | 7 + .../modules/apt/manifests/preferences_snippet.pp | 59 ++ puppet/modules/apt/manifests/preseeded_package.pp | 21 + puppet/modules/apt/manifests/proxy_client.pp | 9 + .../apt/manifests/reboot_required_notify.pp | 21 + puppet/modules/apt/manifests/sources_list.pp | 40 ++ .../modules/apt/manifests/unattended_upgrades.pp | 34 ++ puppet/modules/apt/manifests/update.pp | 7 + puppet/modules/apt/manifests/upgrade_package.pp | 31 + puppet/modules/apt/spec/spec_helper.rb | 12 + puppet/modules/apt/spec/unit/custom_facts_spec.rb | 86 +++ puppet/modules/apt/templates/20proxy.erb | 5 + .../apt/templates/50unattended-upgrades.erb | 38 ++ .../apt/templates/Debian/apticron_jessie.erb | 1 + .../apt/templates/Debian/apticron_lenny.erb | 50 ++ .../modules/apt/templates/Debian/apticron_sid.erb | 1 + .../apt/templates/Debian/apticron_squeeze.erb | 82 +++ .../apt/templates/Debian/apticron_wheezy.erb | 80 +++ .../apt/templates/Debian/listchanges_jessie.erb | 1 + .../apt/templates/Debian/listchanges_lenny.erb | 7 + .../apt/templates/Debian/listchanges_sid.erb | 1 + .../apt/templates/Debian/listchanges_squeeze.erb | 1 + .../apt/templates/Debian/listchanges_wheezy.erb | 1 + .../apt/templates/Debian/preferences_jessie.erb | 14 + .../apt/templates/Debian/preferences_lenny.erb | 25 + .../apt/templates/Debian/preferences_sid.erb | 10 + .../apt/templates/Debian/preferences_squeeze.erb | 30 + .../apt/templates/Debian/preferences_wheezy.erb | 20 + .../modules/apt/templates/Debian/sources.list.erb | 76 +++ .../apt/templates/Ubuntu/preferences_lucid.erb | 1 + .../apt/templates/Ubuntu/preferences_maverick.erb | 30 + .../apt/templates/Ubuntu/preferences_oneiric.erb | 1 + .../apt/templates/Ubuntu/preferences_precise.erb | 1 + .../apt/templates/Ubuntu/preferences_utopic.erb | 1 + .../apt/templates/Ubuntu/preferences_vivid.erb | 1 + .../apt/templates/Ubuntu/preferences_wily.erb | 1 + .../apt/templates/Ubuntu/preferences_xenial.erb | 1 + .../modules/apt/templates/Ubuntu/sources.list.erb | 22 + .../modules/apt/templates/preferences_snippet.erb | 4 + .../apt/templates/preferences_snippet_release.erb | 4 + 76 files changed, 2849 insertions(+) create mode 100644 puppet/modules/apt/.gitignore create mode 100644 puppet/modules/apt/.gitlab-ci.yml create mode 100644 puppet/modules/apt/.gitrepo create mode 100644 puppet/modules/apt/Gemfile create mode 100644 puppet/modules/apt/LICENSE create mode 100644 puppet/modules/apt/README create mode 100644 puppet/modules/apt/Rakefile create mode 100644 puppet/modules/apt/files/02show_upgraded create mode 100644 puppet/modules/apt/files/03clean create mode 100644 puppet/modules/apt/files/03clean_vserver create mode 100644 puppet/modules/apt/files/upgrade_initiator create mode 100644 puppet/modules/apt/lib/facter/apt_running.rb create mode 100644 puppet/modules/apt/lib/facter/debian_codename.rb create mode 100644 puppet/modules/apt/lib/facter/debian_lts.rb create mode 100644 puppet/modules/apt/lib/facter/debian_nextcodename.rb create mode 100644 puppet/modules/apt/lib/facter/debian_nextrelease.rb create mode 100644 puppet/modules/apt/lib/facter/debian_release.rb create mode 100644 puppet/modules/apt/lib/facter/ubuntu_codename.rb create mode 100644 puppet/modules/apt/lib/facter/ubuntu_nextcodename.rb create mode 100644 puppet/modules/apt/lib/facter/util/debian.rb create mode 100644 puppet/modules/apt/lib/facter/util/ubuntu.rb create mode 100644 puppet/modules/apt/manifests/apt_conf.pp create mode 100644 puppet/modules/apt/manifests/apticron.pp create mode 100644 puppet/modules/apt/manifests/cron/base.pp create mode 100644 puppet/modules/apt/manifests/cron/dist_upgrade.pp create mode 100644 puppet/modules/apt/manifests/cron/download.pp create mode 100644 puppet/modules/apt/manifests/dist_upgrade.pp create mode 100644 puppet/modules/apt/manifests/dist_upgrade/initiator.pp create mode 100644 puppet/modules/apt/manifests/dot_d_directories.pp create mode 100644 puppet/modules/apt/manifests/dselect.pp create mode 100644 puppet/modules/apt/manifests/init.pp create mode 100644 puppet/modules/apt/manifests/key.pp create mode 100644 puppet/modules/apt/manifests/key/plain.pp create mode 100644 puppet/modules/apt/manifests/listchanges.pp create mode 100644 puppet/modules/apt/manifests/params.pp create mode 100644 puppet/modules/apt/manifests/preferences.pp create mode 100644 puppet/modules/apt/manifests/preferences/absent.pp create mode 100644 puppet/modules/apt/manifests/preferences_snippet.pp create mode 100644 puppet/modules/apt/manifests/preseeded_package.pp create mode 100644 puppet/modules/apt/manifests/proxy_client.pp create mode 100644 puppet/modules/apt/manifests/reboot_required_notify.pp create mode 100644 puppet/modules/apt/manifests/sources_list.pp create mode 100644 puppet/modules/apt/manifests/unattended_upgrades.pp create mode 100644 puppet/modules/apt/manifests/update.pp create mode 100644 puppet/modules/apt/manifests/upgrade_package.pp create mode 100644 puppet/modules/apt/spec/spec_helper.rb create mode 100644 puppet/modules/apt/spec/unit/custom_facts_spec.rb create mode 100644 puppet/modules/apt/templates/20proxy.erb create mode 100644 puppet/modules/apt/templates/50unattended-upgrades.erb create mode 120000 puppet/modules/apt/templates/Debian/apticron_jessie.erb create mode 100644 puppet/modules/apt/templates/Debian/apticron_lenny.erb create mode 120000 puppet/modules/apt/templates/Debian/apticron_sid.erb create mode 100644 puppet/modules/apt/templates/Debian/apticron_squeeze.erb create mode 100644 puppet/modules/apt/templates/Debian/apticron_wheezy.erb create mode 120000 puppet/modules/apt/templates/Debian/listchanges_jessie.erb create mode 100644 puppet/modules/apt/templates/Debian/listchanges_lenny.erb create mode 120000 puppet/modules/apt/templates/Debian/listchanges_sid.erb create mode 120000 puppet/modules/apt/templates/Debian/listchanges_squeeze.erb create mode 120000 puppet/modules/apt/templates/Debian/listchanges_wheezy.erb create mode 100644 puppet/modules/apt/templates/Debian/preferences_jessie.erb create mode 100644 puppet/modules/apt/templates/Debian/preferences_lenny.erb create mode 100644 puppet/modules/apt/templates/Debian/preferences_sid.erb create mode 100644 puppet/modules/apt/templates/Debian/preferences_squeeze.erb create mode 100644 puppet/modules/apt/templates/Debian/preferences_wheezy.erb create mode 100644 puppet/modules/apt/templates/Debian/sources.list.erb create mode 120000 puppet/modules/apt/templates/Ubuntu/preferences_lucid.erb create mode 100644 puppet/modules/apt/templates/Ubuntu/preferences_maverick.erb create mode 120000 puppet/modules/apt/templates/Ubuntu/preferences_oneiric.erb create mode 120000 puppet/modules/apt/templates/Ubuntu/preferences_precise.erb create mode 120000 puppet/modules/apt/templates/Ubuntu/preferences_utopic.erb create mode 120000 puppet/modules/apt/templates/Ubuntu/preferences_vivid.erb create mode 120000 puppet/modules/apt/templates/Ubuntu/preferences_wily.erb create mode 120000 puppet/modules/apt/templates/Ubuntu/preferences_xenial.erb create mode 100644 puppet/modules/apt/templates/Ubuntu/sources.list.erb create mode 100644 puppet/modules/apt/templates/preferences_snippet.erb create mode 100644 puppet/modules/apt/templates/preferences_snippet_release.erb (limited to 'puppet/modules') diff --git a/puppet/modules/apt/.gitignore b/puppet/modules/apt/.gitignore new file mode 100644 index 00000000..a54aa971 --- /dev/null +++ b/puppet/modules/apt/.gitignore @@ -0,0 +1,12 @@ +/pkg/ +/Gemfile.lock +/vendor/ +/spec/fixtures/manifests/* +/spec/fixtures/modules/* +!/spec/fixtures/modules/apt +!/spec/fixtures/modules/apt/* +/.vagrant/ +/.bundle/ +/coverage/ +/.idea/ +*.iml diff --git a/puppet/modules/apt/.gitlab-ci.yml b/puppet/modules/apt/.gitlab-ci.yml new file mode 100644 index 00000000..f7b8ecad --- /dev/null +++ b/puppet/modules/apt/.gitlab-ci.yml @@ -0,0 +1,12 @@ +before_script: + - ruby -v + - gem install bundler --no-ri --no-rdoc + - bundle install --jobs $(nproc) "${FLAGS[@]}" + +# don't fail on lint warnings +rspec: + script: + - bundle exec rake lint || /bin/true + - bundle exec rake syntax + - bundle exec rake validate + - bundle exec rake spec diff --git a/puppet/modules/apt/.gitrepo b/puppet/modules/apt/.gitrepo new file mode 100644 index 00000000..1dd57eb5 --- /dev/null +++ b/puppet/modules/apt/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_apt + branch = master + commit = 33c61e8df59db1abbed379a9e9790946060a8f1e + parent = 4ccae8700fb136bfbc6b7ef7bb0ab482e632139f + cmdver = 0.3.0 diff --git a/puppet/modules/apt/Gemfile b/puppet/modules/apt/Gemfile new file mode 100644 index 00000000..8925a904 --- /dev/null +++ b/puppet/modules/apt/Gemfile @@ -0,0 +1,13 @@ +source "https://rubygems.org" + +group :test do + gem "rake" + gem "rspec", '< 3.2.0' + gem "puppet", ENV['PUPPET_VERSION'] || ENV['GEM_PUPPET_VERSION'] || ENV['PUPPET_GEM_VERSION'] || '~> 3.7.0' + gem "facter", ENV['FACTER_VERSION'] || ENV['GEM_FACTER_VERSION'] || ENV['FACTER_GEM_VERSION'] || '~> 2.2.0' + gem "rspec-puppet" + gem "puppetlabs_spec_helper" + gem "metadata-json-lint" + gem "rspec-puppet-facts" + gem "mocha" +end diff --git a/puppet/modules/apt/LICENSE b/puppet/modules/apt/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/puppet/modules/apt/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/puppet/modules/apt/README b/puppet/modules/apt/README new file mode 100644 index 00000000..00db7d8e --- /dev/null +++ b/puppet/modules/apt/README @@ -0,0 +1,602 @@ + +Overview +======== + +This module manages apt on Debian. + +It keeps dpkg's and apt's databases as well as the keyrings for securing +package download current. + +backports.debian.org is added. + +/etc/apt/sources.list and /etc/apt/preferences are managed. More +recent Debian releases are pinned to very low values by default to +prevent accidental upgrades. + +Ubuntu support is lagging behind but not absent either. + +! Upgrade Notice ! + + * The `disable_update` parameter has been removed. The main apt class + defaults to *not* run an `apt-get update` on every run anyway so this + parameter seems useless. + You can include the `apt::update` class if you want it to be run every time. + + * The `apt::upgrade_package` now doesn't automatically call an Exec['apt_updated'] + anymore, so you would need to include `apt::update` now by hand. + + * The apt::codename parameter has been removed. In its place, the + debian_codename fact may be overridden via an environment variable. This + will affect all other debian_* facts, and achieve the same result. + + FACTER_debian_codename=jessie puppet agent -t + + * If you were using custom 50unattended-upgrades.${::lsbdistcodename} in your + site_apt, these are no longer supported. You should migrate to passing + $blacklisted_packages to the apt::unattended_upgrades class. + + * the apt class has been moved to a paramterized class. if you were including + this class before, after passing some variables, you will need to move to + instantiating the class with those variables instead. For example, if you + had the following in your manifests: + + $apt_debian_url = 'http://localhost:9999/debian/' + $apt_use_next_release = true + include apt + + you will need to remove the variables, and the include and instead do + the following: + + class { 'apt': debian_url => 'http://localhost:9999/debian/', use_next_release => true } + + previously, you could manually set $lsbdistcodename which would enable forced + upgrades, but because this is a top-level facter variable, and newer puppet + versions do not let you assign variables to other namespaces, this is no + longer possible. However, there is a way to obtain this functionality, and + that is to pass the 'codename' parameter to the apt class, which will change + the sources.list and preferences files to be the codename you set, allowing + you to trigger upgrades: + + include apt::dist_upgrade + class { 'apt': codename => 'wheezy', notify => Exec['apt_dist-upgrade'] } + + * the apticron class has been moved to a parameterized class. if you were + including this class before, you will need to move to instantiating the + class instead. For example, if you had the following in your manifests: + + $apticron_email = 'foo@example.com' + $apticron_notifynew = '1' + ... any $apticron_* variables + include apticron + + you will need to remove the variables, and the include and instead do the + following: + + class { 'apt::apticron': email => 'foo@example.com', notifynew => '1' } + + * the apt::listchanges class has been moved to a paramterized class. if you + were including this class before, after passing some variables, you will need + to move to instantiating the class with those variables instead. For example, + if you had the following in your manifests: + + $apt_listchanges_email = 'foo@example.com' + ... any $apt_listchanges_* variables + include apt::listchanges + + you will need to remove the variables, and the include and instead do the + following: + + class { 'apt::listchanges': email => 'foo@example.com' } + + * the apt::proxy_client class has been moved to a paramterized class. if you + were including this class before, after passing some variables, you will need + to move to instantiating the class with those variables instead. For example, + if you had the following in your manifests: + + $apt_proxy = 'http://proxy.domain' + $apt_proxy_port = 666 + include apt::proxy_client + + you will need to remove the variables, and the include and instead do the + following: + + class { 'apt::proxy_client': proxy => 'http://proxy.domain', port => '666' } + +Requirements +============ + +This module needs: + +- the lsb-release package should be installed on the server prior to running + puppet. otherwise, all of the $::lsb* facts will be empty during runs. +- the common module: https://gitlab.com/shared-puppet-modules-group/common + +By default, on normal hosts, this module sets the configuration option +DSelect::Clean to 'auto'. On virtual servers, the value is set by default to +'pre-auto', because virtual servers are usually more space-bound and have better +recovery mechanisms via the host: + +From apt.conf(5), 0.7.2: + "Cache Clean mode; this value may be one of always, prompt, auto, + pre-auto and never. always and prompt will remove all packages + from the cache after upgrading, prompt (the default) does so + conditionally. auto removes only those packages which are no + longer downloadable (replaced with a new version for + instance). pre-auto performs this action before downloading new + packages." + +To change the default setting for DSelect::Clean, you can create a file named +"03clean" or "03clean_vserver" in your site_apt module's files directory. You +can also define this for a specific host by creating a file in a subdirectory of +the site_apt modules' files directory that is named the same as the +host. (example: site_apt/files/some.host.com/03clean, or +site_apt/files/some.host.com/03clean_vserver) + +Classes +======= + +apt +--- + +The apt class sets up most of the documented functionality. To use functionality +that is not enabled by default, you must set one of the following parameters. + +Example usage: + + class { 'apt': use_next_release => true, debian_url => 'http://localhost:9999/debian/' } + +Class parameters: + +* use_lts + + If this variable is set to true the CODENAME-lts sources (such as + squeeze-lts) are added. + + By default this is false for backward compatibility with older + versions of this module. + +* use_volatile + + If this variable is set to true the CODENAME-updates sources (such as + squeeze-updates) are added. + + By default this is false for backward compatibility with older + versions of this module. + +* include_src + + If this variable is set to true a deb-src source is added for every + added binary archive source. + + By default this is false for backward compatibility with older + versions of this module. + +* use_next_release + + If this variable is set to true the sources for the next Debian + release are added. The default pinning configuration pins it to very + low values. + + By default this is false for backward compatibility with older + versions of this module. + +* debian_url, security_url, backports_url, volatile_url + + These variables allow to override the default APT mirrors respectively + used for the standard Debian archives, the Debian security archive, + the Debian official backports and the Debian Volatile archive. + +* ubuntu_url + + These variables allows to override the default APT mirror used for all + standard Ubuntu archives (including updates, security, backports). + +* repos + + If this variable is set the default repositories list ("main contrib non-free") + is overriden. + +* disable_update + + Disable "apt-get update" which is normally triggered by apt::upgrade_package + and apt::dist_upgrade. + + Note that nodes can be updated once a day by using + APT::Periodic::Update-Package-Lists "1"; + in i.e. /etc/apt/apt.conf.d/80_apt_update_daily. + +* custom_preferences + + For historical reasons (Debian Lenny's version of APT did not support the use + of the preferences.d directory for putting fragments of 'preferences'), this + module will manage a default generic apt/preferences file with more + recent releases pinned to very low values so that any package + installation will not accidentally pull in packages from those suites + unless you explicitly specify the version number. This file will be + complemented with all of the preferences_snippet calls (see below). + + If the default preferences template doesn't suit your needs, you can create a + template located in your site_apt module, and set custom_preferences with the + content (eg. custom_preferences => template('site_apt/preferences') ) + + Setting this variable to false before including this class will force the + apt/preferences file to be absent: + + class { 'apt': custom_preferences => false } + +* custom_sources_list + + By default this module will use a basic apt/sources.list template with + a generic Debian mirror. If you need to set more specific sources, + e.g. changing the sections included in the source, etc. you can set + this variable to the content that you desire to use instead. + + For example, setting this variable will pull in the + templates/site_apt/sources.list file: + + class { 'apt': custom_sources_list => template('site_apt/sources.list') } + +* custom_key_dir + + If you have different apt-key files that you want to get added to your + apt keyring, you can set this variable to a path in your fileserver + where individual key files can be placed. If this is set and keys + exist there, this module will 'apt-key add' each key. + + The debian-archive-keyring package is installed and kept current up to the + latest revision (this includes the backports archive keyring). + +apt::apticron +------------- + +When you instantiate this class, apticron will be installed, with the following +defaults, which you are free to change: + + $ensure_version = 'installed', + $config = "apt/${::operatingsystem}/apticron_${::lsbdistcodename}.erb", + $email = 'root', + $diff_only = '1', + $listchanges_profile = 'apticron', + $system = false, + $ipaddressnum = false, + $ipaddresses = false, + $notifyholds = '0', + $notifynew = '0', + $customsubject = '' + +Example usage: + + class { 'apt::apticron': email => 'foo@example.com', notifynew => '1' } + +apt::cron::download +------------------- + +This class sets up cron-apt so that it downloads upgradable packages, does not +actually do any upgrade and emails when the output changes. + +cron-apt defaults to run at 4 AM. You may want to set the +$apt_cron_hours variable before you include the class: its value will +be passed as the "hours" parameter of a cronjob. Example: + + # Run cron-apt every three hours + $apt_cron_hours = '*/3' + +Note that the default 4 AM cronjob won't be disabled. + +apt::cron::dist_upgrade +----------------------- + +This class sets up cron-apt so that it dist-upgrades the system and +emails when upgrades are performed. + +See apt::cron::download above if you need to run cron-apt more often +than once a day. + +apt::dist_upgrade +----------------- + +This class provides the Exec['apt_dist-upgrade'] resource that +dist-upgrade's the system. + +This exec is set as refreshonly so including this class does not +trigger any action per-se: other resources may notify it, other +classes may inherit from this one and add to its subscription list +using the plusignment ('+>') operator. A real-world example can be +seen in the apt::dist_upgrade::initiator source. + +apt::dist_upgrade::initiator +---------------------------- + +This class automatically dist-upgrade's the system when an initiator +file's content changes. The initiator file is copied from the first +available source amongst the following ones, in decreasing priority +order: + +- puppet:///modules/site_apt/${::fqdn}/upgrade_initiator +- puppet:///modules/site_apt/upgrade_initiator +- puppet:///modules/apt/upgrade_initiator + +This is useful when one does not want to setup a fully automated +upgrade process but still needs a way to manually trigger full +upgrades of any number of systems at scheduled times. + +Beware: a dist-upgrade is triggered the first time Puppet runs after +this class has been included. This is actually the single reason why +this class is not enabled by default. + +When this class is included the APT indexes are updated on every +Puppet run due to the author's lack of Puppet wizardry. + +apt::dselect +------------ + +This class, when included, installs dselect and switches it to expert mode to +suppress superfluous help screens. + +apt::listchanges +---------------- + +This class, when instantiated, installs apt-listchanges and configures it using +the following parameterized variables, which can be changed: + + version = 'present' + config = "apt/${::operatingsystem}/listchanges_${::lsbrelease}.erb" + frontend = 'pager' + email = 'root' + confirm = 0 + saveseen = '/var/lib/apt/listchanges.db' + which = 'both' + + Example usage: + class { 'apt::listchanges': email => 'foo@example.com' } + +apt::proxy_client +----------------- + +This class adds the right configuration to apt to make it fetch packages via a +proxy. The class parameters apt_proxy and apt_proxy_port need to be set: + +You can set the 'proxy' class parameter variable to the URL of the proxy that +will be used. By default, the proxy will be queried on port 3142, but you can +change the port number by setting the 'port' class parameter. + +Example: + + class { 'apt::proxy_client': proxy => 'http://proxy.domain', port => '666' } + +apt::reboot_required_notify +--------------------------- + +This class installs a daily cronjob that checks if a package upgrade +requires the system to be rebooted; if so, cron sends a notification +email to root. + +apt::unattended_upgrades +------------------------ + +If this class is included, it will install the package 'unattended-upgrades' +and configure it to daily upgrade the system. + +The class has the following parameters that you can use to change the contents +of the configuration file. The values shown here are the default values: + + * $config_content = undef + * $config_template = 'apt/50unattended-upgrades.erb' + * $mailonlyonerror = true + * $mail_recipient = 'root' + * $blacklisted_packages = [] + +Note that using $config_content actually specifies all of the configuration +contents and thus makes the other parameters useless. + +example: + + class { 'apt::unattended_upgrades': + config_template => 'site_apt/50unattended-upgrades.jessie', + blacklisted_packages => [ + 'libc6', 'libc6-dev', 'libc6-i686', 'mysql-server', 'redmine', 'nodejs', + 'bird' + ], + } + +Defines +======= + +apt::apt_conf +------------- + +Creates a file in the apt/apt.conf.d directory to easily add configuration +components. One can use either the 'source' meta-parameter to specify a list of +static files to include from the puppet fileserver or the 'content' +meta-parameter to define content inline or with the help of a template. + +Example: + + apt::apt_conf { '80download-only': + source => 'puppet:///modules/site_apt/80download-only', + } + +apt::preferences_snippet +------------------------ + +A way to add pinning information to files in /etc/apt/preferences.d/ + +Example: + + apt::preferences_snippet { + 'irssi-plugin-otr': + release => 'squeeze-backports', + priority => 999; + } + + apt::preferences_snippet { + 'unstable_fallback': + package => '*', + release => 'unstable', + priority => 1; + } + + apt::preferences_snippet { + 'ttdnsd': + pin => 'origin deb.torproject.org', + priority => 999; + } + +The names of the resources will be used as the names of the files in the +preferences.d directory, so you should ensure that resource names follow the +prescribed naming scheme. + +From apt_preferences(5): + Note that the files in the /etc/apt/preferences.d directory are parsed in + alphanumeric ascending order and need to obey the following naming + convention: The files have no or "pref" as filename extension and which + only contain alphanumeric, hyphen (-), underscore (_) and period (.) + characters - otherwise they will be silently ignored. + +apt::preseeded_package +---------------------- + +This simplifies installation of packages for which you wish to preseed the +answers to debconf. For example, if you wish to provide a preseed file for the +locales package, you would place the locales.seed file in +'site_apt/templates/${::lsbdistcodename}/locales.seeds' and then include the +following in your manifest: + + apt::preseeded_package { locales: } + +You can also specify the content of the seed via the content parameter, +for example: + + apt::preseeded_package { 'apticron': + content => 'apticron apticron/notification string root@example.com', + } + +apt::sources_list +----------------- + +Creates a file in the apt/sources.list.d directory to easily add additional apt +sources. One can use either the 'source' meta-parameter to specify a list of +static files to include from the puppet fileserver or the 'content' +meta-parameter to define content inline or with the help of a template. Ending +the resource name in '.list' is optional: it will be automatically added to the +file name if not present in the resource name. + +Example: + + apt::sources_list { 'company_internals': + source => [ "puppet:///modules/site_apt/${::fqdn}/company_internals.list", + 'puppet:///modules/site_apt/company_internals.list' ], + } + +apt::key +-------- + +Deploys a secure apt OpenPGP key. This usually accompanies the +sources.list snippets above for third party repositories. For example, +you would do: + + apt::key { 'neurodebian.gpg': + ensure => present, + source => 'puppet:///modules/site_apt/neurodebian.gpg', + } + +This deploys the key in the `/etc/apt/trusted.gpg.d` directory, which +is assumed by secure apt to be binary OpenPGP keys and *not* +"ascii-armored" or "plain text" OpenPGP key material. For the latter, +use `apt::key::plain`. + +The `.gpg` extension is compulsory for `apt` to pickup the key properly. + +apt::key::plain +--------------- + +Deploys a secure apt OpenPGP key. This usually accompanies the +sources.list snippets above for third party repositories. For example, +you would do: + + apt::key::plain { 'neurodebian.asc': + source => 'puppet:///modules/site_apt/neurodebian.asc', + } + +This deploys the key in the `${apt_base_dir}/keys` directory (as +opposed to `$custom_key_dir` which deploys it in `keys.d`). The reason +this exists on top of `$custom_key_dir` is to allow a more +decentralised distribution of those keys, without having all modules +throw their keys in the same directory in the manifests. + +Note that this model does *not* currently allow keys to be removed! +Use `apt::key` instead for a more practical, revokable approach, but +that needs binary keys. + +apt::upgrade_package +-------------------- + +This simplifies upgrades for DSA security announcements or point-releases. This +will ensure that the named package is upgraded to the version specified, only if +the package is installed, otherwise nothing happens. If the specified version +is 'latest' (the default), then the package is ensured to be upgraded to the +latest package revision when it becomes available. + +For example, the following upgrades the perl package to version 5.8.8-7etch1 +(if it is installed), it also upgrades the syslog-ng and perl-modules packages +to their latest (also, only if they are installed): + +upgrade_package { 'perl': + version => '5.8.8-7etch1'; + 'syslog-ng': + version => latest; + 'perl-modules': +} + +Resources +========= + +File['apt_config'] +------------------ + +Use this resource to depend on or add to a completed apt configuration + +Exec['apt_updated'] +------------------- + +After this point the APT indexes are up-to-date. +This resource is set to `refreshonly => true` so it is not run on +every puppetrun. To run this every time, you can include the `apt::update` +class. + +This resource is usually used like this to ensure current packages are +installed by Package resources: + + include apt::update + Package { require => Exec['apt_updated'] } + +Note that nodes can be updated once a day by using + + APT::Periodic::Update-Package-Lists "1"; + +in i.e. /etc/apt/apt.conf.d/80_apt_update_daily. + + +Tests +===== + +To run pupept rspec tests: + + bundle install --path vendor/bundle + bundle exec rake spec + +Using different facter/puppet versions: + + FACTER_GEM_VERSION=1.6.10 PUPPET_GEM_VERSION=2.7.23 bundle install --path vendor/bundle + bundle exec rake spec + +Licensing +========= + +This puppet module is licensed under the GPL version 3 or later. Redistribution +and modification is encouraged. + +The GPL version 3 license text can be found in the "LICENSE" file accompanying +this puppet module, or at the following URL: + +http://www.gnu.org/licenses/gpl-3.0.html diff --git a/puppet/modules/apt/Rakefile b/puppet/modules/apt/Rakefile new file mode 100644 index 00000000..85326bb4 --- /dev/null +++ b/puppet/modules/apt/Rakefile @@ -0,0 +1,19 @@ +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' +PuppetLint.configuration.send('disable_80chars') +PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"] + +desc "Validate manifests, templates, and ruby files" +task :validate do + Dir['manifests/**/*.pp'].each do |manifest| + sh "puppet parser validate --noop #{manifest}" + end + Dir['spec/**/*.rb','lib/**/*.rb'].each do |ruby_file| + sh "ruby -c #{ruby_file}" unless ruby_file =~ /spec\/fixtures/ + end + Dir['templates/**/*.erb'].each do |template| + sh "erb -P -x -T '-' #{template} | ruby -c" + end +end + +task :test => [:lint, :syntax , :validate, :spec] diff --git a/puppet/modules/apt/files/02show_upgraded b/puppet/modules/apt/files/02show_upgraded new file mode 100644 index 00000000..bb127d41 --- /dev/null +++ b/puppet/modules/apt/files/02show_upgraded @@ -0,0 +1,4 @@ +// This file is managed by Puppet +// all local modifications will be overwritten + +APT::Get::Show-Upgraded true; diff --git a/puppet/modules/apt/files/03clean b/puppet/modules/apt/files/03clean new file mode 100644 index 00000000..3d20924a --- /dev/null +++ b/puppet/modules/apt/files/03clean @@ -0,0 +1,4 @@ +// This file is managed by Puppet +// all local modifications will be overwritten + +DSelect::Clean auto; diff --git a/puppet/modules/apt/files/03clean_vserver b/puppet/modules/apt/files/03clean_vserver new file mode 100644 index 00000000..6bb84e58 --- /dev/null +++ b/puppet/modules/apt/files/03clean_vserver @@ -0,0 +1,4 @@ +// This file is managed by Puppet +// all local modifications will be overwritten + +DSelect::Clean pre-auto; diff --git a/puppet/modules/apt/files/upgrade_initiator b/puppet/modules/apt/files/upgrade_initiator new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/puppet/modules/apt/files/upgrade_initiator @@ -0,0 +1 @@ + diff --git a/puppet/modules/apt/lib/facter/apt_running.rb b/puppet/modules/apt/lib/facter/apt_running.rb new file mode 100644 index 00000000..e8f2156e --- /dev/null +++ b/puppet/modules/apt/lib/facter/apt_running.rb @@ -0,0 +1,7 @@ +Facter.add("apt_running") do + setcode do + #Facter::Util::Resolution.exec('/usr/bin/dpkg -s mysql-server >/dev/null 2>&1 && echo true || echo false') + Facter::Util::Resolution.exec('pgrep apt-get >/dev/null 2>&1 && echo true || echo false') + end +end + diff --git a/puppet/modules/apt/lib/facter/debian_codename.rb b/puppet/modules/apt/lib/facter/debian_codename.rb new file mode 100644 index 00000000..254877aa --- /dev/null +++ b/puppet/modules/apt/lib/facter/debian_codename.rb @@ -0,0 +1,42 @@ +begin + require 'facter/util/debian' +rescue LoadError + require "#{File.dirname(__FILE__)}/util/debian" +end + +def version_to_codename(version) + if Facter::Util::Debian::CODENAMES.has_key?(version) + return Facter::Util::Debian::CODENAMES[version] + else + Facter.warn("Could not determine codename from version '#{version}'") + end +end + +Facter.add(:debian_codename) do + has_weight 99 + confine :operatingsystem => 'Debian' + setcode do + Facter.value('lsbdistcodename') + end +end + +Facter.add(:debian_codename) do + has_weight 66 + confine :operatingsystem => 'Debian' + setcode do + version_to_codename(Facter.value('operatingsystemmajrelease')) + end +end + +Facter.add(:debian_codename) do + has_weight 33 + confine :operatingsystem => 'Debian' + setcode do + debian_version = File.open('/etc/debian_version', &:readline) + if debian_version.match(/^\d+/) + version_to_codename(debian_version.scan(/^(\d+)/)[0][0]) + elsif debian_version.match(/^[a-z]+\/(sid|unstable)/) + debian_version.scan(/^([a-z]+)\//)[0][0] + end + end +end diff --git a/puppet/modules/apt/lib/facter/debian_lts.rb b/puppet/modules/apt/lib/facter/debian_lts.rb new file mode 100644 index 00000000..f53a9eb8 --- /dev/null +++ b/puppet/modules/apt/lib/facter/debian_lts.rb @@ -0,0 +1,16 @@ +begin + require 'facter/util/debian' +rescue LoadError + require "#{File.dirname(__FILE__)}/util/debian" +end + +Facter.add(:debian_lts) do + confine :operatingsystem => 'Debian' + setcode do + if Facter::Util::Debian::LTS.include? Facter.value('debian_codename') + true + else + false + end + end +end diff --git a/puppet/modules/apt/lib/facter/debian_nextcodename.rb b/puppet/modules/apt/lib/facter/debian_nextcodename.rb new file mode 100644 index 00000000..c4c569b2 --- /dev/null +++ b/puppet/modules/apt/lib/facter/debian_nextcodename.rb @@ -0,0 +1,23 @@ +begin + require 'facter/util/debian' +rescue LoadError + require "#{File.dirname(__FILE__)}/util/debian" +end + +def debian_codename_to_next(codename) + if codename == "sid" + return "experimental" + else + codenames = Facter::Util::Debian::CODENAMES + versions = Facter::Util::Debian::CODENAMES.invert + current_version = versions[codename] + return codenames[(current_version.to_i + 1).to_s] + end +end + +Facter.add(:debian_nextcodename) do + confine :operatingsystem => 'Debian' + setcode do + debian_codename_to_next(Facter.value('debian_codename')) + end +end diff --git a/puppet/modules/apt/lib/facter/debian_nextrelease.rb b/puppet/modules/apt/lib/facter/debian_nextrelease.rb new file mode 100644 index 00000000..2a9c4f5f --- /dev/null +++ b/puppet/modules/apt/lib/facter/debian_nextrelease.rb @@ -0,0 +1,23 @@ +def debian_release_to_next(release) + releases = [ + 'oldoldoldstable', + 'oldoldstable', + 'oldstable', + 'stable', + 'testing', + 'unstable', + 'experimental', + ] + if releases.include? release + if releases.index(release)+1 < releases.count + return releases[releases.index(release)+1] + end + end +end + +Facter.add(:debian_nextrelease) do + confine :operatingsystem => 'Debian' + setcode do + debian_release_to_next(Facter.value('debian_release')) + end +end diff --git a/puppet/modules/apt/lib/facter/debian_release.rb b/puppet/modules/apt/lib/facter/debian_release.rb new file mode 100644 index 00000000..2c334ccd --- /dev/null +++ b/puppet/modules/apt/lib/facter/debian_release.rb @@ -0,0 +1,38 @@ +begin + require 'facter/util/debian' +rescue LoadError + require "#{File.dirname(__FILE__)}/util/debian" +end + +def debian_codename_to_release(codename) + stable = Facter::Util::Debian::STABLE + versions = Facter::Util::Debian::CODENAMES.invert + release = nil + if codename == "sid" + release = "unstable" + elsif versions.has_key? codename + version = versions[codename].to_i + if version == stable + release = "stable" + elsif version < stable + release = "stable" + for i in version..stable - 1 + release = "old" + release + end + elsif version == stable + 1 + release = "testing" + end + end + if release.nil? + Facter.warn("Could not determine release from codename #{codename}!") + end + return release +end + +Facter.add(:debian_release) do + has_weight 99 + confine :operatingsystem => 'Debian' + setcode do + debian_codename_to_release(Facter.value('debian_codename')) + end +end diff --git a/puppet/modules/apt/lib/facter/ubuntu_codename.rb b/puppet/modules/apt/lib/facter/ubuntu_codename.rb new file mode 100644 index 00000000..814fd942 --- /dev/null +++ b/puppet/modules/apt/lib/facter/ubuntu_codename.rb @@ -0,0 +1,8 @@ +Facter.add(:ubuntu_codename) do + confine :operatingsystem => 'Ubuntu' + setcode do + Facter.value('lsbdistcodename') + end +end + + diff --git a/puppet/modules/apt/lib/facter/ubuntu_nextcodename.rb b/puppet/modules/apt/lib/facter/ubuntu_nextcodename.rb new file mode 100644 index 00000000..dcd1d426 --- /dev/null +++ b/puppet/modules/apt/lib/facter/ubuntu_nextcodename.rb @@ -0,0 +1,20 @@ +begin + require 'facter/util/ubuntu' +rescue LoadError + require "#{File.dirname(__FILE__)}/util/ubuntu" +end + +def ubuntu_codename_to_next(codename) + codenames = Facter::Util::Ubuntu::CODENAMES + i = codenames.index(codename) + if i and i+1 < codenames.count + return codenames[i+1] + end +end + +Facter.add(:ubuntu_nextcodename) do + confine :operatingsystem => 'Ubuntu' + setcode do + ubuntu_codename_to_next(Facter.value('ubuntu_codename')) + end +end diff --git a/puppet/modules/apt/lib/facter/util/debian.rb b/puppet/modules/apt/lib/facter/util/debian.rb new file mode 100644 index 00000000..290c17b5 --- /dev/null +++ b/puppet/modules/apt/lib/facter/util/debian.rb @@ -0,0 +1,18 @@ +module Facter + module Util + module Debian + STABLE = 8 + CODENAMES = { + "5" => "lenny", + "6" => "squeeze", + "7" => "wheezy", + "8" => "jessie", + "9" => "stretch", + "10" => "buster", + } + LTS = [ + "squeeze", + ] + end + end +end diff --git a/puppet/modules/apt/lib/facter/util/ubuntu.rb b/puppet/modules/apt/lib/facter/util/ubuntu.rb new file mode 100644 index 00000000..52c15e80 --- /dev/null +++ b/puppet/modules/apt/lib/facter/util/ubuntu.rb @@ -0,0 +1,21 @@ +module Facter + module Util + module Ubuntu + CODENAMES = [ + "lucid", + "maverick", + "natty", + "oneiric", + "precise", + "quantal", + "raring", + "saucy", + "trusty", + "utopic", + "vivid", + "wily", + "xenial" + ] + end + end +end diff --git a/puppet/modules/apt/manifests/apt_conf.pp b/puppet/modules/apt/manifests/apt_conf.pp new file mode 100644 index 00000000..949f6157 --- /dev/null +++ b/puppet/modules/apt/manifests/apt_conf.pp @@ -0,0 +1,45 @@ +define apt::apt_conf( + $ensure = 'present', + $source = '', + $content = undef, + $refresh_apt = true ) +{ + + if $source == '' and $content == undef { + fail("One of \$source or \$content must be specified for apt_conf ${name}") + } + + if $source != '' and $content != undef { + fail("Only one of \$source or \$content must specified for apt_conf ${name}") + } + + include apt::dot_d_directories + + # One would expect the 'file' resource on sources.list.d to trigger an + # apt-get update when files are added or modified in the directory, but it + # apparently doesn't. + file { "/etc/apt/apt.conf.d/${name}": + ensure => $ensure, + owner => root, + group => 0, + mode => '0644', + } + + if $source { + File["/etc/apt/apt.conf.d/${name}"] { + source => $source, + } + } + else { + File["/etc/apt/apt.conf.d/${name}"] { + content => $content, + } + } + + if $refresh_apt { + File["/etc/apt/apt.conf.d/${name}"] { + notify => Exec['apt_updated'], + } + } + +} diff --git a/puppet/modules/apt/manifests/apticron.pp b/puppet/modules/apt/manifests/apticron.pp new file mode 100644 index 00000000..9c94f9c9 --- /dev/null +++ b/puppet/modules/apt/manifests/apticron.pp @@ -0,0 +1,24 @@ +class apt::apticron( + $ensure_version = 'installed', + $config = "apt/${::operatingsystem}/apticron_${::debian_codename}.erb", + $email = 'root', + $diff_only = '1', + $listchanges_profile = 'apticron', + $system = false, + $ipaddressnum = false, + $ipaddresses = false, + $notifyholds = '0', + $notifynew = '0', + $customsubject = '' +) { + + package { 'apticron': ensure => $ensure_version } + + file { '/etc/apticron/apticron.conf': + content => template($apt::apticron::config), + owner => root, + group => root, + mode => '0644', + require => Package['apticron']; + } +} diff --git a/puppet/modules/apt/manifests/cron/base.pp b/puppet/modules/apt/manifests/cron/base.pp new file mode 100644 index 00000000..39fc3061 --- /dev/null +++ b/puppet/modules/apt/manifests/cron/base.pp @@ -0,0 +1,20 @@ +class apt::cron::base { + + package { 'cron-apt': ensure => installed } + + case $apt_cron_hours { + '': {} + default: { + # cron-apt defaults to run every night at 4 o'clock + # so we try not to run at the same time. + cron { 'apt_cron_every_N_hours': + command => 'test -x /usr/sbin/cron-apt && /usr/sbin/cron-apt', + user => root, + hour => "${apt_cron_hours}", + minute => 10, + require => Package['cron-apt'], + } + } + } + +} diff --git a/puppet/modules/apt/manifests/cron/dist_upgrade.pp b/puppet/modules/apt/manifests/cron/dist_upgrade.pp new file mode 100644 index 00000000..74403bb7 --- /dev/null +++ b/puppet/modules/apt/manifests/cron/dist_upgrade.pp @@ -0,0 +1,29 @@ +class apt::cron::dist_upgrade inherits apt::cron::base { + + $action = "autoclean -y +dist-upgrade -y -o APT::Get::Show-Upgraded=true -o 'DPkg::Options::=--force-confold' +" + + file { '/etc/cron-apt/action.d/3-download': + ensure => absent, + } + + package { 'apt-listbugs': ensure => absent } + + file { '/etc/cron-apt/action.d/4-dist-upgrade': + content => $action, + owner => root, + group => 0, + mode => '0644', + require => Package[cron-apt]; + } + + file { '/etc/cron-apt/config.d/MAILON': + content => "MAILON=upgrade\n", + owner => root, + group => 0, + mode => '0644', + require => Package[cron-apt]; + } + +} diff --git a/puppet/modules/apt/manifests/cron/download.pp b/puppet/modules/apt/manifests/cron/download.pp new file mode 100644 index 00000000..4a19fec1 --- /dev/null +++ b/puppet/modules/apt/manifests/cron/download.pp @@ -0,0 +1,27 @@ +class apt::cron::download inherits apt::cron::base { + + $action = "autoclean -y +dist-upgrade -d -y -o APT::Get::Show-Upgraded=true +" + + file { '/etc/cron-apt/action.d/4-dist-upgrade': + ensure => absent, + } + + file { '/etc/cron-apt/action.d/3-download': + content => $action, + require => Package[cron-apt], + owner => root, + group => 0, + mode => '0644'; + } + + file { '/etc/cron-apt/config.d/MAILON': + content => "MAILON=changes\n", + require => Package[cron-apt], + owner => root, + group => 0, + mode => '0644'; + } + +} diff --git a/puppet/modules/apt/manifests/dist_upgrade.pp b/puppet/modules/apt/manifests/dist_upgrade.pp new file mode 100644 index 00000000..19c031e0 --- /dev/null +++ b/puppet/modules/apt/manifests/dist_upgrade.pp @@ -0,0 +1,9 @@ +class apt::dist_upgrade { + + exec { 'apt_dist-upgrade': + command => '/usr/bin/apt-get -q -y -o \'DPkg::Options::=--force-confold\' dist-upgrade', + refreshonly => true, + before => Exec['apt_updated'] + } + +} diff --git a/puppet/modules/apt/manifests/dist_upgrade/initiator.pp b/puppet/modules/apt/manifests/dist_upgrade/initiator.pp new file mode 100644 index 00000000..d2389883 --- /dev/null +++ b/puppet/modules/apt/manifests/dist_upgrade/initiator.pp @@ -0,0 +1,23 @@ +class apt::dist_upgrade::initiator inherits apt::dist_upgrade { + + $initiator = 'upgrade_initiator' + $initiator_abs = "${apt::apt_base_dir}/${initiator}" + + file { 'apt_upgrade_initiator': + mode => '0644', + owner => root, + group => 0, + path => $initiator_abs, + checksum => md5, + source => [ + "puppet:///modules/site_apt/${::fqdn}/${initiator}", + "puppet:///modules/site_apt/${initiator}", + "puppet:///modules/apt/${initiator}", + ], + } + + Exec['apt_dist-upgrade'] { + subscribe +> File['apt_upgrade_initiator'], + } + +} diff --git a/puppet/modules/apt/manifests/dot_d_directories.pp b/puppet/modules/apt/manifests/dot_d_directories.pp new file mode 100644 index 00000000..0ace8630 --- /dev/null +++ b/puppet/modules/apt/manifests/dot_d_directories.pp @@ -0,0 +1,15 @@ +class apt::dot_d_directories { + + # watch .d directories and ensure they are present + file { + '/etc/apt/apt.conf.d': + ensure => directory, + checksum => mtime, + notify => Exec['apt_updated']; + '/etc/apt/sources.list.d': + ensure => directory, + checksum => mtime, + notify => Exec['apt_updated']; + } + +} diff --git a/puppet/modules/apt/manifests/dselect.pp b/puppet/modules/apt/manifests/dselect.pp new file mode 100644 index 00000000..2b99a43d --- /dev/null +++ b/puppet/modules/apt/manifests/dselect.pp @@ -0,0 +1,11 @@ +# manage dselect, like +# suppressing the annoying help texts +class apt::dselect { + + file_line { 'dselect_expert': + path => '/etc/dpkg/dselect.cfg', + line => 'expert', + } + + package { 'dselect': ensure => installed } +} diff --git a/puppet/modules/apt/manifests/init.pp b/puppet/modules/apt/manifests/init.pp new file mode 100644 index 00000000..4c44af2a --- /dev/null +++ b/puppet/modules/apt/manifests/init.pp @@ -0,0 +1,150 @@ +# apt.pp - common components and defaults for handling apt +# Copyright (C) 2008 Micah Anerson +# Copyright (C) 2007 David Schmitt +# See LICENSE for the full license granted to you. + +class apt( + $use_lts = $apt::params::use_lts, + $use_volatile = $apt::params::use_volatile, + $use_backports = $apt::params::use_backports, + $include_src = $apt::params::include_src, + $use_next_release = $apt::params::use_next_release, + $debian_url = $apt::params::debian_url, + $security_url = $apt::params::security_url, + $backports_url = $apt::params::backports_url, + $lts_url = $apt::params::lts_url, + $volatile_url = $apt::params::volatile_url, + $ubuntu_url = $apt::params::ubuntu_url, + $repos = $apt::params::repos, + $custom_preferences = $apt::params::custom_preferences, + $custom_sources_list = '', + $custom_key_dir = $apt::params::custom_key_dir +) inherits apt::params { + case $::operatingsystem { + 'debian': { + $real_repos = $repos ? { + 'auto' => 'main contrib non-free', + default => $repos, + } + } + 'ubuntu': { + $real_repos = $repos ? { + 'auto' => 'main restricted universe multiverse', + default => $repos, + } + } + } + + package { 'apt': + ensure => installed, + require => undef, + } + + $sources_content = $custom_sources_list ? { + '' => template( "apt/${::operatingsystem}/sources.list.erb"), + default => $custom_sources_list + } + file { + # include main and security + # additional sources should be included via the apt::sources_list define + '/etc/apt/sources.list': + content => $sources_content, + notify => Exec['apt_updated'], + owner => root, + group => 0, + mode => '0644'; + } + + apt_conf { '02show_upgraded': + source => [ "puppet:///modules/site_apt/${::fqdn}/02show_upgraded", + 'puppet:///modules/site_apt/02show_upgraded', + 'puppet:///modules/apt/02show_upgraded' ] + } + + if ( $::virtual == 'vserver' ) { + apt_conf { '03clean_vserver': + source => [ "puppet:///modules/site_apt/${::fqdn}/03clean_vserver", + 'puppet:///modules/site_apt/03clean_vserver', + 'puppet:///modules/apt/03clean_vserver' ], + alias => '03clean'; + } + } + else { + apt_conf { '03clean': + source => [ "puppet:///modules/site_apt/${::fqdn}/03clean", + 'puppet:///modules/site_apt/03clean', + 'puppet:///modules/apt/03clean' ] + } + } + + case $custom_preferences { + false: { + include apt::preferences::absent + } + default: { + # When squeeze becomes the stable branch, transform this file's header + # into a preferences.d file + include apt::preferences + } + } + + include apt::dot_d_directories + + ## This package should really always be current + package { 'debian-archive-keyring': ensure => latest } + + # backports uses the normal archive key now + package { 'debian-backports-keyring': ensure => absent } + + if ($use_backports and !($::debian_release in ['testing', 'unstable', 'experimental'])) { + apt::sources_list { + 'backports': + content => "deb $backports_url ${::debian_codename}-backports ${apt::real_repos}", + } + if $include_src { + apt::sources_list { + 'backports-src': + content => "deb-src $backports_url ${::debian_codename}-backports ${apt::real_repos}", + } + } + } + + include common::moduledir + common::module_dir { 'apt': } + $apt_base_dir = "${common::moduledir::module_dir_path}/apt" + + if $custom_key_dir { + file { "${apt_base_dir}/keys.d": + source => $custom_key_dir, + recurse => true, + owner => root, + group => root, + mode => '0755', + } + exec { 'custom_keys': + command => "find ${apt_base_dir}/keys.d -type f -exec apt-key add '{}' \\;", + subscribe => File["${apt_base_dir}/keys.d"], + refreshonly => true, + notify => Exec[refresh_apt] + } + if $custom_preferences != false { + Exec['custom_keys'] { + before => File['apt_config'] + } + } + } + + # workaround for preseeded_package component + file { [ '/var/cache', '/var/cache/local', '/var/cache/local/preseeding' ]: ensure => directory } + + exec { 'update_apt': + command => '/usr/bin/apt-get update', + require => [ + File['/etc/apt/apt.conf.d', '/etc/apt/preferences' ], + File['/etc/apt/sources.list'] ], + refreshonly => true, + # Another Semaphor for all packages to reference + alias => [ 'apt_updated', 'refresh_apt'] + } + +} diff --git a/puppet/modules/apt/manifests/key.pp b/puppet/modules/apt/manifests/key.pp new file mode 100644 index 00000000..cb70ec6a --- /dev/null +++ b/puppet/modules/apt/manifests/key.pp @@ -0,0 +1,13 @@ +define apt::key ($source, $ensure = 'present') { + validate_re( + $name, '\.gpg$', + 'An apt::key resource name must have the .gpg extension', + ) + + file { + "/etc/apt/trusted.gpg.d/${name}": + ensure => $ensure, + source => $source, + notify => Exec['apt_updated'], + } +} diff --git a/puppet/modules/apt/manifests/key/plain.pp b/puppet/modules/apt/manifests/key/plain.pp new file mode 100644 index 00000000..dff8b51b --- /dev/null +++ b/puppet/modules/apt/manifests/key/plain.pp @@ -0,0 +1,13 @@ +define apt::key::plain ($source) { + file { + "${apt::apt_base_dir}/keys/${name}": + source => $source; + "${apt::apt_base_dir}/keys": + ensure => directory; + } + exec { "apt-key add '${apt::apt_base_dir}/keys/${name}'": + subscribe => File["${apt::apt_base_dir}/keys/${name}"], + refreshonly => true, + notify => Exec['apt_updated'], + } +} diff --git a/puppet/modules/apt/manifests/listchanges.pp b/puppet/modules/apt/manifests/listchanges.pp new file mode 100644 index 00000000..e64bb1b7 --- /dev/null +++ b/puppet/modules/apt/manifests/listchanges.pp @@ -0,0 +1,19 @@ +class apt::listchanges( + $ensure_version = 'installed', + $config = "apt/${::operatingsystem}/listchanges_${::debian_codename}.erb", + $frontend = 'mail', + $email = 'root', + $confirm = '0', + $saveseen = '/var/lib/apt/listchanges.db', + $which = 'both' +){ + package { 'apt-listchanges': ensure => $ensure_version } + + file { '/etc/apt/listchanges.conf': + content => template($apt::listchanges::config), + owner => root, + group => root, + mode => '0644', + require => Package['apt-listchanges']; + } +} diff --git a/puppet/modules/apt/manifests/params.pp b/puppet/modules/apt/manifests/params.pp new file mode 100644 index 00000000..28af06eb --- /dev/null +++ b/puppet/modules/apt/manifests/params.pp @@ -0,0 +1,22 @@ +class apt::params () { + $use_lts = false + $use_volatile = false + $use_backports = true + $include_src = false + $use_next_release = false + $debian_url = 'http://httpredir.debian.org/debian/' + $security_url = 'http://security.debian.org/' + $ubuntu_url = 'http://archive.ubuntu.com/ubuntu' + $backports_url = $::debian_codename ? { + 'squeeze' => 'http://backports.debian.org/debian-backports/', + default => $::operatingsystem ? { + 'Ubuntu' => $ubuntu_url, + default => $debian_url, + } + } + $lts_url = $debian_url + $volatile_url = 'http://volatile.debian.org/debian-volatile/' + $repos = 'auto' + $custom_preferences = '' + $custom_key_dir = false +} diff --git a/puppet/modules/apt/manifests/preferences.pp b/puppet/modules/apt/manifests/preferences.pp new file mode 100644 index 00000000..6982ca05 --- /dev/null +++ b/puppet/modules/apt/manifests/preferences.pp @@ -0,0 +1,20 @@ +class apt::preferences { + + $pref_contents = $apt::custom_preferences ? { + '' => $::operatingsystem ? { + 'debian' => template("apt/${::operatingsystem}/preferences_${::debian_codename}.erb"), + 'ubuntu' => template("apt/${::operatingsystem}/preferences_${::ubuntu_codename}.erb"), + }, + default => $apt::custom_preferences + } + + file { '/etc/apt/preferences': + ensure => present, + alias => 'apt_config', + # only update together + content => $pref_contents, + require => File['/etc/apt/sources.list'], + owner => root, group => 0, mode => '0644'; + } + +} diff --git a/puppet/modules/apt/manifests/preferences/absent.pp b/puppet/modules/apt/manifests/preferences/absent.pp new file mode 100644 index 00000000..f32e0307 --- /dev/null +++ b/puppet/modules/apt/manifests/preferences/absent.pp @@ -0,0 +1,7 @@ +class apt::preferences::absent { + + file { '/etc/apt/preferences': + ensure => absent, + alias => 'apt_config', + } +} diff --git a/puppet/modules/apt/manifests/preferences_snippet.pp b/puppet/modules/apt/manifests/preferences_snippet.pp new file mode 100644 index 00000000..b7dba0d8 --- /dev/null +++ b/puppet/modules/apt/manifests/preferences_snippet.pp @@ -0,0 +1,59 @@ +define apt::preferences_snippet ( + $priority = undef, + $package = false, + $ensure = 'present', + $source = '', + $release = '', + $pin = '' +) { + + $real_package = $package ? { + false => $name, + default => $package, + } + + if $ensure == 'present' { + if $apt::custom_preferences == false { + fail('Trying to define a preferences_snippet with $custom_preferences set to false.') + } + + if $priority == undef { + fail('apt::preferences_snippet requires the \'priority\' argument to be set') + } + + if !$pin and !$release { + fail('apt::preferences_snippet requires one of the \'pin\' or \'release\' argument to be set') + } + if $pin and $release { + fail('apt::preferences_snippet requires either a \'pin\' or \'release\' argument, not both') + } + } + + file { "/etc/apt/preferences.d/${name}": + ensure => $ensure, + owner => root, group => 0, mode => '0644', + before => Exec['apt_updated']; + } + + case $source { + '': { + case $release { + '': { + File["/etc/apt/preferences.d/${name}"]{ + content => template('apt/preferences_snippet.erb') + } + } + default: { + File["/etc/apt/preferences.d/${name}"]{ + content => template('apt/preferences_snippet_release.erb') + } + } + } + } + default: { + File["/etc/apt/preferences.d/${name}"]{ + source => $source + } + } + } +} diff --git a/puppet/modules/apt/manifests/preseeded_package.pp b/puppet/modules/apt/manifests/preseeded_package.pp new file mode 100644 index 00000000..3ef06879 --- /dev/null +++ b/puppet/modules/apt/manifests/preseeded_package.pp @@ -0,0 +1,21 @@ +define apt::preseeded_package ( + $ensure = 'installed', + $content = '' +) { + $seedfile = "/var/cache/local/preseeding/${name}.seeds" + $real_content = $content ? { + '' => template ( "site_apt/${::debian_codename}/${name}.seeds" ), + default => $content + } + + file { $seedfile: + content => $real_content, + mode => '0600', owner => root, group => root, + } + + package { $name: + ensure => $ensure, + responsefile => $seedfile, + require => File[$seedfile], + } +} diff --git a/puppet/modules/apt/manifests/proxy_client.pp b/puppet/modules/apt/manifests/proxy_client.pp new file mode 100644 index 00000000..9ba79f23 --- /dev/null +++ b/puppet/modules/apt/manifests/proxy_client.pp @@ -0,0 +1,9 @@ +class apt::proxy_client( + $proxy = 'http://localhost', + $port = '3142', +){ + + apt_conf { '20proxy': + content => template('apt/20proxy.erb'), + } +} diff --git a/puppet/modules/apt/manifests/reboot_required_notify.pp b/puppet/modules/apt/manifests/reboot_required_notify.pp new file mode 100644 index 00000000..722e8a5e --- /dev/null +++ b/puppet/modules/apt/manifests/reboot_required_notify.pp @@ -0,0 +1,21 @@ +class apt::reboot_required_notify { + + # This package installs the script that created /var/run/reboot-required*. + # This script (/usr/share/update-notifier/notify-reboot-required) is + # triggered e.g. by kernel packages. + package { 'update-notifier-common': + ensure => installed, + } + + # cron-apt defaults to run every night at 4 o'clock + # plus some random time <1h. + # so we check if a reboot is required a bit later. + cron { 'apt_reboot_required_notify': + command => 'if [ -f /var/run/reboot-required ]; then echo "Reboot required\n" ; cat /var/run/reboot-required.pkgs ; fi', + user => root, + hour => 5, + minute => 20, + require => Package['update-notifier-common'], + } + +} diff --git a/puppet/modules/apt/manifests/sources_list.pp b/puppet/modules/apt/manifests/sources_list.pp new file mode 100644 index 00000000..0ee068d1 --- /dev/null +++ b/puppet/modules/apt/manifests/sources_list.pp @@ -0,0 +1,40 @@ +define apt::sources_list ( + $ensure = 'present', + $source = '', + $content = undef +) { + + if $ensure == 'present' { + if $source == '' and $content == undef { + fail("One of \$source or \$content must be specified for apt_sources_snippet ${name}") + } + if $source != '' and $content != undef { + fail("Only one of \$source or \$content must specified for apt_sources_snippet ${name}") + } + } + + include apt::dot_d_directories + + $realname = regsubst($name, '\.list$', '') + + # One would expect the 'file' resource on sources.list.d to trigger an + # apt-get update when files are added or modified in the directory, but it + # apparently doesn't. + file { "/etc/apt/sources.list.d/${realname}.list": + ensure => $ensure, + owner => root, group => 0, mode => '0644', + notify => Exec['apt_updated'], + } + + if $source { + File["/etc/apt/sources.list.d/${realname}.list"] { + source => $source, + } + } + else { + File["/etc/apt/sources.list.d/${realname}.list"] { + content => $content, + } + } +} + diff --git a/puppet/modules/apt/manifests/unattended_upgrades.pp b/puppet/modules/apt/manifests/unattended_upgrades.pp new file mode 100644 index 00000000..52d75425 --- /dev/null +++ b/puppet/modules/apt/manifests/unattended_upgrades.pp @@ -0,0 +1,34 @@ +class apt::unattended_upgrades ( + $config_content = undef, + $config_template = 'apt/50unattended-upgrades.erb', + $mailonlyonerror = true, + $mail_recipient = 'root', + $blacklisted_packages = [], + $ensure_version = present +) { + + package { 'unattended-upgrades': + ensure => $ensure_version + } + + # For some reason, this directory is sometimes absent, which causes + # unattended-upgrades to crash. + file { '/var/log/unattended-upgrades': + ensure => directory, + owner => 'root', + group => 0, + mode => '0755', + require => Package['unattended-upgrades'], + } + + $file_content = $config_content ? { + undef => template($config_template), + default => $config_content + } + + apt_conf { '50unattended-upgrades': + content => $file_content, + require => Package['unattended-upgrades'], + refresh_apt => false + } +} diff --git a/puppet/modules/apt/manifests/update.pp b/puppet/modules/apt/manifests/update.pp new file mode 100644 index 00000000..dde83200 --- /dev/null +++ b/puppet/modules/apt/manifests/update.pp @@ -0,0 +1,7 @@ +class apt::update inherits ::apt { + + Exec['update_apt'] { + refreshonly => false + } + +} diff --git a/puppet/modules/apt/manifests/upgrade_package.pp b/puppet/modules/apt/manifests/upgrade_package.pp new file mode 100644 index 00000000..30572c96 --- /dev/null +++ b/puppet/modules/apt/manifests/upgrade_package.pp @@ -0,0 +1,31 @@ +define apt::upgrade_package ( + $version = '' +) { + + $version_suffix = $version ? { + '' => '', + 'latest' => '', + default => "=${version}", + } + + if !defined(Package['apt-show-versions']) { + package { 'apt-show-versions': + ensure => installed, + require => undef, + } + } + + if !defined(Package['dctrl-tools']) { + package { 'dctrl-tools': + ensure => installed, + require => undef, + } + } + + exec { "apt-get -q -y -o 'DPkg::Options::=--force-confold' install ${name}${version_suffix}": + onlyif => [ "grep-status -F Status installed -a -P $name -q", "apt-show-versions -u $name | grep -q upgradeable" ], + require => Package['apt-show-versions', 'dctrl-tools'], + before => Exec['apt_updated'] + } + +} diff --git a/puppet/modules/apt/spec/spec_helper.rb b/puppet/modules/apt/spec/spec_helper.rb new file mode 100644 index 00000000..21d1a988 --- /dev/null +++ b/puppet/modules/apt/spec/spec_helper.rb @@ -0,0 +1,12 @@ +# https://puppetlabs.com/blog/testing-modules-in-the-puppet-forge +require 'rspec-puppet' +require 'mocha/api' + +RSpec.configure do |c| + + c.module_path = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')) + c.color = true + + #Puppet.features.stubs(:root? => true) + +end diff --git a/puppet/modules/apt/spec/unit/custom_facts_spec.rb b/puppet/modules/apt/spec/unit/custom_facts_spec.rb new file mode 100644 index 00000000..9a28d92e --- /dev/null +++ b/puppet/modules/apt/spec/unit/custom_facts_spec.rb @@ -0,0 +1,86 @@ +require "spec_helper" + +describe "Facter::Util::Fact" do + before { + Facter.clear + } + + describe 'custom facts' do + + context 'Debian 7' do + before do + Facter.fact(:operatingsystem).stubs(:value).returns("Debian") + Facter.fact(:operatingsystemrelease).stubs(:value).returns("7.8") + Facter.fact(:lsbdistcodename).stubs(:value).returns("wheezy") + end + + it "debian_release = oldstable" do + expect(Facter.fact(:debian_release).value).to eq('oldstable') + end + + it "debian_codename = wheezy" do + expect(Facter.fact(:debian_codename).value).to eq('wheezy') + end + + it "debian_nextcodename = jessie" do + expect(Facter.fact(:debian_nextcodename).value).to eq('jessie') + end + + it "debian_nextrelease = stable" do + expect(Facter.fact(:debian_nextrelease).value).to eq('stable') + end + end + + context 'Debian 8' do + before do + Facter.fact(:operatingsystem).stubs(:value).returns("Debian") + Facter.fact(:operatingsystemrelease).stubs(:value).returns("8.0") + Facter.fact(:lsbdistcodename).stubs(:value).returns("jessie") + end + + it "debian_release = stable" do + expect(Facter.fact(:debian_release).value).to eq('stable') + end + + it "debian_codename = jessie" do + expect(Facter.fact(:debian_codename).value).to eq('jessie') + end + + it "debian_nextcodename = stretch" do + expect(Facter.fact(:debian_nextcodename).value).to eq('stretch') + end + + it "debian_nextrelease = testing" do + expect(Facter.fact(:debian_nextrelease).value).to eq('testing') + end + end + + context 'Ubuntu 15.10' do + before do + Facter.fact(:operatingsystem).stubs(:value).returns("Ubuntu") + Facter.fact(:operatingsystemrelease).stubs(:value).returns("15.10") + Facter.fact(:lsbdistcodename).stubs(:value).returns("wily") + end + + it "ubuntu_codename = wily" do + expect(Facter.fact(:ubuntu_codename).value).to eq('wily') + end + + it "ubuntu_nextcodename = xenial" do + expect(Facter.fact(:ubuntu_nextcodename).value).to eq('xenial') + end + end + end + + describe "Test 'apt_running' fact" do + it "should return true when apt-get is running" do + Facter::Util::Resolution.stubs(:exec).with("pgrep apt-get >/dev/null 2>&1 && echo true || echo false").returns("true") + expect(Facter.fact(:apt_running).value).to eq('true') + end + it "should return false when apt-get is not running" do + Facter::Util::Resolution.stubs(:exec).with("pgrep apt-get >/dev/null 2>&1 && echo true || echo false").returns("false") + expect(Facter.fact(:apt_running).value).to eq('false') + end + end + +end diff --git a/puppet/modules/apt/templates/20proxy.erb b/puppet/modules/apt/templates/20proxy.erb new file mode 100644 index 00000000..520e7b1b --- /dev/null +++ b/puppet/modules/apt/templates/20proxy.erb @@ -0,0 +1,5 @@ +// This file is managed by Puppet +// all local modifications will be overwritten + +Acquire::http { Proxy "<%= @proxy %>:<%= @port %>"; }; +Acquire::HTTP::Proxy::bugs.debian.org "DIRECT"; diff --git a/puppet/modules/apt/templates/50unattended-upgrades.erb b/puppet/modules/apt/templates/50unattended-upgrades.erb new file mode 100644 index 00000000..7c65d102 --- /dev/null +++ b/puppet/modules/apt/templates/50unattended-upgrades.erb @@ -0,0 +1,38 @@ +// this file is managed by puppet ! + +<% if scope.lookupvar('::operatingsystem') == 'Ubuntu' -%> +Unattended-Upgrade::Allowed-Origins { + "${distro_id}:${distro_codename}-security"; + "${distro_id}:${distro_codename}-updates"; + "${distro_id}:${distro_codename}-backports"; +<% elsif scope.lookupvar('::operatingsystem') == 'Debian' and scope.lookupvar('::debian_codename') == 'squeeze' -%> +Unattended-Upgrade::Allowed-Origins { + "${distro_id}:<%= scope.lookupvar('::debian_release') %>"; + "${distro_id}:squeeze-lts"; +<% elsif scope.lookupvar('::operatingsystem') == 'Debian' and scope.lookupvar('::debian_codename') == 'wheezy' -%> +Unattended-Upgrade::Origins-Pattern { + "origin=Debian,archive=<%= scope.lookupvar('::debian_release') %>,label=Debian-Security"; + "origin=Debian,archive=${distro_codename}-lts"; +<% else -%> +Unattended-Upgrade::Origins-Pattern { + "origin=Debian,codename=${distro_codename},label=Debian"; + "origin=Debian,codename=${distro_codename},label=Debian-Security"; +<% end -%> +}; + +<% if not @blacklisted_packages.empty? -%> +Unattended-Upgrade::Package-Blacklist { +<% @blacklisted_packages.each do |pkg| -%> + "<%= pkg %>"; +<% end -%> +}; +<% end -%> + +APT::Periodic::Update-Package-Lists "1"; +APT::Periodic::Download-Upgradeable-Packages "1"; +APT::Periodic::Unattended-Upgrade "1"; + +Unattended-Upgrade::Mail "<%= @mail_recipient -%>"; +<% if @mailonlyonerror -%> +Unattended-Upgrade::MailOnlyOnError "true"; +<% end -%> diff --git a/puppet/modules/apt/templates/Debian/apticron_jessie.erb b/puppet/modules/apt/templates/Debian/apticron_jessie.erb new file mode 120000 index 00000000..a9a3a6fd --- /dev/null +++ b/puppet/modules/apt/templates/Debian/apticron_jessie.erb @@ -0,0 +1 @@ +apticron_wheezy.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Debian/apticron_lenny.erb b/puppet/modules/apt/templates/Debian/apticron_lenny.erb new file mode 100644 index 00000000..86b09977 --- /dev/null +++ b/puppet/modules/apt/templates/Debian/apticron_lenny.erb @@ -0,0 +1,50 @@ +# apticron.conf +# +# set EMAIL to a list of addresses which will be notified of impending updates +# +EMAIL="<%= scope.lookupvar('apt::apticron::email') %>" + +# +# Set DIFF_ONLY to "1" to only output the difference of the current run +# compared to the last run (ie. only new upgrades since the last run). If there +# are no differences, no output/email will be generated. By default, apticron +# will output everything that needs to be upgraded. +# +DIFF_ONLY="<%= scope.lookupvar('apt::apticron::diff_only') %>" + +# +# Set LISTCHANGES_PROFILE if you would like apticron to invoke apt-listchanges +# with the --profile option. You should add a corresponding profile to +# /etc/apt/listchanges.conf +# +LISTCHANGES_PROFILE="<%= scope.lookupvar('apt::apticron::listchanges_profile') %>" + +# +# Set SYSTEM if you would like apticron to use something other than the output +# of "hostname -f" for the system name in the mails it generates +# +# SYSTEM="foobar.example.com" +<% unless (v=scope.lookupvar('apt::apticron::system')).to_s == "false" -%> +SYSTEM="<%= v %>" +<% end -%> + +# +# Set IPADDRESSNUM if you would like to configure the maximal number of IP +# addresses apticron displays. The default is to display 1 address of each +# family type (inet, inet6), if available. +# +# IPADDRESSNUM="1" +<% unless (v=scope.lookupvar('apt::apticron::ipaddressnum')).to_s == "false" -%> +IPADDRESSNUM="<%= v %>" +<% end -%> + +# +# Set IPADDRESSES to a whitespace seperated list of reachable addresses for +# this system. By default, apticron will try to work these out using the +# "ip" command +# +# IPADDRESSES="192.0.2.1 2001:db8:1:2:3::1" +<% unless (v=scope.lookupvar('apt::apticron::ipaddresses')).to_s == "false" -%> +IPADDRESSES="<%= v %>" +<% end -%> + diff --git a/puppet/modules/apt/templates/Debian/apticron_sid.erb b/puppet/modules/apt/templates/Debian/apticron_sid.erb new file mode 120000 index 00000000..a9a3a6fd --- /dev/null +++ b/puppet/modules/apt/templates/Debian/apticron_sid.erb @@ -0,0 +1 @@ +apticron_wheezy.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Debian/apticron_squeeze.erb b/puppet/modules/apt/templates/Debian/apticron_squeeze.erb new file mode 100644 index 00000000..05b7c9b8 --- /dev/null +++ b/puppet/modules/apt/templates/Debian/apticron_squeeze.erb @@ -0,0 +1,82 @@ +# apticron.conf +# +# set EMAIL to a space separated list of addresses which will be notified of +# impending updates +# +EMAIL="<%= scope.lookupvar('apt::apticron::email') %>" + + +# +# Set DIFF_ONLY to "1" to only output the difference of the current run +# compared to the last run (ie. only new upgrades since the last run). If there +# are no differences, no output/email will be generated. By default, apticron +# will output everything that needs to be upgraded. +# +DIFF_ONLY="<%= scope.lookupvar('apt::apticron::diff_only') %>" + +# +# Set LISTCHANGES_PROFILE if you would like apticron to invoke apt-listchanges +# with the --profile option. You should add a corresponding profile to +# /etc/apt/listchanges.conf +# +LISTCHANGES_PROFILE="<%= scope.lookupvar('apt::apticron::listchanges_profile') %>" + +# +# Set SYSTEM if you would like apticron to use something other than the output +# of "hostname -f" for the system name in the mails it generates +# +# SYSTEM="foobar.example.com" +<% unless (v=scope.lookupvar('apt::apticron::system')).to_s == "false" -%> +SYSTEM="<%= v %>" +<% end -%> + + +# +# Set IPADDRESSNUM if you would like to configure the maximal number of IP +# addresses apticron displays. The default is to display 1 address of each +# family type (inet, inet6), if available. +# +# IPADDRESSNUM="1" +<% unless (v=scope.lookupvar('apt::apticron::ipaddressnum')).to_s == "false" -%> +IPADDRESSNUM="<%= v %>" +<% end -%> + + +# +# Set IPADDRESSES to a whitespace separated list of reachable addresses for +# this system. By default, apticron will try to work these out using the +# "ip" command +# +# IPADDRESSES="192.0.2.1 2001:db8:1:2:3::1" +<% unless (v=scope.lookupvar('apt::apticron::ipaddresses')).to_s == "false" -%> +IPADDRESSES="<%= v %>" +<% end -%> + + +# +# Set NOTIFY_HOLDS="0" if you don't want to be notified about new versions of +# packages on hold in your system. The default behavior is downloading and +# listing them as any other package. +# +# NOTIFY_HOLDS="0" +NOTIFY_HOLDS="<%= scope.lookupvar('apt::apticron::notifyholds') %>" + +# +# Set NOTIFY_NEW="0" if you don't want to be notified about packages which +# are not installed in your system. Yes, it's possible! There are some issues +# related to systems which have mixed stable/unstable sources. In these cases +# apt-get will consider for example that packages with "Priority: +# required"/"Essential: yes" in unstable but not in stable should be installed, +# so they will be listed in dist-upgrade output. Please take a look at +# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=531002#44 +# +# NOTIFY_NEW="0" +NOTIFY_NEW="<%= scope.lookupvar('apt::apticron::notifynew') %>" + +# +# Set CUSTOM_SUBJECT if you want to replace the default subject used in +# the notification e-mails. This may help filtering/sorting client-side e-mail. +# +# CUSTOM_SUBJECT="" +CUSTOM_SUBJECT="<%= scope.lookupvar('apt::apticron::customsubject') %>" + diff --git a/puppet/modules/apt/templates/Debian/apticron_wheezy.erb b/puppet/modules/apt/templates/Debian/apticron_wheezy.erb new file mode 100644 index 00000000..655854e6 --- /dev/null +++ b/puppet/modules/apt/templates/Debian/apticron_wheezy.erb @@ -0,0 +1,80 @@ +# apticron.conf +# +# set EMAIL to a space separated list of addresses which will be notified of +# impending updates +# +EMAIL="<%= scope.lookupvar('apt::apticron::email') %>" + +# +# Set DIFF_ONLY to "1" to only output the difference of the current run +# compared to the last run (ie. only new upgrades since the last run). If there +# are no differences, no output/email will be generated. By default, apticron +# will output everything that needs to be upgraded. +# +DIFF_ONLY="<%= scope.lookupvar('apt::apticron::diff_only') %>" + +# +# Set LISTCHANGES_PROFILE if you would like apticron to invoke apt-listchanges +# with the --profile option. You should add a corresponding profile to +# /etc/apt/listchanges.conf +# +LISTCHANGES_PROFILE="<%= scope.lookupvar('apt::apticron::listchanges_profile') %>" + +# +# Set SYSTEM if you would like apticron to use something other than the output +# of "hostname -f" for the system name in the mails it generates +# +# SYSTEM="foobar.example.com" +<% unless (v=scope.lookupvar('apt::apticron::system')).to_s == "false" -%> +SYSTEM="<%= v %>" +<% end -%> + +# +# Set IPADDRESSNUM if you would like to configure the maximal number of IP +# addresses apticron displays. The default is to display 1 address of each +# family type (inet, inet6), if available. +# +# IPADDRESSNUM="1" +<% unless (v=scope.lookupvar('apt::apticron::ipaddressnum')).to_s == "false" -%> +IPADDRESSNUM="<%= v %>" +<% end -%> + +# +# Set IPADDRESSES to a whitespace separated list of reachable addresses for +# this system. By default, apticron will try to work these out using the +# "ip" command +# +# IPADDRESSES="192.0.2.1 2001:db8:1:2:3::1" +<% unless (v=scope.lookupvar('apt::apticron::ipaddresses')).to_s == "false" -%> +IPADDRESSES=<%= v %>" +<% end -%> + +# +# Set NOTIFY_HOLDS="0" if you don't want to be notified about new versions of +# packages on hold in your system. The default behavior is downloading and +# listing them as any other package. +# +# NOTIFY_HOLDS="0" +NOTIFY_HOLDS="<%= scope.lookupvar('apt::apticron::notifyholds') %>" + +# +# Set NOTIFY_NEW="0" if you don't want to be notified about packages which +# are not installed in your system. Yes, it's possible! There are some issues +# related to systems which have mixed stable/unstable sources. In these cases +# apt-get will consider for example that packages with "Priority: +# required"/"Essential: yes" in unstable but not in stable should be installed, +# so they will be listed in dist-upgrade output. Please take a look at +# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=531002#44 +# +# NOTIFY_NEW="0" +NOTIFY_NEW="<%= scope.lookupvar('apt::apticron::notifynew') %>" + + +# +# Set CUSTOM_SUBJECT if you want to replace the default subject used in +# the notification e-mails. This may help filtering/sorting client-side e-mail. +# If you want to use internal vars please use single quotes here. Ex: +# ='[apticron] : package update(s)' +# +# CUSTOM_SUBJECT="" +CUSTOM_SUBJECT="<%= scope.lookupvar('apt::apticron::customsubject') %>" diff --git a/puppet/modules/apt/templates/Debian/listchanges_jessie.erb b/puppet/modules/apt/templates/Debian/listchanges_jessie.erb new file mode 120000 index 00000000..74ab496d --- /dev/null +++ b/puppet/modules/apt/templates/Debian/listchanges_jessie.erb @@ -0,0 +1 @@ +listchanges_lenny.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Debian/listchanges_lenny.erb b/puppet/modules/apt/templates/Debian/listchanges_lenny.erb new file mode 100644 index 00000000..1025dd0e --- /dev/null +++ b/puppet/modules/apt/templates/Debian/listchanges_lenny.erb @@ -0,0 +1,7 @@ +[apt] +frontend=<%= scope.lookupvar('apt::listchanges::frontend') %> +email_address=<%= scope.lookupvar('apt::listchanges::email') %> +confirm=<%= scope.lookupvar('apt::listchanges::confirm') %> +save_seen=<%= scope.lookupvar('apt::listchanges::saveseen') %> +which=<%= scope.lookupvar('apt::listchanges::which') %> + diff --git a/puppet/modules/apt/templates/Debian/listchanges_sid.erb b/puppet/modules/apt/templates/Debian/listchanges_sid.erb new file mode 120000 index 00000000..74ab496d --- /dev/null +++ b/puppet/modules/apt/templates/Debian/listchanges_sid.erb @@ -0,0 +1 @@ +listchanges_lenny.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Debian/listchanges_squeeze.erb b/puppet/modules/apt/templates/Debian/listchanges_squeeze.erb new file mode 120000 index 00000000..74ab496d --- /dev/null +++ b/puppet/modules/apt/templates/Debian/listchanges_squeeze.erb @@ -0,0 +1 @@ +listchanges_lenny.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Debian/listchanges_wheezy.erb b/puppet/modules/apt/templates/Debian/listchanges_wheezy.erb new file mode 120000 index 00000000..74ab496d --- /dev/null +++ b/puppet/modules/apt/templates/Debian/listchanges_wheezy.erb @@ -0,0 +1 @@ +listchanges_lenny.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Debian/preferences_jessie.erb b/puppet/modules/apt/templates/Debian/preferences_jessie.erb new file mode 100644 index 00000000..0888abe5 --- /dev/null +++ b/puppet/modules/apt/templates/Debian/preferences_jessie.erb @@ -0,0 +1,14 @@ +Explanation: Debian <%= codename=scope.lookupvar('::debian_codename') %> +Package: * +Pin: release o=Debian,n=<%= codename %> +Pin-Priority: 990 + +Explanation: Debian sid +Package: * +Pin: release o=Debian,n=sid +Pin-Priority: 1 + +Explanation: Debian fallback +Package: * +Pin: release o=Debian +Pin-Priority: -10 diff --git a/puppet/modules/apt/templates/Debian/preferences_lenny.erb b/puppet/modules/apt/templates/Debian/preferences_lenny.erb new file mode 100644 index 00000000..65001687 --- /dev/null +++ b/puppet/modules/apt/templates/Debian/preferences_lenny.erb @@ -0,0 +1,25 @@ +Explanation: Debian <%= codename=scope.lookupvar('::debian_codename') %> +Package: * +Pin: release o=Debian,a=<%= scope.lookupvar('::debian_release') %>,v=5* +Pin-Priority: 990 + +Explanation: Debian backports +Package: * +Pin: origin backports.debian.org +Pin-Priority: 200 + +Explanation: Debian <%= next_release=scope.lookupvar('::debian_nextrelease') %> +Package: * +Pin: release o=Debian,a=<%= next_release %> +Pin-Priority: 2 + +Explanation: Debian sid +Package: * +Pin: release o=Debian,a=unstable +Pin-Priority: 1 + +Explanation: Debian fallback +Package: * +Pin: release o=Debian +Pin-Priority: -10 + diff --git a/puppet/modules/apt/templates/Debian/preferences_sid.erb b/puppet/modules/apt/templates/Debian/preferences_sid.erb new file mode 100644 index 00000000..eb185543 --- /dev/null +++ b/puppet/modules/apt/templates/Debian/preferences_sid.erb @@ -0,0 +1,10 @@ +Explanation: Debian sid +Package: * +Pin: release o=Debian,n=sid +Pin-Priority: 990 + +Explanation: Debian fallback +Package: * +Pin: release o=Debian +Pin-Priority: -10 + diff --git a/puppet/modules/apt/templates/Debian/preferences_squeeze.erb b/puppet/modules/apt/templates/Debian/preferences_squeeze.erb new file mode 100644 index 00000000..885edc73 --- /dev/null +++ b/puppet/modules/apt/templates/Debian/preferences_squeeze.erb @@ -0,0 +1,30 @@ +Explanation: Debian <%= codename=scope.lookupvar('::debian_codename') %> +Package: * +Pin: release o=Debian,n=<%= codename %> +Pin-Priority: 990 + +Explanation: Debian <%= codename %>-updates +Package: * +Pin: release o=Debian,n=<%= codename %>-updates +Pin-Priority: 990 + +Explanation: Debian <%= codename %>-lts +Package: * +Pin: release o=Debian,n=<%= codename %>-lts +Pin-Priority: 990 + +Explanation: Debian <%= next_codename=scope.lookupvar('::debian_nextcodename') %> +Package: * +Pin: release o=Debian,n=<%= next_codename %> +Pin-Priority: 2 + +Explanation: Debian sid +Package: * +Pin: release o=Debian,n=sid +Pin-Priority: 1 + +Explanation: Debian fallback +Package: * +Pin: release o=Debian +Pin-Priority: -10 + diff --git a/puppet/modules/apt/templates/Debian/preferences_wheezy.erb b/puppet/modules/apt/templates/Debian/preferences_wheezy.erb new file mode 100644 index 00000000..106108d5 --- /dev/null +++ b/puppet/modules/apt/templates/Debian/preferences_wheezy.erb @@ -0,0 +1,20 @@ +Explanation: Debian <%= codename=scope.lookupvar('::debian_codename') %> +Package: * +Pin: release o=Debian,n=<%= codename %> +Pin-Priority: 990 + +Explanation: Debian <%= codename %>-updates +Package: * +Pin: release o=Debian,n=<%= codename %>-updates +Pin-Priority: 990 + +Explanation: Debian sid +Package: * +Pin: release o=Debian,n=sid +Pin-Priority: 1 + +Explanation: Debian fallback +Package: * +Pin: release o=Debian +Pin-Priority: -10 + diff --git a/puppet/modules/apt/templates/Debian/sources.list.erb b/puppet/modules/apt/templates/Debian/sources.list.erb new file mode 100644 index 00000000..44eea538 --- /dev/null +++ b/puppet/modules/apt/templates/Debian/sources.list.erb @@ -0,0 +1,76 @@ +# This file is managed by puppet +# all local modifications will be overwritten + +### Debian current: <%= codename=scope.lookupvar('::debian_codename') %> + +# basic +deb <%= debian_url=scope.lookupvar('apt::debian_url') %> <%= codename %> <%= lrepos=scope.lookupvar('apt::real_repos') %> +<% if include_src=scope.lookupvar('apt::include_src') -%> +deb-src <%= debian_url %> <%= codename %> <%= lrepos %> +<% end -%> + +# security +<% if ((release=scope.lookupvar('::debian_release')) == "stable" || release == "oldstable") -%> +deb <%= security_url=scope.lookupvar('apt::security_url') %> <%= codename %>/updates <%= lrepos %> +<% if include_src -%> +deb-src <%= security_url %> <%= codename %>/updates <%= lrepos %> +<% end -%> +<% else -%> +# There is no security support for <%= release %> +<% end -%> + +<% if use_volatile=scope.lookupvar('apt::use_volatile') -%> +# volatile +<% if (release == "testing" || release == "unstable" || release == "experimental") -%> +# There is no volatile archive for <%= release %> +<% else -%> +deb <%= debian_url %> <%= codename %>-updates <%= lrepos %> +<% if include_src -%> +deb-src <%= debian_url %> <%= codename %>-updates <%= lrepos %> +<% end + end + end -%> + +<% if use_lts=scope.lookupvar('apt::use_lts') -%> +# LTS +<% if release_lts=scope.lookupvar('::debian_lts') == "false" -%> +# There is no LTS archive for <%= release %> +<% else -%> +deb <%= debian_url %> <%= codename %>-lts <%= lrepos %> +<% if include_src -%> +deb-src <%= debian_url %> <%= codename %>-lts <%= lrepos %> +<% end -%> +<% end -%> +<% end -%> + +<% if next_release=scope.lookupvar('apt::use_next_release') -%> +### Debian next: <%= next_release=scope.lookupvar('::debian_nextrelease') ; next_codename=scope.lookupvar('::debian_nextcodename') %> + +# basic +deb <%= debian_url %> <%= next_codename %> <%= lrepos %> +<% if include_src -%> +deb-src <%= debian_url %> <%= next_codename %> <%= lrepos %> +<% end -%> + +# security +<% if (next_release == "unstable" || next_release == "experimental") -%> +# There is no security support for <%= next_release %> +<% else -%> +deb <%= security_url %> <%= next_codename %>/updates <%= lrepos %> +<% if include_src then -%> +deb-src <%= security_url %> <%= next_codename %>/updates <%= lrepos %> +<% end + end -%> + +<% if use_volatile -%> +# volatile +<% if (next_release == "testing" || next_release == "unstable" || next_release == "experimental") -%> +# There is no volatile archive for <%= next_release %> +<% else -%> +deb <%= debian_url %> <%= next_codename %>-updates <%= lrepos %> +<% if include_src -%> +deb-src <%= debian_url %> <%= next_codename %>-updates <%= lrepos %> +<% end + end + end + end -%> diff --git a/puppet/modules/apt/templates/Ubuntu/preferences_lucid.erb b/puppet/modules/apt/templates/Ubuntu/preferences_lucid.erb new file mode 120000 index 00000000..3debe4fc --- /dev/null +++ b/puppet/modules/apt/templates/Ubuntu/preferences_lucid.erb @@ -0,0 +1 @@ +preferences_maverick.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Ubuntu/preferences_maverick.erb b/puppet/modules/apt/templates/Ubuntu/preferences_maverick.erb new file mode 100644 index 00000000..8e5481d3 --- /dev/null +++ b/puppet/modules/apt/templates/Ubuntu/preferences_maverick.erb @@ -0,0 +1,30 @@ +Explanation: Ubuntu <%= codename=scope.lookupvar('::ubuntu_codename') %> security +Package: * +Pin: release o=Ubuntu,a=<%= codename %>-security +Pin-Priority: 990 + +Explanation: Ubuntu <%= codename %> updates +Package: * +Pin: release o=Ubuntu,a=<%= codename %>-updates +Pin-Priority: 980 + +Explanation: Ubuntu <%= codename %> +Package: * +Pin: release o=Ubuntu,a=<%= codename %> +Pin-Priority: 970 + +Explanation: Ubuntu backports +Package: * +Pin: release a=<%= codename %>-backports +Pin-Priority: 200 + +Explanation: Ubuntu <%= next_release=scope.lookupvar('::ubuntu_nextcodename') %> +Package: * +Pin: release o=Ubuntu,a=<%= next_release %> +Pin-Priority: 2 + +Explanation: Ubuntu fallback +Package: * +Pin: release o=Ubuntu +Pin-Priority: -10 + diff --git a/puppet/modules/apt/templates/Ubuntu/preferences_oneiric.erb b/puppet/modules/apt/templates/Ubuntu/preferences_oneiric.erb new file mode 120000 index 00000000..3debe4fc --- /dev/null +++ b/puppet/modules/apt/templates/Ubuntu/preferences_oneiric.erb @@ -0,0 +1 @@ +preferences_maverick.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Ubuntu/preferences_precise.erb b/puppet/modules/apt/templates/Ubuntu/preferences_precise.erb new file mode 120000 index 00000000..3debe4fc --- /dev/null +++ b/puppet/modules/apt/templates/Ubuntu/preferences_precise.erb @@ -0,0 +1 @@ +preferences_maverick.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Ubuntu/preferences_utopic.erb b/puppet/modules/apt/templates/Ubuntu/preferences_utopic.erb new file mode 120000 index 00000000..3debe4fc --- /dev/null +++ b/puppet/modules/apt/templates/Ubuntu/preferences_utopic.erb @@ -0,0 +1 @@ +preferences_maverick.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Ubuntu/preferences_vivid.erb b/puppet/modules/apt/templates/Ubuntu/preferences_vivid.erb new file mode 120000 index 00000000..3debe4fc --- /dev/null +++ b/puppet/modules/apt/templates/Ubuntu/preferences_vivid.erb @@ -0,0 +1 @@ +preferences_maverick.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Ubuntu/preferences_wily.erb b/puppet/modules/apt/templates/Ubuntu/preferences_wily.erb new file mode 120000 index 00000000..3debe4fc --- /dev/null +++ b/puppet/modules/apt/templates/Ubuntu/preferences_wily.erb @@ -0,0 +1 @@ +preferences_maverick.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Ubuntu/preferences_xenial.erb b/puppet/modules/apt/templates/Ubuntu/preferences_xenial.erb new file mode 120000 index 00000000..3debe4fc --- /dev/null +++ b/puppet/modules/apt/templates/Ubuntu/preferences_xenial.erb @@ -0,0 +1 @@ +preferences_maverick.erb \ No newline at end of file diff --git a/puppet/modules/apt/templates/Ubuntu/sources.list.erb b/puppet/modules/apt/templates/Ubuntu/sources.list.erb new file mode 100644 index 00000000..e6d2f643 --- /dev/null +++ b/puppet/modules/apt/templates/Ubuntu/sources.list.erb @@ -0,0 +1,22 @@ +# This file is managed by puppet +# all local modifications will be overwritten + +# basic <%= codename=scope.lookupvar('::ubuntu_codename') %> +deb <%= ubuntu_url=scope.lookupvar('apt::ubuntu_url') %> <%= codename %> <%= lrepos=scope.lookupvar('apt::real_repos') %> +<% if include_src=scope.lookupvar('apt::include_src') -%> +deb-src <%= ubuntu_url %> <%= codename %> <%= lrepos %> +<% end -%> + +<% if use_volatile=scope.lookupvar('apt::use_volatile') -%> +# updates +deb <%= ubuntu_url %> <%= codename %>-updates <%= lrepos %> +<% if include_src -%> +deb-src <%= ubuntu_url %> <%= codename %>-updates <%= lrepos %> +<% end + end -%> + +# security suppport +deb <%= ubuntu_url %> <%= codename %>-security <%= lrepos %> +<% if include_src -%> +deb-src <%= ubuntu_url %> <%= codename %>-security <%= lrepos %> +<% end -%> diff --git a/puppet/modules/apt/templates/preferences_snippet.erb b/puppet/modules/apt/templates/preferences_snippet.erb new file mode 100644 index 00000000..903e73d6 --- /dev/null +++ b/puppet/modules/apt/templates/preferences_snippet.erb @@ -0,0 +1,4 @@ +Package: <%= @real_package %> +Pin: <%= @pin %> +Pin-Priority: <%= @priority %> + diff --git a/puppet/modules/apt/templates/preferences_snippet_release.erb b/puppet/modules/apt/templates/preferences_snippet_release.erb new file mode 100644 index 00000000..b95d3f81 --- /dev/null +++ b/puppet/modules/apt/templates/preferences_snippet_release.erb @@ -0,0 +1,4 @@ +Package: <%= @real_package %> +Pin: release a=<%= @release %> +Pin-Priority: <%= @priority %> + -- cgit v1.2.3 From 5552d592f9332e55bcf2a5d2c6b0258b8130c26b Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:31 -0400 Subject: git subrepo clone https://leap.se/git/puppet_lsb puppet/modules/lsb subrepo: subdir: "puppet/modules/lsb" merged: "bac64e7" upstream: origin: "https://leap.se/git/puppet_lsb" branch: "master" commit: "bac64e7" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: Ia48799c5442c7b930952fdb822bd80d796eab321 --- puppet/modules/lsb/.gitrepo | 11 +++++++++++ puppet/modules/lsb/manifests/base.pp | 3 +++ puppet/modules/lsb/manifests/centos.pp | 5 +++++ puppet/modules/lsb/manifests/debian.pp | 6 ++++++ puppet/modules/lsb/manifests/init.pp | 6 ++++++ 5 files changed, 31 insertions(+) create mode 100644 puppet/modules/lsb/.gitrepo create mode 100644 puppet/modules/lsb/manifests/base.pp create mode 100644 puppet/modules/lsb/manifests/centos.pp create mode 100644 puppet/modules/lsb/manifests/debian.pp create mode 100644 puppet/modules/lsb/manifests/init.pp (limited to 'puppet/modules') diff --git a/puppet/modules/lsb/.gitrepo b/puppet/modules/lsb/.gitrepo new file mode 100644 index 00000000..640efc53 --- /dev/null +++ b/puppet/modules/lsb/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_lsb + branch = master + commit = bac64e7595a6d4f8d409b024a26bddb1c06188d6 + parent = 2e384e68fb867d8ba7178c4398e35653ab567538 + cmdver = 0.3.0 diff --git a/puppet/modules/lsb/manifests/base.pp b/puppet/modules/lsb/manifests/base.pp new file mode 100644 index 00000000..9dc8d5a4 --- /dev/null +++ b/puppet/modules/lsb/manifests/base.pp @@ -0,0 +1,3 @@ +class lsb::base { + package{'lsb': ensure => present } +} diff --git a/puppet/modules/lsb/manifests/centos.pp b/puppet/modules/lsb/manifests/centos.pp new file mode 100644 index 00000000..b7006187 --- /dev/null +++ b/puppet/modules/lsb/manifests/centos.pp @@ -0,0 +1,5 @@ +class lsb::centos inherits lsb::base { + Package['lsb']{ + name => 'redhat-lsb', + } +} diff --git a/puppet/modules/lsb/manifests/debian.pp b/puppet/modules/lsb/manifests/debian.pp new file mode 100644 index 00000000..c32070f3 --- /dev/null +++ b/puppet/modules/lsb/manifests/debian.pp @@ -0,0 +1,6 @@ +class lsb::debian inherits lsb::base { + Package['lsb']{ + name => 'lsb-release', + require => undef, + } +} diff --git a/puppet/modules/lsb/manifests/init.pp b/puppet/modules/lsb/manifests/init.pp new file mode 100644 index 00000000..85b34e1f --- /dev/null +++ b/puppet/modules/lsb/manifests/init.pp @@ -0,0 +1,6 @@ +class lsb { + case $::operatingsystem { + debian,ubuntu: { include lsb::debian } + centos: { include lsb::centos } + } +} -- cgit v1.2.3 From 984375bab6546a7ef1e716402468a2f4cb6e1925 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:32 -0400 Subject: git subrepo clone https://leap.se/git/puppet_ntp puppet/modules/ntp subrepo: subdir: "puppet/modules/ntp" merged: "8a554ab" upstream: origin: "https://leap.se/git/puppet_ntp" branch: "master" commit: "8a554ab" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I6132c417d321ed4f48cc3cd52d4050603fada61a --- puppet/modules/ntp/.fixtures.yml | 5 + puppet/modules/ntp/.gitignore | 3 + puppet/modules/ntp/.gitrepo | 11 + puppet/modules/ntp/.nodeset.yml | 35 +++ puppet/modules/ntp/.travis.yml | 40 ++++ puppet/modules/ntp/CHANGELOG | 61 +++++ puppet/modules/ntp/CONTRIBUTING.md | 9 + puppet/modules/ntp/Gemfile | 19 ++ puppet/modules/ntp/LICENSE | 202 ++++++++++++++++ puppet/modules/ntp/Modulefile | 11 + puppet/modules/ntp/README.markdown | 215 +++++++++++++++++ puppet/modules/ntp/Rakefile | 2 + puppet/modules/ntp/manifests/config.pp | 23 ++ puppet/modules/ntp/manifests/init.pp | 58 +++++ puppet/modules/ntp/manifests/install.pp | 9 + puppet/modules/ntp/manifests/params.pp | 116 +++++++++ puppet/modules/ntp/manifests/service.pp | 18 ++ puppet/modules/ntp/spec/classes/ntp_spec.rb | 261 +++++++++++++++++++++ .../fixtures/modules/my_ntp/templates/ntp.conf.erb | 4 + puppet/modules/ntp/spec/spec.opts | 6 + puppet/modules/ntp/spec/spec_helper.rb | 1 + puppet/modules/ntp/spec/spec_helper_system.rb | 26 ++ puppet/modules/ntp/spec/system/basic_spec.rb | 13 + puppet/modules/ntp/spec/system/class_spec.rb | 39 +++ puppet/modules/ntp/spec/system/ntp_config_spec.rb | 35 +++ puppet/modules/ntp/spec/system/ntp_install_spec.rb | 31 +++ puppet/modules/ntp/spec/system/ntp_service_spec.rb | 25 ++ .../ntp/spec/system/preferred_servers_spec.rb | 20 ++ puppet/modules/ntp/spec/system/restrict_spec.rb | 20 ++ .../ntp/spec/unit/puppet/provider/README.markdown | 4 + .../ntp/spec/unit/puppet/type/README.markdown | 4 + puppet/modules/ntp/templates/ntp.conf.erb | 43 ++++ puppet/modules/ntp/tests/init.pp | 11 + 33 files changed, 1380 insertions(+) create mode 100644 puppet/modules/ntp/.fixtures.yml create mode 100644 puppet/modules/ntp/.gitignore create mode 100644 puppet/modules/ntp/.gitrepo create mode 100644 puppet/modules/ntp/.nodeset.yml create mode 100644 puppet/modules/ntp/.travis.yml create mode 100644 puppet/modules/ntp/CHANGELOG create mode 100644 puppet/modules/ntp/CONTRIBUTING.md create mode 100644 puppet/modules/ntp/Gemfile create mode 100644 puppet/modules/ntp/LICENSE create mode 100644 puppet/modules/ntp/Modulefile create mode 100644 puppet/modules/ntp/README.markdown create mode 100644 puppet/modules/ntp/Rakefile create mode 100644 puppet/modules/ntp/manifests/config.pp create mode 100644 puppet/modules/ntp/manifests/init.pp create mode 100644 puppet/modules/ntp/manifests/install.pp create mode 100644 puppet/modules/ntp/manifests/params.pp create mode 100644 puppet/modules/ntp/manifests/service.pp create mode 100644 puppet/modules/ntp/spec/classes/ntp_spec.rb create mode 100644 puppet/modules/ntp/spec/fixtures/modules/my_ntp/templates/ntp.conf.erb create mode 100644 puppet/modules/ntp/spec/spec.opts create mode 100644 puppet/modules/ntp/spec/spec_helper.rb create mode 100644 puppet/modules/ntp/spec/spec_helper_system.rb create mode 100644 puppet/modules/ntp/spec/system/basic_spec.rb create mode 100644 puppet/modules/ntp/spec/system/class_spec.rb create mode 100644 puppet/modules/ntp/spec/system/ntp_config_spec.rb create mode 100644 puppet/modules/ntp/spec/system/ntp_install_spec.rb create mode 100644 puppet/modules/ntp/spec/system/ntp_service_spec.rb create mode 100644 puppet/modules/ntp/spec/system/preferred_servers_spec.rb create mode 100644 puppet/modules/ntp/spec/system/restrict_spec.rb create mode 100644 puppet/modules/ntp/spec/unit/puppet/provider/README.markdown create mode 100644 puppet/modules/ntp/spec/unit/puppet/type/README.markdown create mode 100644 puppet/modules/ntp/templates/ntp.conf.erb create mode 100644 puppet/modules/ntp/tests/init.pp (limited to 'puppet/modules') diff --git a/puppet/modules/ntp/.fixtures.yml b/puppet/modules/ntp/.fixtures.yml new file mode 100644 index 00000000..a4b98014 --- /dev/null +++ b/puppet/modules/ntp/.fixtures.yml @@ -0,0 +1,5 @@ +fixtures: + repositories: + "stdlib": "git://github.com/puppetlabs/puppetlabs-stdlib.git" + symlinks: + "ntp": "#{source_dir}" diff --git a/puppet/modules/ntp/.gitignore b/puppet/modules/ntp/.gitignore new file mode 100644 index 00000000..49cf4650 --- /dev/null +++ b/puppet/modules/ntp/.gitignore @@ -0,0 +1,3 @@ +pkg/ +metadata.json +Gemfile.lock diff --git a/puppet/modules/ntp/.gitrepo b/puppet/modules/ntp/.gitrepo new file mode 100644 index 00000000..dd7d7267 --- /dev/null +++ b/puppet/modules/ntp/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_ntp + branch = master + commit = 8a554ab4b00e25f52a337c4c974fd89f44042957 + parent = 5552d592f9332e55bcf2a5d2c6b0258b8130c26b + cmdver = 0.3.0 diff --git a/puppet/modules/ntp/.nodeset.yml b/puppet/modules/ntp/.nodeset.yml new file mode 100644 index 00000000..cbd0d57b --- /dev/null +++ b/puppet/modules/ntp/.nodeset.yml @@ -0,0 +1,35 @@ +--- +default_set: 'centos-64-x64' +sets: + 'centos-59-x64': + nodes: + "main.foo.vm": + prefab: 'centos-59-x64' + 'centos-64-x64': + nodes: + "main.foo.vm": + prefab: 'centos-64-x64' + 'fedora-18-x64': + nodes: + "main.foo.vm": + prefab: 'fedora-18-x64' + 'debian-607-x64': + nodes: + "main.foo.vm": + prefab: 'debian-607-x64' + 'debian-70rc1-x64': + nodes: + "main.foo.vm": + prefab: 'debian-70rc1-x64' + 'ubuntu-server-10044-x64': + nodes: + "main.foo.vm": + prefab: 'ubuntu-server-10044-x64' + 'ubuntu-server-12042-x64': + nodes: + "main.foo.vm": + prefab: 'ubuntu-server-12042-x64' + 'sles-11sp1-x64': + nodes: + "main.foo.vm": + prefab: 'sles-11sp1-x64' diff --git a/puppet/modules/ntp/.travis.yml b/puppet/modules/ntp/.travis.yml new file mode 100644 index 00000000..e9f0e84b --- /dev/null +++ b/puppet/modules/ntp/.travis.yml @@ -0,0 +1,40 @@ +--- +branches: + only: + - master +language: ruby +bundler_args: --without development +script: "bundle exec rake spec SPEC_OPTS='--format documentation'" +after_success: + - git clone -q git://github.com/puppetlabs/ghpublisher.git .forge-releng + - .forge-releng/publish +rvm: +- 1.8.7 +- 1.9.3 +- 2.0.0 +env: + matrix: + - PUPPET_GEM_VERSION="~> 2.7.0" + - PUPPET_GEM_VERSION="~> 3.0.0" + - PUPPET_GEM_VERSION="~> 3.1.0" + - PUPPET_GEM_VERSION="~> 3.2.0" + global: + - PUBLISHER_LOGIN=puppetlabs + - secure: |- + ZiIkYd9+CdPzpwSjFPnVkCx1FIlipxpbdyD33q94h2Tj5zXjNb1GXizVy0NR + kVxGhU5Ld8y9z8DTqKRgCI1Yymg3H//OU++PKLOQj/X5juWVR4URBNPeBOzu + IJBDl1MADKA4i1+jAZPpz4mTvTtKS4pWKErgCSmhSfsY1hs7n6c= +matrix: + exclude: + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 2.7.0" + - rvm: 2.0.0 + env: PUPPET_GEM_VERSION="~> 2.7.0" + - rvm: 2.0.0 + env: PUPPET_GEM_VERSION="~> 3.0.0" + - rvm: 2.0.0 + env: PUPPET_GEM_VERSION="~> 3.1.0" + - rvm: 1.8.7 + env: PUPPET_GEM_VERSION="~> 3.2.0" +notifications: + email: false diff --git a/puppet/modules/ntp/CHANGELOG b/puppet/modules/ntp/CHANGELOG new file mode 100644 index 00000000..8be6c4e0 --- /dev/null +++ b/puppet/modules/ntp/CHANGELOG @@ -0,0 +1,61 @@ +2013-07-31 - Version 2.0.0 + +Summary: + +The 2.0 release focuses on merging all the distro specific +templates into a single reusable template across all platforms. + +To aid in that goal we now allow you to change the driftfile, +ntp keys, and perferred_servers. + +Backwards-incompatible changes: + +As all the distro specific templates have been removed and a +unified one created you may be missing functionality you +previously relied on. Please test carefully before rolling +out globally. + +Configuration directives that might possibly be affected: +- `filegen` +- `fudge` (for virtual machines) +- `keys` +- `logfile` +- `restrict` +- `restrictkey` +- `statistics` +- `trustedkey` + +Features: +- All templates merged into a single template. +- NTP Keys support added. +- Add preferred servers support. +- Parameters in `ntp` class: + - `driftfile`: path for the ntp driftfile. + - `keys_enable`: Enable NTP keys feature. + - `keys_file`: Path for the NTP keys file. + - `keys_trusted`: Which keys to trust. + - `keys_controlkey`: Which key to use for the control key. + - `keys_requestkey`: Which key to use for the request key. + - `preferred_servers`: Array of servers to prefer. + - `restrict`: Array of restriction options to apply. + +2013-07-15 - Version 1.0.1 +Bugfixes: +- Fix deprecated warning in `autoupdate` parameter. +- Correctly quote is_virtual fact. + +2013-07-08 - Version 1.0.0 +Features: +- Completely refactored to split across several classes. +- rspec-puppet tests rewritten to cover more options. +- rspec-system tests added. +- ArchLinux handled via osfamily instead of special casing. +- parameters in `ntp` class: + - `autoupdate`: deprecated in favor of directly setting package_ensure. + - `panic`: set to false if you wish to allow large clock skews. + +2011-11-10 Dan Bode - 0.0.4 +Add Amazon Linux as a supported platform +Add unit tests +2011-06-16 Jeff McCune - 0.0.3 +Initial release under puppetlabs diff --git a/puppet/modules/ntp/CONTRIBUTING.md b/puppet/modules/ntp/CONTRIBUTING.md new file mode 100644 index 00000000..a2b1d77b --- /dev/null +++ b/puppet/modules/ntp/CONTRIBUTING.md @@ -0,0 +1,9 @@ +Puppet Labs modules on the Puppet Forge are open projects, and community contributions +are essential for keeping them great. We can’t access the huge number of platforms and +myriad of hardware, software, and deployment configurations that Puppet is intended to serve. + +We want to keep it as easy as possible to contribute changes so that our modules work +in your environment. There are a few guidelines that we need contributors to follow so +that we can have a chance of keeping on top of things. + +You can read the complete module contribution guide [on the Puppet Labs wiki.](http://projects.puppetlabs.com/projects/module-site/wiki/Module_contributing) diff --git a/puppet/modules/ntp/Gemfile b/puppet/modules/ntp/Gemfile new file mode 100644 index 00000000..4e733308 --- /dev/null +++ b/puppet/modules/ntp/Gemfile @@ -0,0 +1,19 @@ +source 'https://rubygems.org' + +group :development, :test do + gem 'rake', :require => false + gem 'puppetlabs_spec_helper', :require => false + gem 'rspec-system-puppet', :require => false + gem 'puppet-lint', :require => false + gem 'serverspec', :require => false + gem 'rspec-system-serverspec', :require => false + gem 'vagrant-wrapper', :require => false +end + +if puppetversion = ENV['PUPPET_GEM_VERSION'] + gem 'puppet', puppetversion, :require => false +else + gem 'puppet', :require => false +end + +# vim:ft=ruby diff --git a/puppet/modules/ntp/LICENSE b/puppet/modules/ntp/LICENSE new file mode 100644 index 00000000..57bc88a1 --- /dev/null +++ b/puppet/modules/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/puppet/modules/ntp/Modulefile b/puppet/modules/ntp/Modulefile new file mode 100644 index 00000000..9610ef67 --- /dev/null +++ b/puppet/modules/ntp/Modulefile @@ -0,0 +1,11 @@ +name 'puppetlabs-ntp' +version '2.0.0-rc1' +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, Fedora, FreeBSD, ArchLinux and Gentoo.' +project_page 'http://github.com/puppetlabs/puppetlabs-ntp' + +## Add dependencies, if any: +dependency 'puppetlabs/stdlib', '>= 0.1.6' diff --git a/puppet/modules/ntp/README.markdown b/puppet/modules/ntp/README.markdown new file mode 100644 index 00000000..3aedd47a --- /dev/null +++ b/puppet/modules/ntp/README.markdown @@ -0,0 +1,215 @@ +#ntp + +####Table of Contents + +1. [Overview](#overview) +2. [Module Description - What the module does and why it is useful](#module-description) +3. [Setup - The basics of getting started with ntp](#setup) + * [What ntp affects](#what-ntp-affects) + * [Setup requirements](#setup-requirements) + * [Beginning with ntp](#beginning-with-ntp) +4. [Usage - Configuration options and additional functionality](#usage) +5. [Reference - An under-the-hood peek at what the module is doing and how](#reference) +5. [Limitations - OS compatibility, etc.](#limitations) +6. [Development - Guide for contributing to the module](#development) + +##Overview + +The NTP module installs, configures, and manages the ntp service. + +##Module Description + +The NTP module handles running NTP across a range of operating systems and +distributions. Where possible we use the upstream ntp templates so that the +results closely match what you'd get if you modified the package default conf +files. + +##Setup + +###What ntp affects + +* ntp package. +* ntp configuration file. +* ntp service. + +###Beginning with ntp + +include '::ntp' is enough to get you up and running. If you wish to pass in +parameters like which servers to use then you can use: + +```puppet +class { '::ntp': + servers => [ 'ntp1.corp.com', 'ntp2.corp.com' ], +} +``` + +##Usage + +All interaction with the ntp module can do be done through the main ntp class. +This means you can simply toggle the options in the ntp class to get at the +full functionality. + +###I just want NTP, what's the minimum I need? + +```puppet +include '::ntp' +``` + +###I just want to tweak the servers, nothing else. + +```puppet +class { '::ntp': + servers => [ 'ntp1.corp.com', 'ntp2.corp.com' ], +} +``` + +###I'd like to make sure I restrict who can connect as well. + +```puppet +class { '::ntp': + servers => [ 'ntp1.corp.com', 'ntp2.corp.com' ], + restrict => 'restrict 127.0.0.1', +} +``` + +###I'd like to opt out of having the service controlled, we use another tool for that. + +```puppet +class { '::ntp': + servers => [ 'ntp1.corp.com', 'ntp2.corp.com' ], + restrict => 'restrict 127.0.0.1', + manage_service => false, +} +``` + +###Looks great! But I'd like a different template, we need to do something unique here. + +```puppet +class { '::ntp': + servers => [ 'ntp1.corp.com', 'ntp2.corp.com' ], + restrict => 'restrict 127.0.0.1', + manage_service => false, + config_template => 'different/module/custom.template.erb', +} +``` + +##Reference + +###Classes + +* ntp: Main class, includes all the rest. +* ntp::install: Handles the packages. +* ntp::config: Handles the configuration file. +* ntp::service: Handles the service. + +###Parameters + +The following parameters are available in the ntp module + +####`autoupdate` + +Deprecated: This parameter previously determined if the ntp module should be +automatically updated to the latest version available. Replaced by package\_ +ensure. + +####`config` + +This sets the file to write ntp configuration into. + +####`config_template` + +This determines which template puppet should use for the ntp configuration. + +####`driftfile` + +This sets the location of the driftfile for ntp. + +####`keys_controlkey` + +Which of the keys is used as the control key. + +####`keys_enable` + +Should the ntp keys functionality be enabled. + +####`keys_file` + +Location of the keys file. + +####`keys_requestkey` + +Which of the keys is used as the request key. + +####`package_ensure` + +This can be set to 'present' or 'latest' or a specific version to choose the +ntp package to be installed. + +####`package_name` + +This determines the name of the package to install. + +####`panic` + +This determines if ntp should 'panic' in the event of a very large clock skew. +We set this to false if you're on a virtual machine by default as they don't +do a great job with keeping time. + +####`preferred_servers` + +List of ntp servers to prefer. Will append prefer for any server in this list +that also appears in the servers list. + +####`restrict` + +This sets the restrict options in the ntp configuration. + +####`servers` + +This selects the servers to use for ntp peers. + +####`service_enable` + +This determines if the service should be enabled at boot. + +####`service_ensure` + +This determines if the service should be running or not. + +####`service_manage` + +This selects if puppet should manage the service in the first place. + +####`service_name` + +This selects the name of the ntp service for puppet to manage. + + +##Limitations + +This module has been built on and tested against Puppet 2.7 and higher. + +The module has been tested on: + +* RedHat Enterprise Linux 5/6 +* Debian 6/7 +* CentOS 5/6 +* Ubuntu 12.04 +* Gentoo +* Arch Linux +* FreeBSD + +Testing on other platforms has been light and cannot be guaranteed. + +##Development + +Puppet Labs modules on the Puppet Forge are open projects, and community +contributions are essential for keeping them great. We can’t access the +huge number of platforms and myriad of hardware, software, and deployment +configurations that Puppet is intended to serve. + +We want to keep it as easy as possible to contribute changes so that our +modules work in your environment. There are a few guidelines that we need +contributors to follow so that we can have a chance of keeping on top of things. + +You can read the complete module contribution guide [on the Puppet Labs wiki.](http://projects.puppetlabs.com/projects/module-site/wiki/Module_contributing) diff --git a/puppet/modules/ntp/Rakefile b/puppet/modules/ntp/Rakefile new file mode 100644 index 00000000..bb60173e --- /dev/null +++ b/puppet/modules/ntp/Rakefile @@ -0,0 +1,2 @@ +require 'puppetlabs_spec_helper/rake_tasks' +require 'rspec-system/rake_task' diff --git a/puppet/modules/ntp/manifests/config.pp b/puppet/modules/ntp/manifests/config.pp new file mode 100644 index 00000000..1c8963dc --- /dev/null +++ b/puppet/modules/ntp/manifests/config.pp @@ -0,0 +1,23 @@ +# +class ntp::config inherits ntp { + + if $keys_enable { + $directory = dirname($keys_file) + file { $directory: + ensure => directory, + owner => 0, + group => 0, + mode => '0755', + recurse => true, + } + } + + file { $config: + ensure => file, + owner => 0, + group => 0, + mode => '0644', + content => template($config_template), + } + +} diff --git a/puppet/modules/ntp/manifests/init.pp b/puppet/modules/ntp/manifests/init.pp new file mode 100644 index 00000000..be951187 --- /dev/null +++ b/puppet/modules/ntp/manifests/init.pp @@ -0,0 +1,58 @@ +class ntp ( + $autoupdate = $ntp::params::autoupdate, + $config = $ntp::params::config, + $config_template = $ntp::params::config_template, + $driftfile = $ntp::params::driftfile, + $keys_enable = $ntp::params::keys_enable, + $keys_file = $ntp::params::keys_file, + $keys_controlkey = $ntp::params::keys_controlkey, + $keys_requestkey = $ntp::params::keys_requestkey, + $keys_trusted = $ntp::params::keys_trusted, + $package_ensure = $ntp::params::package_ensure, + $package_name = $ntp::params::package_name, + $panic = $ntp::params::panic, + $preferred_servers = $ntp::params::preferred_servers, + $restrict = $ntp::params::restrict, + $servers = $ntp::params::servers, + $service_enable = $ntp::params::service_enable, + $service_ensure = $ntp::params::service_ensure, + $service_manage = $ntp::params::service_manage, + $service_name = $ntp::params::service_name, +) inherits ntp::params { + + validate_absolute_path($config) + validate_string($config_template) + validate_absolute_path($driftfile) + validate_bool($keys_enable) + validate_re($keys_controlkey, ['^\d+$', '']) + validate_re($keys_requestkey, ['^\d+$', '']) + validate_array($keys_trusted) + validate_string($package_ensure) + validate_array($package_name) + validate_bool($panic) + validate_array($preferred_servers) + validate_array($restrict) + validate_array($servers) + validate_bool($service_enable) + validate_string($service_ensure) + validate_bool($service_manage) + validate_string($service_name) + + if $autoupdate { + notice('autoupdate parameter has been deprecated and replaced with package_ensure. Set this to latest for the same behavior as autoupdate => true.') + } + + include '::ntp::install' + include '::ntp::config' + include '::ntp::service' + + # Anchor this as per #8040 - this ensures that classes won't float off and + # mess everything up. You can read about this at: + # http://docs.puppetlabs.com/puppet/2.7/reference/lang_containment.html#known-issues + anchor { 'ntp::begin': } + anchor { 'ntp::end': } + + Anchor['ntp::begin'] -> Class['::ntp::install'] -> Class['::ntp::config'] + ~> Class['::ntp::service'] -> Anchor['ntp::end'] + +} diff --git a/puppet/modules/ntp/manifests/install.pp b/puppet/modules/ntp/manifests/install.pp new file mode 100644 index 00000000..098949c3 --- /dev/null +++ b/puppet/modules/ntp/manifests/install.pp @@ -0,0 +1,9 @@ +# +class ntp::install inherits ntp { + + package { 'ntp': + ensure => $package_ensure, + name => $package_name, + } + +} diff --git a/puppet/modules/ntp/manifests/params.pp b/puppet/modules/ntp/manifests/params.pp new file mode 100644 index 00000000..10a4fb2b --- /dev/null +++ b/puppet/modules/ntp/manifests/params.pp @@ -0,0 +1,116 @@ +class ntp::params { + + $autoupdate = false + $config_template = 'ntp/ntp.conf.erb' + $keys_enable = false + $keys_controlkey = '' + $keys_requestkey = '' + $keys_trusted = [] + $package_ensure = 'present' + $preferred_servers = [] + $restrict = [ + 'restrict default kod nomodify notrap nopeer noquery', + 'restrict -6 default kod nomodify notrap nopeer noquery', + 'restrict 127.0.0.1', + 'restrict -6 ::1', + ] + $service_enable = true + $service_ensure = 'running' + $service_manage = true + + # On virtual machines allow large clock skews. + $panic = str2bool($::is_virtual) ? { + true => false, + default => true, + } + + case $::osfamily { + 'Debian': { + $config = '/etc/ntp.conf' + $keys_file = '/etc/ntp/keys' + $driftfile = '/var/lib/ntp/drift' + $package_name = [ 'ntp' ] + $service_name = 'ntp' + $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', + ] + } + 'RedHat': { + $config = '/etc/ntp.conf' + $driftfile = '/var/lib/ntp/drift' + $keys_file = '/etc/ntp/keys' + $package_name = [ 'ntp' ] + $service_name = 'ntpd' + $servers = [ + '0.centos.pool.ntp.org', + '1.centos.pool.ntp.org', + '2.centos.pool.ntp.org', + ] + } + 'SuSE': { + $config = '/etc/ntp.conf' + $driftfile = '/var/lib/ntp/drift/ntp.drift' + $keys_file = '/etc/ntp/keys' + $package_name = [ 'ntp' ] + $service_name = 'ntp' + $servers = [ + '0.opensuse.pool.ntp.org', + '1.opensuse.pool.ntp.org', + '2.opensuse.pool.ntp.org', + '3.opensuse.pool.ntp.org', + ] + } + 'FreeBSD': { + $config = '/etc/ntp.conf' + $driftfile = '/var/db/ntpd.drift' + $keys_file = '/etc/ntp/keys' + $package_name = ['net/ntp'] + $service_name = 'ntpd' + $servers = [ + '0.freebsd.pool.ntp.org iburst maxpoll 9', + '1.freebsd.pool.ntp.org iburst maxpoll 9', + '2.freebsd.pool.ntp.org iburst maxpoll 9', + '3.freebsd.pool.ntp.org iburst maxpoll 9', + ] + } + 'Archlinux': { + $config = '/etc/ntp.conf' + $driftfile = '/var/lib/ntp/drift' + $keys_file = '/etc/ntp/keys' + $package_name = [ 'ntp' ] + $service_name = 'ntpd' + $servers = [ + '0.pool.ntp.org', + '1.pool.ntp.org', + '2.pool.ntp.org', + ] + } + 'Linux': { + # Account for distributions that don't have $::osfamily specific settings. + case $::operatingsystem { + 'Gentoo': { + $config = '/etc/ntp.conf' + $driftfile = '/var/lib/ntp/drift' + $keys_file = '/etc/ntp/keys' + $package_name = ['net-misc/ntp'] + $service_name = 'ntpd' + $servers = [ + '0.gentoo.pool.ntp.org', + '1.gentoo.pool.ntp.org', + '2.gentoo.pool.ntp.org', + '3.gentoo.pool.ntp.org', + ] + } + default: { + fail("The ${module_name} module is not supported on an ${::operatingsystem} distribution.") + } + } + } + default: { + fail("The ${module_name} module is not supported on an ${::osfamily} based system.") + } + } +} diff --git a/puppet/modules/ntp/manifests/service.pp b/puppet/modules/ntp/manifests/service.pp new file mode 100644 index 00000000..3f1ada0b --- /dev/null +++ b/puppet/modules/ntp/manifests/service.pp @@ -0,0 +1,18 @@ +# +class ntp::service inherits ntp { + + if ! ($service_ensure in [ 'running', 'stopped' ]) { + fail('service_ensure parameter must be running or stopped') + } + + if $service_manage == true { + service { 'ntp': + ensure => $service_ensure, + enable => $service_enable, + name => $service_name, + hasstatus => true, + hasrestart => true, + } + } + +} diff --git a/puppet/modules/ntp/spec/classes/ntp_spec.rb b/puppet/modules/ntp/spec/classes/ntp_spec.rb new file mode 100644 index 00000000..6c636f40 --- /dev/null +++ b/puppet/modules/ntp/spec/classes/ntp_spec.rb @@ -0,0 +1,261 @@ +require 'spec_helper' + +describe 'ntp' do + + ['Debian', 'RedHat','SuSE', 'FreeBSD', 'Archlinux', 'Gentoo'].each do |system| + if system == 'Gentoo' + let(:facts) {{ :osfamily => 'Linux', :operatingsystem => system }} + else + let(:facts) {{ :osfamily => system }} + end + + it { should include_class('ntp::install') } + it { should include_class('ntp::config') } + it { should include_class('ntp::service') } + + describe 'ntp::config on #{system}' do + it { should contain_file('/etc/ntp.conf').with_owner('0') } + it { should contain_file('/etc/ntp.conf').with_group('0') } + it { should contain_file('/etc/ntp.conf').with_mode('0644') } + + describe 'allows template to be overridden' do + let(:params) {{ :config_template => 'my_ntp/ntp.conf.erb' }} + it { should contain_file('/etc/ntp.conf').with({ + 'content' => /server foobar/}) + } + end + + describe "keys for osfamily #{system}" do + context "when enabled" do + let(:params) {{ + :keys_enable => true, + :keys_file => '/etc/ntp/ntp.keys', + :keys_trusted => ['1', '2', '3'], + :keys_controlkey => '2', + :keys_requestkey => '3', + }} + + it { should contain_file('/etc/ntp').with({ + 'ensure' => 'directory'}) + } + it { should contain_file('/etc/ntp.conf').with({ + 'content' => /trustedkey 1 2 3/}) + } + it { should contain_file('/etc/ntp.conf').with({ + 'content' => /controlkey 2/}) + } + it { should contain_file('/etc/ntp.conf').with({ + 'content' => /requestkey 3/}) + } + end + end + + context "when disabled" do + let(:params) {{ + :keys_enable => false, + :keys_file => '/etc/ntp/ntp.keys', + :keys_trusted => ['1', '2', '3'], + :keys_controlkey => '2', + :keys_requestkey => '3', + }} + + it { should_not contain_file('/etc/ntp').with({ + 'ensure' => 'directory'}) + } + it { should_not contain_file('/etc/ntp.conf').with({ + 'content' => /trustedkey 1 2 3/}) + } + it { should_not contain_file('/etc/ntp.conf').with({ + 'content' => /controlkey 2/}) + } + it { should_not contain_file('/etc/ntp.conf').with({ + 'content' => /requestkey 3/}) + } + end + + describe 'preferred servers' do + context "when set" do + let(:params) {{ + :servers => ['a', 'b', 'c', 'd'], + :preferred_servers => ['a', 'b'] + }} + + it { should contain_file('/etc/ntp.conf').with({ + 'content' => /server a prefer\nserver b prefer\nserver c\nserver d/}) + } + end + context "when not set" do + let(:params) {{ + :servers => ['a', 'b', 'c', 'd'], + :preferred_servers => [] + }} + + it { should_not contain_file('/etc/ntp.conf').with({ + 'content' => /server a prefer/}) + } + end + end + + describe 'ntp::install on #{system}' do + let(:params) {{ :package_ensure => 'present', :package_name => ['ntp'], }} + + it { should contain_package('ntp').with( + :ensure => 'present', + :name => 'ntp' + )} + + describe 'should allow package ensure to be overridden' do + let(:params) {{ :package_ensure => 'latest', :package_name => ['ntp'] }} + it { should contain_package('ntp').with_ensure('latest') } + end + + describe 'should allow the package name to be overridden' do + let(:params) {{ :package_ensure => 'present', :package_name => ['hambaby'] }} + it { should contain_package('ntp').with_name('hambaby') } + end + end + + describe 'ntp::service' do + let(:params) {{ + :service_manage => true, + :service_enable => true, + :service_ensure => 'running', + :service_name => 'ntp' + }} + + describe 'with defaults' do + it { should contain_service('ntp').with( + :enable => true, + :ensure => 'running', + :name => 'ntp' + )} + end + + describe 'service_ensure' do + describe 'when overridden' do + let(:params) {{ :service_name => 'ntp', :service_ensure => 'stopped' }} + it { should contain_service('ntp').with_ensure('stopped') } + end + end + + describe 'service_manage' do + let(:params) {{ + :service_manage => false, + :service_enable => true, + :service_ensure => 'running', + :service_name => 'ntpd', + }} + + it 'when set to false' do + should_not contain_service('ntp').with({ + 'enable' => true, + 'ensure' => 'running', + 'name' => 'ntpd' + }) + end + end + end + end + + context 'ntp::config' do + describe "for operating system Gentoo" do + let(:facts) {{ :operatingsystem => 'Gentoo', + :osfamily => 'Linux' }} + + it 'uses the NTP pool servers by default' do + should contain_file('/etc/ntp.conf').with({ + 'content' => /server \d.gentoo.pool.ntp.org/, + }) + end + end + describe "on osfamily Debian" do + let(:facts) {{ :osfamily => 'debian' }} + + it 'uses the debian ntp servers by default' do + should contain_file('/etc/ntp.conf').with({ + 'content' => /server \d.debian.pool.ntp.org iburst/, + }) + end + end + + describe "on osfamily RedHat" do + let(:facts) {{ :osfamily => 'RedHat' }} + + it 'uses the redhat ntp servers by default' do + should contain_file('/etc/ntp.conf').with({ + 'content' => /server \d.centos.pool.ntp.org/, + }) + end + end + + describe "on osfamily SuSE" do + let(:facts) {{ :osfamily => 'SuSE' }} + + it 'uses the opensuse ntp servers by default' do + should contain_file('/etc/ntp.conf').with({ + 'content' => /server \d.opensuse.pool.ntp.org/, + }) + end + end + + describe "on osfamily FreeBSD" do + let(:facts) {{ :osfamily => 'FreeBSD' }} + + it 'uses the freebsd ntp servers by default' do + should contain_file('/etc/ntp.conf').with({ + 'content' => /server \d.freebsd.pool.ntp.org iburst maxpoll 9/, + }) + end + end + + describe "on osfamily ArchLinux" do + let(:facts) {{ :osfamily => 'ArchLinux' }} + + it 'uses the NTP pool servers by default' do + should contain_file('/etc/ntp.conf').with({ + 'content' => /server \d.pool.ntp.org/, + }) + end + end + + describe "for operating system family unsupported" do + let(:facts) {{ + :osfamily => 'unsupported', + }} + + it { expect{ subject }.to raise_error( + /^The ntp module is not supported on an unsupported based system./ + )} + end + end + + describe 'for virtual machines' do + let(:facts) {{ :osfamily => 'Archlinux', + :is_virtual => 'true' }} + + it 'should not use local clock as a time source' do + should_not contain_file('/etc/ntp.conf').with({ + 'content' => /server.*127.127.1.0.*fudge.*127.127.1.0 stratum 10/, + }) + end + + it 'allows large clock skews' do + should contain_file('/etc/ntp.conf').with({ + 'content' => /tinker panic 0/, + }) + end + end + + describe 'for physical machines' do + let(:facts) {{ :osfamily => 'Archlinux', + :is_virtual => 'false' }} + + it 'disallows large clock skews' do + should_not contain_file('/etc/ntp.conf').with({ + 'content' => /tinker panic 0/, + }) + end + end + end + +end diff --git a/puppet/modules/ntp/spec/fixtures/modules/my_ntp/templates/ntp.conf.erb b/puppet/modules/ntp/spec/fixtures/modules/my_ntp/templates/ntp.conf.erb new file mode 100644 index 00000000..40cf67c6 --- /dev/null +++ b/puppet/modules/ntp/spec/fixtures/modules/my_ntp/templates/ntp.conf.erb @@ -0,0 +1,4 @@ +#my uber ntp config +# + +server foobar diff --git a/puppet/modules/ntp/spec/spec.opts b/puppet/modules/ntp/spec/spec.opts new file mode 100644 index 00000000..91cd6427 --- /dev/null +++ b/puppet/modules/ntp/spec/spec.opts @@ -0,0 +1,6 @@ +--format +s +--colour +--loadby +mtime +--backtrace diff --git a/puppet/modules/ntp/spec/spec_helper.rb b/puppet/modules/ntp/spec/spec_helper.rb new file mode 100644 index 00000000..2c6f5664 --- /dev/null +++ b/puppet/modules/ntp/spec/spec_helper.rb @@ -0,0 +1 @@ +require 'puppetlabs_spec_helper/module_spec_helper' diff --git a/puppet/modules/ntp/spec/spec_helper_system.rb b/puppet/modules/ntp/spec/spec_helper_system.rb new file mode 100644 index 00000000..d5208463 --- /dev/null +++ b/puppet/modules/ntp/spec/spec_helper_system.rb @@ -0,0 +1,26 @@ +require 'rspec-system/spec_helper' +require 'rspec-system-puppet/helpers' +require 'rspec-system-serverspec/helpers' +include Serverspec::Helper::RSpecSystem +include Serverspec::Helper::DetectOS +include RSpecSystemPuppet::Helpers + +RSpec.configure do |c| + # Project root + proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + # Enable colour + c.tty = true + + c.include RSpecSystemPuppet::Helpers + + # This is where we 'setup' the nodes before running our tests + c.before :suite do + # Install puppet + puppet_install + + # Install modules and dependencies + puppet_module_install(:source => proj_root, :module_name => 'ntp') + shell('puppet module install puppetlabs-stdlib') + end +end diff --git a/puppet/modules/ntp/spec/system/basic_spec.rb b/puppet/modules/ntp/spec/system/basic_spec.rb new file mode 100644 index 00000000..7b717a04 --- /dev/null +++ b/puppet/modules/ntp/spec/system/basic_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper_system' + +# Here we put the more basic fundamental tests, ultra obvious stuff. +describe "basic tests:" do + context 'make sure we have copied the module across' do + # No point diagnosing any more if the module wasn't copied properly + context shell 'ls /etc/puppet/modules/ntp' do + its(:stdout) { should =~ /Modulefile/ } + its(:stderr) { should be_empty } + its(:exit_code) { should be_zero } + end + end +end diff --git a/puppet/modules/ntp/spec/system/class_spec.rb b/puppet/modules/ntp/spec/system/class_spec.rb new file mode 100644 index 00000000..49dfc641 --- /dev/null +++ b/puppet/modules/ntp/spec/system/class_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper_system' + +describe "ntp class:" do + context 'should run successfully' do + pp = "class { 'ntp': }" + + context puppet_apply(pp) do + its(:stderr) { should be_empty } + its(:exit_code) { should_not == 1 } + its(:refresh) { should be_nil } + its(:stderr) { should be_empty } + its(:exit_code) { should be_zero } + end + end + + context 'service_ensure => stopped:' do + pp = "class { 'ntp': service_ensure => stopped }" + + context puppet_apply(pp) do + its(:stderr) { should be_empty } + its(:exit_code) { should_not == 1 } + its(:refresh) { should be_nil } + its(:stderr) { should be_empty } + its(:exit_code) { should be_zero } + end + end + + context 'service_ensure => running:' do + pp = "class { 'ntp': service_ensure => running }" + + context puppet_apply(pp) do |r| + its(:stderr) { should be_empty } + its(:exit_code) { should_not == 1 } + its(:refresh) { should be_nil } + its(:stderr) { should be_empty } + its(:exit_code) { should be_zero } + end + end +end diff --git a/puppet/modules/ntp/spec/system/ntp_config_spec.rb b/puppet/modules/ntp/spec/system/ntp_config_spec.rb new file mode 100644 index 00000000..194cdf10 --- /dev/null +++ b/puppet/modules/ntp/spec/system/ntp_config_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper_system' + +describe 'ntp::config class' do + let(:os) { + node.facts['osfamily'] + } + + puppet_apply(%{ + class { 'ntp': } + }) + + case node.facts['osfamily'] + when 'FreeBSD' + line = '0.freebsd.pool.ntp.org iburst maxpoll 9' + when 'Debian' + line = '0.debian.pool.ntp.org iburst' + when 'RedHat' + line = '0.centos.pool.ntp.org' + when 'SuSE' + line = '0.opensuse.pool.ntp.org' + when 'Linux' + case node.facts['operatingsystem'] + when 'ArchLinux' + line = '0.pool.ntp.org' + when 'Gentoo' + line = '0.gentoo.pool.ntp.org' + end + end + + describe file('/etc/ntp.conf') do + it { should be_file } + it { should contain line } + end + +end diff --git a/puppet/modules/ntp/spec/system/ntp_install_spec.rb b/puppet/modules/ntp/spec/system/ntp_install_spec.rb new file mode 100644 index 00000000..39759c5e --- /dev/null +++ b/puppet/modules/ntp/spec/system/ntp_install_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper_system' + + +describe 'ntp::install class' do + let(:os) { + node.facts['osfamily'] + } + + case node.facts['osfamily'] + when 'FreeBSD' + packagename = 'net/ntp' + when 'Linux' + case node.facts['operatingsystem'] + when 'ArchLinux' + packagename = 'ntp' + when 'Gentoo' + packagename = 'net-misc/ntp' + end + else + packagename = 'ntp' + end + + puppet_apply(%{ + class { 'ntp': } + }) + + describe package(packagename) do + it { should be_installed } + end + +end diff --git a/puppet/modules/ntp/spec/system/ntp_service_spec.rb b/puppet/modules/ntp/spec/system/ntp_service_spec.rb new file mode 100644 index 00000000..b97e2a4e --- /dev/null +++ b/puppet/modules/ntp/spec/system/ntp_service_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper_system' + + +describe 'ntp::service class' do + let(:os) { + node.facts['osfamily'] + } + + case node.facts['osfamily'] + when 'RedHat', 'FreeBSD', 'Linux' + servicename = 'ntpd' + else + servicename = 'ntp' + end + + puppet_apply(%{ + class { 'ntp': } + }) + + describe service(servicename) do + it { should be_enabled } + it { should be_running } + end + +end diff --git a/puppet/modules/ntp/spec/system/preferred_servers_spec.rb b/puppet/modules/ntp/spec/system/preferred_servers_spec.rb new file mode 100644 index 00000000..686861bc --- /dev/null +++ b/puppet/modules/ntp/spec/system/preferred_servers_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper_system' + +describe 'preferred servers' do + it 'applies cleanly' do + puppet_apply(%{ + class { '::ntp': + servers => ['a', 'b', 'c', 'd'], + preferred_servers => ['c', 'd'], + } + }) + end + + describe file('/etc/ntp.conf') do + it { should be_file } + it { should contain 'server a' } + it { should contain 'server b' } + it { should contain 'server c prefer' } + it { should contain 'server d prefer' } + end +end diff --git a/puppet/modules/ntp/spec/system/restrict_spec.rb b/puppet/modules/ntp/spec/system/restrict_spec.rb new file mode 100644 index 00000000..ae23bc01 --- /dev/null +++ b/puppet/modules/ntp/spec/system/restrict_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper_system' + +describe "ntp class with restrict:" do + context 'should run successfully' do + pp = "class { 'ntp': restrict => ['test restrict']}" + + context puppet_apply(pp) do + its(:stderr) { should be_empty } + its(:exit_code) { should_not == 1 } + its(:refresh) { should be_nil } + its(:stderr) { should be_empty } + its(:exit_code) { should be_zero } + end + end + + describe file('/etc/ntp.conf') do + it { should contain('test restrict') } + end + +end diff --git a/puppet/modules/ntp/spec/unit/puppet/provider/README.markdown b/puppet/modules/ntp/spec/unit/puppet/provider/README.markdown new file mode 100644 index 00000000..70258502 --- /dev/null +++ b/puppet/modules/ntp/spec/unit/puppet/provider/README.markdown @@ -0,0 +1,4 @@ +Provider Specs +============== + +Define specs for your providers under this directory. diff --git a/puppet/modules/ntp/spec/unit/puppet/type/README.markdown b/puppet/modules/ntp/spec/unit/puppet/type/README.markdown new file mode 100644 index 00000000..1ee19ac8 --- /dev/null +++ b/puppet/modules/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/puppet/modules/ntp/templates/ntp.conf.erb b/puppet/modules/ntp/templates/ntp.conf.erb new file mode 100644 index 00000000..94b36755 --- /dev/null +++ b/puppet/modules/ntp/templates/ntp.conf.erb @@ -0,0 +1,43 @@ +# ntp.conf: Managed by puppet. +# +<% if @panic == false -%> +# Keep ntpd from panicking in the event of a large clock skew +# when a VM guest is suspended and resumed. +tinker panic 0 +<% end -%> + +<% if @restrict != [] -%> +# Permit time synchronization with our time source, but do not' +# permit the source to query or modify the service on this system.' +<% @restrict.flatten.each do |restrict| -%> +<%= restrict %> +<% end %> +<% end -%> + +# Servers +<% [@servers].flatten.each do |server| -%> +server <%= server %><% if @preferred_servers.include?(server) -%> prefer<% end %> +<% end -%> + +<% if scope.lookupvar('::is_virtual') == "false" -%> +# 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 +<% end -%> + +# Driftfile. +driftfile <%= @driftfile %> + +<% if @keys_enable -%> +keys <%= @keys_file %> +<% unless @keys_trusted.empty? -%> +trustedkey <%= @keys_trusted.join(' ') %> +<% end -%> +<% if @keys_requestkey != '' -%> +requestkey <%= @keys_requestkey %> +<% end -%> +<% if @keys_controlkey != '' -%> +controlkey <%= @keys_controlkey %> +<% end -%> +<% end -%> diff --git a/puppet/modules/ntp/tests/init.pp b/puppet/modules/ntp/tests/init.pp new file mode 100644 index 00000000..e6d9b537 --- /dev/null +++ b/puppet/modules/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'], + } + +} -- cgit v1.2.3 From 1f231f09a9b6911b2ca57ac82235c6028922d54f Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:35 -0400 Subject: git subrepo clone https://leap.se/git/puppet_git puppet/modules/git subrepo: subdir: "puppet/modules/git" merged: "ba5dd8d" upstream: origin: "https://leap.se/git/puppet_git" branch: "master" commit: "ba5dd8d" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: Ic7edc42aa0639e51cfa1873ec265e20e25f0a4f4 --- puppet/modules/git/.gitrepo | 11 ++ puppet/modules/git/files/config/CentOS/git-daemon | 26 ++++ .../git/files/config/CentOS/git-daemon.vhosts | 27 ++++ puppet/modules/git/files/config/Debian/git-daemon | 22 +++ puppet/modules/git/files/init.d/CentOS/git-daemon | 75 ++++++++++ puppet/modules/git/files/init.d/Debian/git-daemon | 151 +++++++++++++++++++++ puppet/modules/git/files/web/gitweb.conf | 53 ++++++++ puppet/modules/git/files/xinetd.d/git | 16 +++ puppet/modules/git/files/xinetd.d/git.disabled | 16 +++ puppet/modules/git/files/xinetd.d/git.vhosts | 16 +++ puppet/modules/git/manifests/base.pp | 7 + puppet/modules/git/manifests/centos.pp | 2 + puppet/modules/git/manifests/changes.pp | 33 +++++ puppet/modules/git/manifests/clone.pp | 60 ++++++++ puppet/modules/git/manifests/daemon.pp | 17 +++ puppet/modules/git/manifests/daemon/base.pp | 31 +++++ puppet/modules/git/manifests/daemon/centos.pp | 19 +++ puppet/modules/git/manifests/daemon/disable.pp | 33 +++++ puppet/modules/git/manifests/daemon/vhosts.pp | 10 ++ puppet/modules/git/manifests/debian.pp | 6 + puppet/modules/git/manifests/init.pp | 25 ++++ puppet/modules/git/manifests/svn.pp | 10 ++ puppet/modules/git/manifests/web.pp | 20 +++ puppet/modules/git/manifests/web/absent.pp | 17 +++ puppet/modules/git/manifests/web/lighttpd.pp | 7 + puppet/modules/git/manifests/web/repo.pp | 56 ++++++++ puppet/modules/git/manifests/web/repo/lighttpd.pp | 16 +++ puppet/modules/git/templates/web/config | 31 +++++ puppet/modules/git/templates/web/lighttpd | 21 +++ 29 files changed, 834 insertions(+) create mode 100644 puppet/modules/git/.gitrepo create mode 100644 puppet/modules/git/files/config/CentOS/git-daemon create mode 100644 puppet/modules/git/files/config/CentOS/git-daemon.vhosts create mode 100644 puppet/modules/git/files/config/Debian/git-daemon create mode 100644 puppet/modules/git/files/init.d/CentOS/git-daemon create mode 100644 puppet/modules/git/files/init.d/Debian/git-daemon create mode 100644 puppet/modules/git/files/web/gitweb.conf create mode 100644 puppet/modules/git/files/xinetd.d/git create mode 100644 puppet/modules/git/files/xinetd.d/git.disabled create mode 100644 puppet/modules/git/files/xinetd.d/git.vhosts create mode 100644 puppet/modules/git/manifests/base.pp create mode 100644 puppet/modules/git/manifests/centos.pp create mode 100644 puppet/modules/git/manifests/changes.pp create mode 100644 puppet/modules/git/manifests/clone.pp create mode 100644 puppet/modules/git/manifests/daemon.pp create mode 100644 puppet/modules/git/manifests/daemon/base.pp create mode 100644 puppet/modules/git/manifests/daemon/centos.pp create mode 100644 puppet/modules/git/manifests/daemon/disable.pp create mode 100644 puppet/modules/git/manifests/daemon/vhosts.pp create mode 100644 puppet/modules/git/manifests/debian.pp create mode 100644 puppet/modules/git/manifests/init.pp create mode 100644 puppet/modules/git/manifests/svn.pp create mode 100644 puppet/modules/git/manifests/web.pp create mode 100644 puppet/modules/git/manifests/web/absent.pp create mode 100644 puppet/modules/git/manifests/web/lighttpd.pp create mode 100644 puppet/modules/git/manifests/web/repo.pp create mode 100644 puppet/modules/git/manifests/web/repo/lighttpd.pp create mode 100644 puppet/modules/git/templates/web/config create mode 100644 puppet/modules/git/templates/web/lighttpd (limited to 'puppet/modules') diff --git a/puppet/modules/git/.gitrepo b/puppet/modules/git/.gitrepo new file mode 100644 index 00000000..5b10e73e --- /dev/null +++ b/puppet/modules/git/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_git + branch = master + commit = ba5dd8d5c8e09d521ff49f1ebc753601e449f828 + parent = 984375bab6546a7ef1e716402468a2f4cb6e1925 + cmdver = 0.3.0 diff --git a/puppet/modules/git/files/config/CentOS/git-daemon b/puppet/modules/git/files/config/CentOS/git-daemon new file mode 100644 index 00000000..a9b208c2 --- /dev/null +++ b/puppet/modules/git/files/config/CentOS/git-daemon @@ -0,0 +1,26 @@ +# git-daemon config file + +# location of the lockfile +#LOCKFILE=/var/lock/subsys/git-daemon + +# which directory to server +#GITDIR=/srv/git + +# do we serve vhosts? +# setting this to yes assumes that you +# have in $GITDIR per vhost to serve +# a subdirectory containing their repos. +# for example: +# - /srv/git/git.example.com +# - /srv/git/git.example.org +#GITVHOST=no + +# the user git-daemon should run with +#GITUSER=nobody + +# options for the daemon +#OPTIONS="--reuseaddr --verbose --detach" + +# location of the daemon +#GITDAEMON=/usr/bin/git-daemon + diff --git a/puppet/modules/git/files/config/CentOS/git-daemon.vhosts b/puppet/modules/git/files/config/CentOS/git-daemon.vhosts new file mode 100644 index 00000000..62bb9d4b --- /dev/null +++ b/puppet/modules/git/files/config/CentOS/git-daemon.vhosts @@ -0,0 +1,27 @@ +# git-daemon config file + +# location of the lockfile +#LOCKFILE=/var/lock/subsys/git-daemon + +# which directory to server +#GITDIR=/srv/git + +# do we serve vhosts? +# setting this to yes assumes that you +# have in $GITDIR per vhost to serve +# a subdirectory containing their repos. +# for example: +# - /srv/git/git.example.com +# - /srv/git/git.example.org +#GITVHOST=no +GITVHOST=yes + +# the user git-daemon should run with +#GITUSER=nobody + +# options for the daemon +#OPTIONS="--reuseaddr --verbose --detach" + +# location of the daemon +#GITDAEMON=/usr/bin/git-daemon + diff --git a/puppet/modules/git/files/config/Debian/git-daemon b/puppet/modules/git/files/config/Debian/git-daemon new file mode 100644 index 00000000..b25e1e7f --- /dev/null +++ b/puppet/modules/git/files/config/Debian/git-daemon @@ -0,0 +1,22 @@ +# Defaults for the git-daemon initscript + +# Set to yes to start git-daemon +RUN=yes + +# Set to the user and group git-daemon should run as +USER=nobody +GROUP=nogroup + +# Set the base path and the directory where the repositories are. +REPOSITORIES="/srv/git" + +# Provide a way to have custom setup. +# +# Note, when ADVANCED_OPTS is defined the REPOSITORIES setting is ignored, +# so take good care to specify exactly what git-daemon have to do. +# +# Here is an example from the man page: +#ADVANCED_OPTS="--verbose --export-all \ +# --interpolated-path=/pub/%IP/%D \ +# /pub/192.168.1.200/software \ +# /pub/10.10.220.23/software" diff --git a/puppet/modules/git/files/init.d/CentOS/git-daemon b/puppet/modules/git/files/init.d/CentOS/git-daemon new file mode 100644 index 00000000..aed20756 --- /dev/null +++ b/puppet/modules/git/files/init.d/CentOS/git-daemon @@ -0,0 +1,75 @@ +#!/bin/bash +# puppet Init script for running the git-daemon +# +# Author: Marcel Haerry +# +# chkconfig: - 98 02 +# +# description: Enables the git-daemon to serve various directories. By default it serves /srv/git +# processname: git-daemon +# config: /etc/sysconfig/git-daemon + +PATH=/usr/bin:/sbin:/bin:/usr/sbin +export PATH + +[ -f /etc/sysconfig/git-daemon ] && . /etc/sysconfig/git-daemon +lockfile=${LOCKFILE-/var/lock/subsys/git-daemon} +gitdir=${GITDIR-/srv/git} +gitvhost=${GITVHOST-no} +user=${GITUSER-nobody} +options=${OPTIONS-"--reuseaddr --verbose --detach"} +gitdaemon=${GITDAEMON-/usr/bin/git-daemon} +RETVAL=0 + +gitoptions="--user=${user} ${options}" +if [ $gitvhost = yes ]; then + gitoptions="${gitoptions} --interpolated-path=${gitdir}/%H/%D" +else + gitoptions="${gitoptions} --base-path=${gitdir}" +fi + +# Source function library. +. /etc/rc.d/init.d/functions + +start() { + echo -n $"Starting git-daemon: " + daemon $gitdaemon $gitoptions + RETVAL=$? + echo + [ $RETVAL = 0 ] && touch ${lockfile} + return $RETVAL +} + +stop() { + echo -n $"Stopping git-daemon: " + killproc $gitdaemon + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f ${lockfile} +} + +restart() { + stop + start +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + status) + status $gitdaemon + RETVAL=$? + ;; + *) + echo $"Usage: $0 {start|stop|status|restart}" + exit 1 +esac + +exit $RETVAL diff --git a/puppet/modules/git/files/init.d/Debian/git-daemon b/puppet/modules/git/files/init.d/Debian/git-daemon new file mode 100644 index 00000000..ab57c4a1 --- /dev/null +++ b/puppet/modules/git/files/init.d/Debian/git-daemon @@ -0,0 +1,151 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: git-daemon +# Required-Start: $network $remote_fs $syslog +# Required-Stop: $network $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: git-daemon service +# Description: git-daemon makes git repositories available via the git +# protocol. +### END INIT INFO + +# Author: Antonio Ospite +# +# Please remove the "Author" lines above and replace them +# with your own name if you copy and modify this script. + +# Do NOT "set -e" + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/lib/git-core +DESC="git-daemon service" +NAME=git-daemon +DAEMON=/usr/lib/git-core/$NAME +PIDFILE=/var/run/$NAME.pid +SCRIPTNAME=/etc/init.d/$NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Fallback options values, we use these when +# the /etc/default/git-daemon file does not exist +RUN=no +USER=git +GROUP=git +REPOSITORIES="/srv/git/" + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +# If ADVANCED_OPTS is empty, use a default setting +if [ "x$ADVANCED_OPTS" == "x" ]; +then + ADVANCED_OPTS="--base-path=$REPOSITORIES $REPOSITORIES" +fi + +DAEMON_ARGS="--syslog --reuseaddr \ + --user=$USER --group=$GROUP \ + $ADVANCED_OPTS" + + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --background --make-pidfile -- \ + $DAEMON_ARGS \ + || return 2 + + return 0 +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON + [ "$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + restart|force-reload) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 + exit 3 + ;; +esac + +: diff --git a/puppet/modules/git/files/web/gitweb.conf b/puppet/modules/git/files/web/gitweb.conf new file mode 100644 index 00000000..88226aaa --- /dev/null +++ b/puppet/modules/git/files/web/gitweb.conf @@ -0,0 +1,53 @@ +# The gitweb config file is a fragment of perl code. You can set variables +# using "our $variable = value"; text from "#" character until the end of a +# line is ignored. See perlsyn(1) man page for details. +# +# See /usr/share/doc/gitweb-*/README and /usr/share/doc/gitweb-*/INSTALL for +# more details and available configuration variables. + +# Set the path to git projects. This is an absolute filesystem path which will +# be prepended to the project path. +#our $projectroot = "/var/lib/git"; + +# Set the list of git base URLs used for URL to where fetch project from, i.e. +# the full URL is "$git_base_url/$project". By default this is empty +#our @git_base_url_list = qw(git://git.example.com +# ssh://git.example.com/var/lib/git); + +# Enable the 'blame' blob view, showing the last commit that modified +# each line in the file. This can be very CPU-intensive. Disabled by default +#$feature{'blame'}{'default'} = [1]; +# +# Allow projects to override the default setting via git config file. +# Example: gitweb.blame = 0|1; +#$feature{'blame'}{'override'} = 1; + +# Disable the 'snapshot' link, providing a compressed archive of any tree. This +# can potentially generate high traffic if you have large project. Enabled for +# .tar.gz snapshots by default. +# +# Value is a list of formats defined in %known_snapshot_formats that you wish +# to offer. +#$feature{'snapshot'}{'default'} = []; +# +# Allow projects to override the default setting via git config file. +# Example: gitweb.snapshot = tbz2,zip; (use "none" to disable) +#$feature{'snapshot'}{'override'} = 1; + +# Disable grep search, which will list the files in currently selected tree +# containing the given string. This can be potentially CPU-intensive, of +# course. Enabled by default. +#$feature{'grep'}{'default'} = [0]; +# +# Allow projects to override the default setting via git config file. +# Example: gitweb.grep = 0|1; +#$feature{'grep'}{'override'} = 1; + +# Disable the pickaxe search, which will list the commits that modified a given +# string in a file. This can be practical and quite faster alternative to +# 'blame', but still potentially CPU-intensive. Enabled by default. +#$feature{'pickaxe'}{'default'} = [0]; +# +# Allow projects to override the default setting via git config file. +# Example: gitweb.pickaxe = 0|1; +#$feature{'pickaxe'}{'override'} = 1; diff --git a/puppet/modules/git/files/xinetd.d/git b/puppet/modules/git/files/xinetd.d/git new file mode 100644 index 00000000..64c53e8b --- /dev/null +++ b/puppet/modules/git/files/xinetd.d/git @@ -0,0 +1,16 @@ +# default: off +# description: The git dæmon allows git repositories to be exported using +# the git:// protocol. + +service git +{ + disable = no + socket_type = stream + wait = no + user = nobody + server = /usr/bin/git-daemon + server_args = --base-path=/srv/git --export-all --user-path=public_git --syslog --inetd --verbose + log_on_failure += USERID +# xinetd doesn't do this by default. bug #195265 + flags = IPv6 +} diff --git a/puppet/modules/git/files/xinetd.d/git.disabled b/puppet/modules/git/files/xinetd.d/git.disabled new file mode 100644 index 00000000..dcfae918 --- /dev/null +++ b/puppet/modules/git/files/xinetd.d/git.disabled @@ -0,0 +1,16 @@ +# default: off +# description: The git dæmon allows git repositories to be exported using +# the git:// protocol. + +service git +{ + disable = yes + socket_type = stream + wait = no + user = nobody + server = /usr/bin/git-daemon + server_args = --base-path=/srv/git --export-all --user-path=public_git --syslog --inetd --verbose + log_on_failure += USERID +# xinetd doesn't do this by default. bug #195265 + flags = IPv6 +} diff --git a/puppet/modules/git/files/xinetd.d/git.vhosts b/puppet/modules/git/files/xinetd.d/git.vhosts new file mode 100644 index 00000000..98938206 --- /dev/null +++ b/puppet/modules/git/files/xinetd.d/git.vhosts @@ -0,0 +1,16 @@ +# default: off +# description: The git dæmon allows git repositories to be exported using +# the git:// protocol. + +service git +{ + disable = no + socket_type = stream + wait = no + user = nobody + server = /usr/bin/git-daemon + server_args = --interpolated-path=/srv/git/%H/%D --syslog --inetd --verbose + log_on_failure += USERID +# xinetd doesn't do this by default. bug #195265 + flags = IPv6 +} diff --git a/puppet/modules/git/manifests/base.pp b/puppet/modules/git/manifests/base.pp new file mode 100644 index 00000000..e6188390 --- /dev/null +++ b/puppet/modules/git/manifests/base.pp @@ -0,0 +1,7 @@ +class git::base { + + package { 'git': + ensure => present, + alias => 'git', + } +} diff --git a/puppet/modules/git/manifests/centos.pp b/puppet/modules/git/manifests/centos.pp new file mode 100644 index 00000000..96344756 --- /dev/null +++ b/puppet/modules/git/manifests/centos.pp @@ -0,0 +1,2 @@ +class git::centos inherits git::base { +} diff --git a/puppet/modules/git/manifests/changes.pp b/puppet/modules/git/manifests/changes.pp new file mode 100644 index 00000000..71112051 --- /dev/null +++ b/puppet/modules/git/manifests/changes.pp @@ -0,0 +1,33 @@ +# Usage +# git::changes { name: +# cwd => "/path/to/git/" +# user => "me", +# ensure => {*assume-unchanged*, tracked} +# } +# + +define git::changes ( $cwd, $user, $ensure='assume-unchanged' ) { + + case $ensure { + default: { err ( "unknown ensure value '${ensure}'" ) } + + assume-unchanged: { + exec { "assume-unchanged ${name}": + command => "/usr/bin/git update-index --assume-unchanged ${name}", + cwd => $cwd, + user => $user, + unless => "/usr/bin/git ls-files -v | grep '^[ch] ${name}'", + } + } + + tracked: { + exec { "track changes ${name}": + command => "/usr/bin/git update-index --no-assume-unchanged ${name}", + cwd => $cwd, + user => $user, + onlyif => "/usr/bin/git ls-files -v | grep '^[ch] ${name}'", + } + } + } +} + diff --git a/puppet/modules/git/manifests/clone.pp b/puppet/modules/git/manifests/clone.pp new file mode 100644 index 00000000..29f0b2b3 --- /dev/null +++ b/puppet/modules/git/manifests/clone.pp @@ -0,0 +1,60 @@ +# submodules: Whether we should initialize and update +# submodules as well +# Default: false +# clone_before: before which resources a cloning should +# happen. This is releveant in combination +# with submodules as the exec of submodules +# requires the `cwd` and you might get a +# dependency cycle if you manage $projectroot +# somewhere else. +define git::clone( + $ensure = present, + $git_repo, + $projectroot, + $submodules = false, + $clone_before = 'absent', + $cloneddir_user='root', + $cloneddir_group='0', + $cloneddir_restrict_mode=true +){ + case $ensure { + absent: { + exec{"rm -rf $projectroot": + onlyif => "test -d $projectroot", + } + } + default: { + require ::git + exec {"git-clone_${name}": + command => "git clone --no-hardlinks ${git_repo} ${projectroot}", + creates => "${projectroot}/.git", + user => root, + notify => Exec["git-clone-chown_${name}"], + } + if $clone_before != 'absent' { + Exec["git-clone_${name}"]{ + before => $clone_before, + } + } + if $submodules { + exec{"git-submodules_${name}": + command => "git submodule init && git submodule update", + cwd => $projectroot, + refreshonly => true, + subscribe => Exec["git-clone_${name}"], + } + } + exec {"git-clone-chown_${name}": + command => "chown -R ${cloneddir_user}:${cloneddir_group} ${projectroot};chmod -R og-rwx ${projectroot}/.git", + refreshonly => true + } + if $cloneddir_restrict_mode { + exec {"git-clone-chmod_${name}": + command => "chmod -R o-rwx ${projectroot}", + refreshonly => true, + subscribe => Exec["git-clone_${name}"], + } + } + } + } +} diff --git a/puppet/modules/git/manifests/daemon.pp b/puppet/modules/git/manifests/daemon.pp new file mode 100644 index 00000000..1e85ff84 --- /dev/null +++ b/puppet/modules/git/manifests/daemon.pp @@ -0,0 +1,17 @@ +class git::daemon { + + include git + + case $operatingsystem { + centos: { include git::daemon::centos } + debian: { include git::daemon::base } + } + + if $use_shorewall { + include shorewall::rules::gitdaemon + } + + if $use_nagios { + nagios::service { "git-daemon": check_command => "check_git!${fqdn}"; } + } +} diff --git a/puppet/modules/git/manifests/daemon/base.pp b/puppet/modules/git/manifests/daemon/base.pp new file mode 100644 index 00000000..6a03d4fd --- /dev/null +++ b/puppet/modules/git/manifests/daemon/base.pp @@ -0,0 +1,31 @@ +class git::daemon::base inherits git::base { + + file { 'git-daemon_initscript': + source => [ "puppet://$server/modules/site_git/init.d/${fqdn}/git-daemon", + "puppet://$server/modules/site_git/init.d/${operatingsystem}/git-daemon", + "puppet://$server/modules/site_git/init.d/git-daemon", + "puppet://$server/modules/git/init.d/${operatingsystem}/git-daemon", + "puppet://$server/modules/git/init.d/git-daemon" ], + require => Package['git'], + path => "/etc/init.d/git-daemon", + owner => root, group => 0, mode => 0755; + } + + file { 'git-daemon_config': + source => [ "puppet://$server/modules/site_git/config/${fqdn}/git-daemon", + "puppet://$server/modules/site_git/config/${operatingsystem}/git-daemon", + "puppet://$server/modules/site_git/config/git-daemon", + "puppet://$server/modules/git/config/${operatingsystem}/git-daemon", + "puppet://$server/modules/git/config/git-daemon" ], + require => Package['git'], + path => "/etc/default/git-daemon", + owner => root, group => 0, mode => 0644; + } + + service { 'git-daemon': + ensure => running, + enable => true, + hasstatus => true, + require => [ File['git-daemon_initscript'], File['git-daemon_config'] ], + } +} diff --git a/puppet/modules/git/manifests/daemon/centos.pp b/puppet/modules/git/manifests/daemon/centos.pp new file mode 100644 index 00000000..e276259d --- /dev/null +++ b/puppet/modules/git/manifests/daemon/centos.pp @@ -0,0 +1,19 @@ +class git::daemon::centos inherits git::daemon::base { + + package { 'git-daemon': + ensure => installed, + require => Package['git'], + alias => 'git-daemon', + } + + File['git-daemon_initscript'] { + path => '/etc/init.d/git-daemon', + require +> Package['git-daemon'], + } + + File['git-daemon_config'] { + path => '/etc/init.d/git-daemon', + require +> Package['git-daemon'], + } + +} diff --git a/puppet/modules/git/manifests/daemon/disable.pp b/puppet/modules/git/manifests/daemon/disable.pp new file mode 100644 index 00000000..c044e962 --- /dev/null +++ b/puppet/modules/git/manifests/daemon/disable.pp @@ -0,0 +1,33 @@ +class git::daemon::disable inherits git::daemon::base { + + if defined(Package['git-daemon']) { + Package['git-daemon'] { + ensure => absent, + } + } + + File['git-daemon_initscript'] { + ensure => absent, + } + + File['git-daemon_config'] { + ensure => absent, + } + + Service['git-daemon'] { + ensure => stopped, + enable => false, + require => undef, + before => File['git-daemon_initscript'], + } + + if $use_shorewall { + include shorewall::rules::gitdaemon::absent + } + + if $use_nagios { + nagios::service { "git-daemon": check_command => "check_git!${fqdn}", ensure => absent; } + } +} + + diff --git a/puppet/modules/git/manifests/daemon/vhosts.pp b/puppet/modules/git/manifests/daemon/vhosts.pp new file mode 100644 index 00000000..9591330f --- /dev/null +++ b/puppet/modules/git/manifests/daemon/vhosts.pp @@ -0,0 +1,10 @@ +class git::daemon::vhosts inherits git::daemon { + + File['git-daemon_config']{ + source => [ "puppet://$server/modules/site_git/config/${fqdn}/git-daemon.vhosts", + "puppet://$server/modules/site_git/config/${operatingsystem}/git-daemon.vhosts", + "puppet://$server/modules/site_git/config/git-daemon.vhosts", + "puppet://$server/modules/git/config/${operatingsystem}/git-daemon.vhosts", + "puppet://$server/modules/git/config/git-daemon.vhosts" ], + } +} diff --git a/puppet/modules/git/manifests/debian.pp b/puppet/modules/git/manifests/debian.pp new file mode 100644 index 00000000..2e63d692 --- /dev/null +++ b/puppet/modules/git/manifests/debian.pp @@ -0,0 +1,6 @@ +class git::debian inherits git::base { + + Package['git'] { + name => 'git-core', + } +} diff --git a/puppet/modules/git/manifests/init.pp b/puppet/modules/git/manifests/init.pp new file mode 100644 index 00000000..4693af75 --- /dev/null +++ b/puppet/modules/git/manifests/init.pp @@ -0,0 +1,25 @@ +# +# git module +# +# Copyright 2008, Puzzle ITC +# Marcel Härry haerry+puppet(at)puzzle.ch +# Simon Josi josi+puppet(at)puzzle.ch +# +# This program is free software; you can redistribute +# it and/or modify it under the terms of the GNU +# General Public License version 3 as published by +# the Free Software Foundation. +# + +class git { + + case $operatingsystem { + debian: { include git::debian } + centos: { include git::centos } + } + + if $use_shorewall { + include shorewall::rules::out::git + } + +} diff --git a/puppet/modules/git/manifests/svn.pp b/puppet/modules/git/manifests/svn.pp new file mode 100644 index 00000000..ea934749 --- /dev/null +++ b/puppet/modules/git/manifests/svn.pp @@ -0,0 +1,10 @@ +# manifests/svn.pp + +class git::svn { + include ::git + include subversion + + package { 'git-svn': + require => [ Package['git'], Package['subversion'] ], + } +} diff --git a/puppet/modules/git/manifests/web.pp b/puppet/modules/git/manifests/web.pp new file mode 100644 index 00000000..3cf5139e --- /dev/null +++ b/puppet/modules/git/manifests/web.pp @@ -0,0 +1,20 @@ +class git::web { + include git + + package { 'gitweb': + ensure => present, + require => Package['git'], + } + + file { '/etc/gitweb.d': + ensure => directory, + owner => root, group => 0, mode => 0755; + } + file { '/etc/gitweb.conf': + source => [ "puppet:///modules/site_git/web/${fqdn}/gitweb.conf", + "puppet:///modules/site_git/web/gitweb.conf", + "puppet:///modules/git/web/gitweb.conf" ], + require => Package['gitweb'], + owner => root, group => 0, mode => 0644; + } +} diff --git a/puppet/modules/git/manifests/web/absent.pp b/puppet/modules/git/manifests/web/absent.pp new file mode 100644 index 00000000..4d0dba33 --- /dev/null +++ b/puppet/modules/git/manifests/web/absent.pp @@ -0,0 +1,17 @@ +class git::web::absent { + + package { 'gitweb': + ensure => absent, + } + + file { '/etc/gitweb.d': + ensure => absent, + purge => true, + force => true, + recurse => true, + } + file { '/etc/gitweb.conf': + ensure => absent, + } +} + diff --git a/puppet/modules/git/manifests/web/lighttpd.pp b/puppet/modules/git/manifests/web/lighttpd.pp new file mode 100644 index 00000000..980e23c0 --- /dev/null +++ b/puppet/modules/git/manifests/web/lighttpd.pp @@ -0,0 +1,7 @@ +class git::web::lighttpd { + include ::lighttpd + + lighttpd::config::file{'lighttpd-gitweb': + content => 'global { server.modules += ("mod_rewrite", "mod_redirect", "mod_alias", "mod_setenv", "mod_cgi" ) }', + } +} diff --git a/puppet/modules/git/manifests/web/repo.pp b/puppet/modules/git/manifests/web/repo.pp new file mode 100644 index 00000000..da6f74f0 --- /dev/null +++ b/puppet/modules/git/manifests/web/repo.pp @@ -0,0 +1,56 @@ +# domain: the domain under which this repo will be avaiable +# projectroot: where the git repos are listened +# projects_list: which repos to export +# +# logmode: +# - default: Do normal logging including ips +# - anonym: Don't log ips +define git::web::repo( + $ensure = 'present', + $projectroot = 'absent', + $projects_list = 'absent', + $logmode = 'default', + $sitename = 'absent' +){ + if ($ensure == 'present') and (($projects_list == 'absent') or ($projectroot == 'absent')){ + fail("You have to pass \$project_list and \$projectroot for ${name} if it should be present!") + } + if $ensure == 'present' { include git::web } + $gitweb_url = $name + case $gitweb_sitename { + 'absent': { $gitweb_sitename = "${name} git repository" } + default: { $gitweb_sitename = $sitename } + } + $gitweb_config = "/etc/gitweb.d/${name}.conf" + file{"${gitweb_config}": } + if $ensure == 'present' { + File["${gitweb_config}"]{ + content => template("git/web/config") + } + } else { + File["${gitweb_config}"]{ + ensure => absent, + } + } + case $gitweb_webserver { + 'lighttpd': { + git::web::repo::lighttpd{$name: + ensure => $ensure, + logmode => $logmode, + gitweb_url => $gitweb_url, + gitweb_config => $gitweb_config, + } + } + 'apache': { + apache::vhost::gitweb{$gitweb_url: + logmode => $logmode, + ensure => $ensure, + } + } + default: { + if ($ensure == 'present') { + fail("no supported \$gitweb_webserver defined on ${fqdn}, so can't do git::web::repo: ${name}") + } + } + } +} diff --git a/puppet/modules/git/manifests/web/repo/lighttpd.pp b/puppet/modules/git/manifests/web/repo/lighttpd.pp new file mode 100644 index 00000000..11cee4ce --- /dev/null +++ b/puppet/modules/git/manifests/web/repo/lighttpd.pp @@ -0,0 +1,16 @@ +# logmode: +# - default: Do normal logging including ips +# - anonym: Don't log ips +define git::web::repo::lighttpd( + $ensure = 'present', + $gitweb_url, + $logmode = 'default', + $gitweb_config +){ + if $ensure == 'present' { include git::web::lighttpd } + + lighttpd::vhost::file{$name: + ensure => $ensure, + content => template('git/web/lighttpd'); + } +} diff --git a/puppet/modules/git/templates/web/config b/puppet/modules/git/templates/web/config new file mode 100644 index 00000000..5286f6a6 --- /dev/null +++ b/puppet/modules/git/templates/web/config @@ -0,0 +1,31 @@ +# Include the global configuration, if found. +do "/etc/gitweb.conf" if -e "/etc/gitweb.conf"; + +# Point to projects.list file generated by gitosis. +# Here gitosis manages the user "git", who has a +# home directory of /srv/example.com/git +$projects_list = "<%= projects_list %>"; + +# Where the actual repositories are located. +$projectroot = "<%= projectroot %>"; + +# By default, gitweb will happily let people browse any repository +# they guess the name of. This may or may not be what you wanted. I +# choose to allow gitweb to show only repositories that git-daemon +# is already sharing anonymously. +$export_ok = "git-daemon-export-ok"; + +# Alternatively, you could set these, to allow exactly the things in +# projects.list, which in this case is the repos with gitweb=yes +# in gitosis.conf. This means you don't need daemon=yes, but you +# can't have repositories hidden but browsable if you know the name. +# And note gitweb already allows downloading the full repository, +# so you might as well serve git-daemon too. +# $export_ok = ""; +# $strict_export = "true"; + +# A list of base urls where all the repositories can be cloned from. +# Easier than having per-repository cloneurl files. +@git_base_url_list = ('git://<%= gitweb_url %>'); + +$GITWEB_SITENAME = "<%= gitweb_sitename %>" diff --git a/puppet/modules/git/templates/web/lighttpd b/puppet/modules/git/templates/web/lighttpd new file mode 100644 index 00000000..cf244691 --- /dev/null +++ b/puppet/modules/git/templates/web/lighttpd @@ -0,0 +1,21 @@ +$HTTP["host"] == "<%= gitweb_url %>" { + url.redirect += ( + "^$" => "/", + ) + + <%- if logmode.to_s == 'anonym' -%> + accesslog.format = "127.0.0.1 %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" + <%- end -%> + + alias.url += ( + "/static/gitweb.css" => "/var/www/git/static/gitweb.css", + "/static/git-logo.png" => "/var/www/git/static/git-logo.png", + "/static/git-favicon.png" => "/var/www/git/static/git-favicon.png", + "/" => "/var/www/git/gitweb.cgi", + ) + + setenv.add-environment = ( + "GITWEB_CONFIG" => "<%= gitweb_config %>" + ) + cgi.assign = ( ".cgi" => "" ) +} -- cgit v1.2.3 From 6083b23278927189de58c11bbb5bc7d93ccced24 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:36 -0400 Subject: git subrepo clone https://leap.se/git/puppet_common puppet/modules/common subrepo: subdir: "puppet/modules/common" merged: "ae14962" upstream: origin: "https://leap.se/git/puppet_common" branch: "master" commit: "ae14962" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I82a15d5ab5c4e8f689f73de4e5ae97557f39b6fb --- puppet/modules/common/.gitrepo | 11 + puppet/modules/common/LICENSE | 674 +++++++++++++++++++++ puppet/modules/common/README | 44 ++ .../common/lib/puppet/parser/functions/basename.rb | 22 + .../common/lib/puppet/parser/functions/dirname.rb | 22 + .../lib/puppet/parser/functions/get_default.rb | 15 + .../common/lib/puppet/parser/functions/hostname.rb | 13 + .../parser/functions/multi_source_template.rb | 29 + .../lib/puppet/parser/functions/prefix_with.rb | 9 + .../lib/puppet/parser/functions/re_escape.rb | 7 + .../lib/puppet/parser/functions/slash_escape.rb | 7 + .../lib/puppet/parser/functions/substitute.rb | 20 + .../common/lib/puppet/parser/functions/tfile.rb | 19 + puppet/modules/common/manifests/module_dir.pp | 34 ++ puppet/modules/common/manifests/module_file.pp | 37 ++ puppet/modules/common/manifests/moduledir.pp | 18 + .../modules/common/manifests/moduledir/common.pp | 4 + puppet/modules/common/spec/spec.opts | 6 + puppet/modules/common/spec/spec_helper.rb | 16 + .../common/spec/unit/parser/functions/tfile.rb | 54 ++ 20 files changed, 1061 insertions(+) create mode 100644 puppet/modules/common/.gitrepo create mode 100644 puppet/modules/common/LICENSE create mode 100644 puppet/modules/common/README create mode 100644 puppet/modules/common/lib/puppet/parser/functions/basename.rb create mode 100644 puppet/modules/common/lib/puppet/parser/functions/dirname.rb create mode 100644 puppet/modules/common/lib/puppet/parser/functions/get_default.rb create mode 100644 puppet/modules/common/lib/puppet/parser/functions/hostname.rb create mode 100644 puppet/modules/common/lib/puppet/parser/functions/multi_source_template.rb create mode 100644 puppet/modules/common/lib/puppet/parser/functions/prefix_with.rb create mode 100644 puppet/modules/common/lib/puppet/parser/functions/re_escape.rb create mode 100644 puppet/modules/common/lib/puppet/parser/functions/slash_escape.rb create mode 100644 puppet/modules/common/lib/puppet/parser/functions/substitute.rb create mode 100644 puppet/modules/common/lib/puppet/parser/functions/tfile.rb create mode 100644 puppet/modules/common/manifests/module_dir.pp create mode 100644 puppet/modules/common/manifests/module_file.pp create mode 100644 puppet/modules/common/manifests/moduledir.pp create mode 100644 puppet/modules/common/manifests/moduledir/common.pp create mode 100644 puppet/modules/common/spec/spec.opts create mode 100644 puppet/modules/common/spec/spec_helper.rb create mode 100644 puppet/modules/common/spec/unit/parser/functions/tfile.rb (limited to 'puppet/modules') diff --git a/puppet/modules/common/.gitrepo b/puppet/modules/common/.gitrepo new file mode 100644 index 00000000..7d45d07b --- /dev/null +++ b/puppet/modules/common/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_common + branch = master + commit = ae149624f9bc551865b93b9b7155af2de8deeb71 + parent = 1f231f09a9b6911b2ca57ac82235c6028922d54f + cmdver = 0.3.0 diff --git a/puppet/modules/common/LICENSE b/puppet/modules/common/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/puppet/modules/common/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/puppet/modules/common/README b/puppet/modules/common/README new file mode 100644 index 00000000..e6df7663 --- /dev/null +++ b/puppet/modules/common/README @@ -0,0 +1,44 @@ +Common Module +------------- + +The common module installs various functions that are required by other +modules. This module should be installed before any of the other module. + +! Upgrade Notice ! + +The 'append_if_no_such_line' define has been replaced with the 'line' define. If +you are using 'append_if_no_such_line' anywhere in your manifests, you will need +to transition to 'line' before upgrading to this version of the common +module. The 'line' define is a drop-in replacement and essentially equivalent, +so the transition is quite easy, you should only simply need to change the name +in your manifests. + +To use this module, follow these directions: + +1. Your modules directory will need all the files included in this + repository placed under a directory called "common" + +2. Add the following line to manifests/site.pp: + + import "modules.pp" + +3. Add the following line to manifests/modules.pp: + + import "common" + + +Original author: David Schmitt (mailto:david@dasz.at) +Copyright:: Copyright (c) 2007-2009 dasz.at OG +License:: 3-clause BSD + +Additional authors: +Copyright (C) 2007 David Schmitt +Copyright 2008-2011, admin(at)immerda.ch +Copyright 2008, Puzzle ITC GmbH + Marcel Härry haerry+puppet(at)puzzle.ch + Simon Josi josi+puppet(at)puzzle.ch +Copyright 2009-2011, Riseup Labs + Pietro Ferrari + Micah Anderson +Copyright (C) 2007 Antoine Beaupre +Copyright (c) 2011 intrigeri - intrigeri(at)boum.org \ No newline at end of file diff --git a/puppet/modules/common/lib/puppet/parser/functions/basename.rb b/puppet/modules/common/lib/puppet/parser/functions/basename.rb new file mode 100644 index 00000000..dc725375 --- /dev/null +++ b/puppet/modules/common/lib/puppet/parser/functions/basename.rb @@ -0,0 +1,22 @@ +# This function has two modes of operation: +# +# basename(string) : string +# +# Returns the last component of the filename given as argument, which must be +# formed using forward slashes ("/") regardless of the separator used on the +# local file system. +# +# basename(string[]) : string[] +# +# Returns an array of strings with the basename of each item from the argument. +# +module Puppet::Parser::Functions + newfunction(:basename, :type => :rvalue) do |args| + if args[0].is_a?(Array) + args.collect do |a| File.basename(a) end + else + File.basename(args[0]) + end + end +end + diff --git a/puppet/modules/common/lib/puppet/parser/functions/dirname.rb b/puppet/modules/common/lib/puppet/parser/functions/dirname.rb new file mode 100644 index 00000000..ea0d50b4 --- /dev/null +++ b/puppet/modules/common/lib/puppet/parser/functions/dirname.rb @@ -0,0 +1,22 @@ +# This function has two modes of operation: +# +# dirname(string) : string +# +# Returns all components of the filename given as argument except the last +# one. The filename must be formed using forward slashes (``/..) regardless of +# the separator used on the local file system. +# +# dirname(string[]) : string[] +# +# Returns an array of strings with the basename of each item from the argument. +# +module Puppet::Parser::Functions + newfunction(:dirname, :type => :rvalue) do |args| + if args[0].is_a?(Array) + args.collect do |a| File.dirname(a) end + else + File.dirname(args[0]) + end + end +end + diff --git a/puppet/modules/common/lib/puppet/parser/functions/get_default.rb b/puppet/modules/common/lib/puppet/parser/functions/get_default.rb new file mode 100644 index 00000000..3f4359bd --- /dev/null +++ b/puppet/modules/common/lib/puppet/parser/functions/get_default.rb @@ -0,0 +1,15 @@ +# get_default($value, $default) : $value +# +# return $value || $default. +module Puppet::Parser::Functions + newfunction(:get_default, :type => :rvalue) do |args| + value = nil + args.each { |x| + if ! x.nil? and x.length > 0 + value = x + break + end + } + return value + end +end diff --git a/puppet/modules/common/lib/puppet/parser/functions/hostname.rb b/puppet/modules/common/lib/puppet/parser/functions/hostname.rb new file mode 100644 index 00000000..7bc477f2 --- /dev/null +++ b/puppet/modules/common/lib/puppet/parser/functions/hostname.rb @@ -0,0 +1,13 @@ +# get an uniq array of ipaddresses for a hostname +require 'resolv' + +module Puppet::Parser::Functions + newfunction(:hostname, :type => :rvalue) do |args| + res = Array.new + Resolv::DNS.new.each_address(args[0]){ |addr| + res << addr + } + res.uniq + end +end + diff --git a/puppet/modules/common/lib/puppet/parser/functions/multi_source_template.rb b/puppet/modules/common/lib/puppet/parser/functions/multi_source_template.rb new file mode 100644 index 00000000..e0753205 --- /dev/null +++ b/puppet/modules/common/lib/puppet/parser/functions/multi_source_template.rb @@ -0,0 +1,29 @@ +module Puppet::Parser::Functions + require 'erb' + + newfunction(:multi_source_template, :type => :rvalue) do |args| + contents = nil + environment = compiler.environment + sources = args + + sources.each do |file| + Puppet.debug("Looking for #{file} in #{environment}") + if filename = Puppet::Parser::Files.find_template(file, environment.to_s) + wrapper = Puppet::Parser::TemplateWrapper.new(self) + wrapper.file = file + + begin + contents = wrapper.result + rescue => detail + raise Puppet::ParseError, "Failed to parse template %s: %s" % [file, detail] + end + + break + end + end + + raise Puppet::ParseError, "multi_source_template: No match found for files: #{sources.join(', ')}" if contents == nil + + contents + end +end diff --git a/puppet/modules/common/lib/puppet/parser/functions/prefix_with.rb b/puppet/modules/common/lib/puppet/parser/functions/prefix_with.rb new file mode 100644 index 00000000..6e64a4a8 --- /dev/null +++ b/puppet/modules/common/lib/puppet/parser/functions/prefix_with.rb @@ -0,0 +1,9 @@ +# prefix arguments 2..n with first argument + +module Puppet::Parser::Functions + newfunction(:prefix_with, :type => :rvalue) do |args| + prefix = args.shift + args.collect {|v| "%s%s" % [prefix, v] } + end +end + diff --git a/puppet/modules/common/lib/puppet/parser/functions/re_escape.rb b/puppet/modules/common/lib/puppet/parser/functions/re_escape.rb new file mode 100644 index 00000000..7bee90a8 --- /dev/null +++ b/puppet/modules/common/lib/puppet/parser/functions/re_escape.rb @@ -0,0 +1,7 @@ +# apply ruby regexp escaping to a string +module Puppet::Parser::Functions + newfunction(:re_escape, :type => :rvalue) do |args| + Regexp.escape(args[0]) + end +end + diff --git a/puppet/modules/common/lib/puppet/parser/functions/slash_escape.rb b/puppet/modules/common/lib/puppet/parser/functions/slash_escape.rb new file mode 100644 index 00000000..04d3b95e --- /dev/null +++ b/puppet/modules/common/lib/puppet/parser/functions/slash_escape.rb @@ -0,0 +1,7 @@ +# escape slashes in a String +module Puppet::Parser::Functions + newfunction(:slash_escape, :type => :rvalue) do |args| + args[0].gsub(/\//, '\\/') + end +end + diff --git a/puppet/modules/common/lib/puppet/parser/functions/substitute.rb b/puppet/modules/common/lib/puppet/parser/functions/substitute.rb new file mode 100644 index 00000000..4c97def3 --- /dev/null +++ b/puppet/modules/common/lib/puppet/parser/functions/substitute.rb @@ -0,0 +1,20 @@ +# subsititute($string, $regex, $replacement) : $string +# subsititute($string[], $regex, $replacement) : $string[] +# +# Replace all ocurrences of $regex in $string by $replacement. +# $regex is interpreted as Ruby regular expression. +# +# For long-term portability it is recommended to refrain from using Ruby's +# extended RE features. +module Puppet::Parser::Functions + newfunction(:substitute, :type => :rvalue) do |args| + if args[0].is_a?(Array) + args[0].collect do |val| + val.gsub(/#{args[1]}/, args[2]) + end + else + args[0].gsub(/#{args[1]}/, args[2]) + end + end +end + diff --git a/puppet/modules/common/lib/puppet/parser/functions/tfile.rb b/puppet/modules/common/lib/puppet/parser/functions/tfile.rb new file mode 100644 index 00000000..acb6609b --- /dev/null +++ b/puppet/modules/common/lib/puppet/parser/functions/tfile.rb @@ -0,0 +1,19 @@ +Puppet::Parser::Functions::newfunction( + :tfile, + :type => :rvalue, + :doc => "Returns the content of a file. If the file or the path does not + yet exist, it will create the path and touch the file." +) do |args| + raise Puppet::ParseError, 'tfile() needs one argument' if args.length != 1 + path = args.to_a.first + unless File.exists?(path) + dir = File.dirname(path) + unless File.directory?(dir) + require 'fileutils' + FileUtils.mkdir_p(dir, :mode => 0700) + end + require 'fileutils' + FileUtils.touch(path) + end + File.read(path) +end diff --git a/puppet/modules/common/manifests/module_dir.pp b/puppet/modules/common/manifests/module_dir.pp new file mode 100644 index 00000000..2420da94 --- /dev/null +++ b/puppet/modules/common/manifests/module_dir.pp @@ -0,0 +1,34 @@ +# common/manifests/modules_dir.pp -- create a default directory +# for storing module specific information +# +# Copyright (C) 2007 David Schmitt +# See LICENSE for the full license granted to you. + +# A module_dir is a storage place for all the stuff a module might want to +# store. According to the FHS, this should go to /var/lib. Since this is a part +# of puppet, the full path is /var/lib/puppet/modules/${name}. Every module +# should # prefix its module_dirs with its name. +# +# Usage: +# include common::moduledir +# module_dir { ["common", "common/dir1", "common/dir2" ]: } +# +# You may refer to a file in module_dir by using : +# file { "${common::moduledir::module_dir_path}/somedir/somefile": } +define common::module_dir( + $owner = root, + $group = 0, + $mode = 0644 +) { + include common::moduledir + file { + "${common::moduledir::module_dir_path}/${name}": + ensure => directory, + recurse => true, + purge => true, + force => true, + owner => $owner, + group => $group, + mode => $mode; + } +} diff --git a/puppet/modules/common/manifests/module_file.pp b/puppet/modules/common/manifests/module_file.pp new file mode 100644 index 00000000..c1070bcf --- /dev/null +++ b/puppet/modules/common/manifests/module_file.pp @@ -0,0 +1,37 @@ +# common/manifests/module_file.pp -- use a modules_dir to store module +# specific files +# +# Copyright (C) 2007 David Schmitt +# See LICENSE for the full license granted to you. + +# Put a file into module-local storage. +# +# Usage: +# common::module_file { "module/file": +# source => "puppet:///...", +# mode => 644, # default +# owner => root, # default +# group => 0, # default +# } +define common::module_file ( + $ensure = present, + $source = undef, + $owner = root, + $group = 0, + $mode = 0644 +){ + include common::moduledir + file { + "${common::moduledir::module_dir_path}/${name}": + ensure => $ensure, + } + + if $ensure != 'absent' { + File["${common::moduledir::module_dir_path}/${name}"]{ + source => $source, + owner => $owner, + group => $group, + mode => $mode, + } + } +} diff --git a/puppet/modules/common/manifests/moduledir.pp b/puppet/modules/common/manifests/moduledir.pp new file mode 100644 index 00000000..f779085b --- /dev/null +++ b/puppet/modules/common/manifests/moduledir.pp @@ -0,0 +1,18 @@ +# setup root for module_dirs +class common::moduledir { + # Use this variable to reference the base path. Thus you are safe from any + # changes. + $module_dir_path = '/var/lib/puppet/modules' + + # Module programmers can use /var/lib/puppet/modules/$modulename to save + # module-local data, e.g. for constructing config files + file{$module_dir_path: + ensure => directory, + recurse => true, + purge => true, + force => true, + owner => root, + group => 0, + mode => '0755'; + } +} diff --git a/puppet/modules/common/manifests/moduledir/common.pp b/puppet/modules/common/manifests/moduledir/common.pp new file mode 100644 index 00000000..e74c601e --- /dev/null +++ b/puppet/modules/common/manifests/moduledir/common.pp @@ -0,0 +1,4 @@ +# setup a common dir +class common::moduledir::common{ + common::module_dir{'common': } +} diff --git a/puppet/modules/common/spec/spec.opts b/puppet/modules/common/spec/spec.opts new file mode 100644 index 00000000..91cd6427 --- /dev/null +++ b/puppet/modules/common/spec/spec.opts @@ -0,0 +1,6 @@ +--format +s +--colour +--loadby +mtime +--backtrace diff --git a/puppet/modules/common/spec/spec_helper.rb b/puppet/modules/common/spec/spec_helper.rb new file mode 100644 index 00000000..6ba62e11 --- /dev/null +++ b/puppet/modules/common/spec/spec_helper.rb @@ -0,0 +1,16 @@ +require 'pathname' +dir = Pathname.new(__FILE__).parent +$LOAD_PATH.unshift(dir, dir + 'lib', dir + '../lib') +require 'puppet' +gem 'rspec', '>= 1.2.9' +require 'spec/autorun' + +Dir[File.join(File.dirname(__FILE__), 'support', '*.rb')].each do |support_file| + require support_file +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/puppet/modules/common/spec/unit/parser/functions/tfile.rb b/puppet/modules/common/spec/unit/parser/functions/tfile.rb new file mode 100644 index 00000000..5c8f636e --- /dev/null +++ b/puppet/modules/common/spec/unit/parser/functions/tfile.rb @@ -0,0 +1,54 @@ +#! /usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' +require 'mocha' + +describe "the tfile function" do + + before :each do + @scope = Puppet::Parser::Scope.new + end + + it "should exist" do + Puppet::Parser::Functions.function("tfile").should == "function_tfile" + end + + it "should raise a ParseError if there is less than 1 arguments" do + lambda { @scope.function_tfile([]) }.should( raise_error(Puppet::ParseError)) + end + + it "should raise a ParseError if there is more than 1 arguments" do + lambda { @scope.function_tfile(["bar", "gazonk"]) }.should( raise_error(Puppet::ParseError)) + end + + describe "when executed properly" do + + before :each do + File.stubs(:read).with('/some_path/aa').returns("foo1\nfoo2\n") + end + + it "should return the content of the file" do + File.stubs(:exists?).with('/some_path/aa').returns(true) + result = @scope.function_tfile(['/some_path/aa']) + result.should == "foo1\nfoo2\n" + end + + it "should touch a file if it does not exist" do + File.stubs(:exists?).with('/some_path/aa').returns(false) + File.stubs(:directory?).with('/some_path').returns(true) + FileUtils.expects(:touch).with('/some_path/aa') + result = @scope.function_tfile(['/some_path/aa']) + result.should == "foo1\nfoo2\n" + end + + it "should create the path if it does not exist" do + File.stubs(:exists?).with('/some_path/aa').returns(false) + File.stubs(:directory?).with('/some_path').returns(false) + FileUtils.expects(:mkdir_p).with("/some_path",:mode => 0700) + FileUtils.expects(:touch).with('/some_path/aa') + result = @scope.function_tfile(['/some_path/aa']) + result.should == "foo1\nfoo2\n" + end + end + +end -- cgit v1.2.3 From 6209061fd112fed1715676abb7b6ae4697f21d83 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:51 -0400 Subject: git subrepo clone https://leap.se/git/puppet_shorewall puppet/modules/shorewall subrepo: subdir: "puppet/modules/shorewall" merged: "06e89ed" upstream: origin: "https://leap.se/git/puppet_shorewall" branch: "master" commit: "06e89ed" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: Ief531c1b951e9a1573d31bd9718cc5df11706af5 --- puppet/modules/shorewall/.gitrepo | 11 + puppet/modules/shorewall/LICENSE | 674 +++++++++++++++++++++ puppet/modules/shorewall/README.md | 224 +++++++ .../shorewall/files/boilerplate/blacklist.footer | 1 + .../shorewall/files/boilerplate/blacklist.header | 10 + .../shorewall/files/boilerplate/clear.footer | 1 + .../shorewall/files/boilerplate/clear.header | 13 + .../shorewall/files/boilerplate/continue.footer | 1 + .../shorewall/files/boilerplate/continue.header | 14 + .../shorewall/files/boilerplate/hosts.footer | 1 + .../shorewall/files/boilerplate/hosts.header | 9 + .../shorewall/files/boilerplate/init.footer | 1 + .../shorewall/files/boilerplate/init.header | 13 + .../shorewall/files/boilerplate/initdone.footer | 1 + .../shorewall/files/boilerplate/initdone.header | 14 + .../shorewall/files/boilerplate/interfaces.footer | 1 + .../shorewall/files/boilerplate/interfaces.header | 10 + .../shorewall/files/boilerplate/maclog.footer | 1 + .../shorewall/files/boilerplate/maclog.header | 14 + .../shorewall/files/boilerplate/mangle.footer | 1 + .../shorewall/files/boilerplate/mangle.header | 7 + .../shorewall/files/boilerplate/masq.footer | 1 + .../shorewall/files/boilerplate/masq.header | 9 + .../modules/shorewall/files/boilerplate/nat.footer | 1 + .../modules/shorewall/files/boilerplate/nat.header | 9 + .../shorewall/files/boilerplate/params.footer | 1 + .../shorewall/files/boilerplate/params.header | 26 + .../shorewall/files/boilerplate/policy.footer | 1 + .../shorewall/files/boilerplate/policy.header | 11 + .../shorewall/files/boilerplate/providers.footer | 1 + .../shorewall/files/boilerplate/providers.header | 9 + .../shorewall/files/boilerplate/proxyarp.footer | 1 + .../shorewall/files/boilerplate/proxyarp.header | 9 + .../shorewall/files/boilerplate/rfc1918.footer | 5 + .../shorewall/files/boilerplate/rfc1918.header | 5 + .../files/boilerplate/routestopped.footer | 1 + .../files/boilerplate/routestopped.header | 11 + .../shorewall/files/boilerplate/rtrules.footer | 1 + .../shorewall/files/boilerplate/rtrules.header | 8 + .../shorewall/files/boilerplate/rules.footer | 1 + .../shorewall/files/boilerplate/rules.header | 10 + .../shorewall/files/boilerplate/start.footer | 1 + .../shorewall/files/boilerplate/start.header | 12 + .../shorewall/files/boilerplate/started.footer | 1 + .../shorewall/files/boilerplate/started.header | 20 + .../shorewall/files/boilerplate/stop.footer | 1 + .../shorewall/files/boilerplate/stop.header | 13 + .../shorewall/files/boilerplate/stopped.footer | 1 + .../shorewall/files/boilerplate/stopped.header | 13 + .../shorewall/files/boilerplate/tcclasses.footer | 1 + .../shorewall/files/boilerplate/tcclasses.header | 9 + .../shorewall/files/boilerplate/tcdevices.footer | 1 + .../shorewall/files/boilerplate/tcdevices.header | 10 + .../shorewall/files/boilerplate/tcrules.footer | 1 + .../shorewall/files/boilerplate/tcrules.header | 15 + .../shorewall/files/boilerplate/tunnel.footer | 1 + .../shorewall/files/boilerplate/tunnel.header | 11 + .../shorewall/files/boilerplate/zones.footer | 1 + .../shorewall/files/boilerplate/zones.header | 12 + puppet/modules/shorewall/files/empty/.ignore | 1 + puppet/modules/shorewall/manifests/base.pp | 78 +++ puppet/modules/shorewall/manifests/blacklist.pp | 9 + puppet/modules/shorewall/manifests/centos.pp | 13 + puppet/modules/shorewall/manifests/debian.pp | 11 + puppet/modules/shorewall/manifests/entry.pp | 12 + .../shorewall/manifests/extension_script.pp | 16 + puppet/modules/shorewall/manifests/gentoo.pp | 5 + puppet/modules/shorewall/manifests/host.pp | 10 + puppet/modules/shorewall/manifests/init.pp | 123 ++++ puppet/modules/shorewall/manifests/interface.pp | 29 + puppet/modules/shorewall/manifests/managed_file.pp | 20 + puppet/modules/shorewall/manifests/mangle.pp | 20 + puppet/modules/shorewall/manifests/masq.pp | 17 + puppet/modules/shorewall/manifests/nat.pp | 11 + puppet/modules/shorewall/manifests/params.pp | 5 + puppet/modules/shorewall/manifests/policy.pp | 12 + puppet/modules/shorewall/manifests/providers.pp | 16 + puppet/modules/shorewall/manifests/proxyarp.pp | 11 + puppet/modules/shorewall/manifests/rfc1918.pp | 8 + puppet/modules/shorewall/manifests/routestopped.pp | 14 + puppet/modules/shorewall/manifests/rtrules.pp | 11 + puppet/modules/shorewall/manifests/rule.pp | 20 + puppet/modules/shorewall/manifests/rule_section.pp | 7 + .../modules/shorewall/manifests/rules/cobbler.pp | 19 + puppet/modules/shorewall/manifests/rules/dns.pp | 6 + .../shorewall/manifests/rules/dns/disable.pp | 6 + .../modules/shorewall/manifests/rules/dns_rules.pp | 22 + puppet/modules/shorewall/manifests/rules/ekeyd.pp | 10 + puppet/modules/shorewall/manifests/rules/ftp.pp | 10 + .../modules/shorewall/manifests/rules/gitdaemon.pp | 10 + .../shorewall/manifests/rules/gitdaemon/absent.pp | 5 + puppet/modules/shorewall/manifests/rules/http.pp | 10 + .../shorewall/manifests/rules/http/disable.pp | 5 + puppet/modules/shorewall/manifests/rules/https.pp | 10 + puppet/modules/shorewall/manifests/rules/identd.pp | 10 + puppet/modules/shorewall/manifests/rules/imap.pp | 11 + puppet/modules/shorewall/manifests/rules/ipsec.pp | 32 + .../modules/shorewall/manifests/rules/ipsec_nat.pp | 18 + .../shorewall/manifests/rules/jabberserver.pp | 34 ++ puppet/modules/shorewall/manifests/rules/jetty.pp | 12 + .../shorewall/manifests/rules/jetty/http.pp | 9 + .../modules/shorewall/manifests/rules/jetty/ssl.pp | 11 + .../modules/shorewall/manifests/rules/keyserver.pp | 11 + .../shorewall/manifests/rules/libvirt/host.pp | 80 +++ .../shorewall/manifests/rules/managesieve.pp | 25 + puppet/modules/shorewall/manifests/rules/mdns.pp | 8 + puppet/modules/shorewall/manifests/rules/munin.pp | 16 + puppet/modules/shorewall/manifests/rules/mysql.pp | 11 + puppet/modules/shorewall/manifests/rules/nfsd.pp | 115 ++++ .../shorewall/manifests/rules/ntp/client.pp | 11 + .../shorewall/manifests/rules/ntp/server.pp | 10 + .../modules/shorewall/manifests/rules/openfire.pp | 12 + .../modules/shorewall/manifests/rules/openvpn.pp | 18 + .../modules/shorewall/manifests/rules/out/ekeyd.pp | 10 + .../modules/shorewall/manifests/rules/out/git.pp | 10 + .../shorewall/manifests/rules/out/ibackup.pp | 12 + .../modules/shorewall/manifests/rules/out/imap.pp | 11 + .../modules/shorewall/manifests/rules/out/irc.pp | 10 + .../modules/shorewall/manifests/rules/out/ircs.pp | 10 + .../shorewall/manifests/rules/out/keyserver.pp | 11 + .../shorewall/manifests/rules/out/managesieve.pp | 25 + .../modules/shorewall/manifests/rules/out/munin.pp | 10 + .../modules/shorewall/manifests/rules/out/mysql.pp | 11 + .../modules/shorewall/manifests/rules/out/pop3.pp | 11 + .../shorewall/manifests/rules/out/postgres.pp | 11 + .../shorewall/manifests/rules/out/puppet.pp | 20 + .../modules/shorewall/manifests/rules/out/pyzor.pp | 12 + .../modules/shorewall/manifests/rules/out/razor.pp | 12 + .../modules/shorewall/manifests/rules/out/silc.pp | 19 + .../modules/shorewall/manifests/rules/out/smtp.pp | 11 + .../modules/shorewall/manifests/rules/out/ssh.pp | 10 + .../shorewall/manifests/rules/out/ssh/disable.pp | 5 + .../shorewall/manifests/rules/out/ssh/remove.pp | 5 + .../modules/shorewall/manifests/rules/out/whois.pp | 11 + .../modules/shorewall/manifests/rules/out/xmpp.pp | 10 + puppet/modules/shorewall/manifests/rules/pop3.pp | 11 + .../modules/shorewall/manifests/rules/postgres.pp | 10 + puppet/modules/shorewall/manifests/rules/puppet.pp | 11 + .../shorewall/manifests/rules/puppet/master.pp | 10 + puppet/modules/shorewall/manifests/rules/rsync.pp | 10 + puppet/modules/shorewall/manifests/rules/silcd.pp | 19 + puppet/modules/shorewall/manifests/rules/smtp.pp | 10 + .../shorewall/manifests/rules/smtp/disable.pp | 5 + .../shorewall/manifests/rules/smtp_submission.pp | 10 + .../manifests/rules/smtp_submission/disable.pp | 5 + puppet/modules/shorewall/manifests/rules/smtps.pp | 10 + .../shorewall/manifests/rules/smtps/disable.pp | 5 + .../shorewall/manifests/rules/sobby/instance.pp | 11 + puppet/modules/shorewall/manifests/rules/ssh.pp | 13 + puppet/modules/shorewall/manifests/rules/syslog.pp | 12 + puppet/modules/shorewall/manifests/rules/tftp.pp | 18 + puppet/modules/shorewall/manifests/rules/tinc.pp | 34 ++ puppet/modules/shorewall/manifests/rules/tomcat.pp | 12 + puppet/modules/shorewall/manifests/rules/torify.pp | 29 + .../rules/torify/allow_tor_transparent_proxy.pp | 21 + .../manifests/rules/torify/allow_tor_user.pp | 15 + .../manifests/rules/torify/redirect_tcp_to_tor.pp | 40 ++ .../manifests/rules/torify/reject_non_tor.pp | 32 + .../shorewall/manifests/rules/torify/user.pp | 27 + puppet/modules/shorewall/manifests/tcclasses.pp | 12 + puppet/modules/shorewall/manifests/tcdevices.pp | 11 + puppet/modules/shorewall/manifests/tcrules.pp | 12 + puppet/modules/shorewall/manifests/tunnel.pp | 11 + puppet/modules/shorewall/manifests/zone.pp | 14 + .../modules/shorewall/templates/debian_default.erb | 26 + 165 files changed, 3036 insertions(+) create mode 100644 puppet/modules/shorewall/.gitrepo create mode 100644 puppet/modules/shorewall/LICENSE create mode 100644 puppet/modules/shorewall/README.md create mode 100644 puppet/modules/shorewall/files/boilerplate/blacklist.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/blacklist.header create mode 100644 puppet/modules/shorewall/files/boilerplate/clear.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/clear.header create mode 100644 puppet/modules/shorewall/files/boilerplate/continue.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/continue.header create mode 100644 puppet/modules/shorewall/files/boilerplate/hosts.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/hosts.header create mode 100644 puppet/modules/shorewall/files/boilerplate/init.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/init.header create mode 100644 puppet/modules/shorewall/files/boilerplate/initdone.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/initdone.header create mode 100644 puppet/modules/shorewall/files/boilerplate/interfaces.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/interfaces.header create mode 100644 puppet/modules/shorewall/files/boilerplate/maclog.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/maclog.header create mode 100644 puppet/modules/shorewall/files/boilerplate/mangle.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/mangle.header create mode 100644 puppet/modules/shorewall/files/boilerplate/masq.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/masq.header create mode 100644 puppet/modules/shorewall/files/boilerplate/nat.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/nat.header create mode 100644 puppet/modules/shorewall/files/boilerplate/params.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/params.header create mode 100644 puppet/modules/shorewall/files/boilerplate/policy.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/policy.header create mode 100644 puppet/modules/shorewall/files/boilerplate/providers.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/providers.header create mode 100644 puppet/modules/shorewall/files/boilerplate/proxyarp.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/proxyarp.header create mode 100644 puppet/modules/shorewall/files/boilerplate/rfc1918.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/rfc1918.header create mode 100644 puppet/modules/shorewall/files/boilerplate/routestopped.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/routestopped.header create mode 100644 puppet/modules/shorewall/files/boilerplate/rtrules.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/rtrules.header create mode 100644 puppet/modules/shorewall/files/boilerplate/rules.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/rules.header create mode 100644 puppet/modules/shorewall/files/boilerplate/start.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/start.header create mode 100644 puppet/modules/shorewall/files/boilerplate/started.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/started.header create mode 100644 puppet/modules/shorewall/files/boilerplate/stop.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/stop.header create mode 100644 puppet/modules/shorewall/files/boilerplate/stopped.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/stopped.header create mode 100644 puppet/modules/shorewall/files/boilerplate/tcclasses.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/tcclasses.header create mode 100644 puppet/modules/shorewall/files/boilerplate/tcdevices.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/tcdevices.header create mode 100644 puppet/modules/shorewall/files/boilerplate/tcrules.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/tcrules.header create mode 100644 puppet/modules/shorewall/files/boilerplate/tunnel.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/tunnel.header create mode 100644 puppet/modules/shorewall/files/boilerplate/zones.footer create mode 100644 puppet/modules/shorewall/files/boilerplate/zones.header create mode 100644 puppet/modules/shorewall/files/empty/.ignore create mode 100644 puppet/modules/shorewall/manifests/base.pp create mode 100644 puppet/modules/shorewall/manifests/blacklist.pp create mode 100644 puppet/modules/shorewall/manifests/centos.pp create mode 100644 puppet/modules/shorewall/manifests/debian.pp create mode 100644 puppet/modules/shorewall/manifests/entry.pp create mode 100644 puppet/modules/shorewall/manifests/extension_script.pp create mode 100644 puppet/modules/shorewall/manifests/gentoo.pp create mode 100644 puppet/modules/shorewall/manifests/host.pp create mode 100644 puppet/modules/shorewall/manifests/init.pp create mode 100644 puppet/modules/shorewall/manifests/interface.pp create mode 100644 puppet/modules/shorewall/manifests/managed_file.pp create mode 100644 puppet/modules/shorewall/manifests/mangle.pp create mode 100644 puppet/modules/shorewall/manifests/masq.pp create mode 100644 puppet/modules/shorewall/manifests/nat.pp create mode 100644 puppet/modules/shorewall/manifests/params.pp create mode 100644 puppet/modules/shorewall/manifests/policy.pp create mode 100644 puppet/modules/shorewall/manifests/providers.pp create mode 100644 puppet/modules/shorewall/manifests/proxyarp.pp create mode 100644 puppet/modules/shorewall/manifests/rfc1918.pp create mode 100644 puppet/modules/shorewall/manifests/routestopped.pp create mode 100644 puppet/modules/shorewall/manifests/rtrules.pp create mode 100644 puppet/modules/shorewall/manifests/rule.pp create mode 100644 puppet/modules/shorewall/manifests/rule_section.pp create mode 100644 puppet/modules/shorewall/manifests/rules/cobbler.pp create mode 100644 puppet/modules/shorewall/manifests/rules/dns.pp create mode 100644 puppet/modules/shorewall/manifests/rules/dns/disable.pp create mode 100644 puppet/modules/shorewall/manifests/rules/dns_rules.pp create mode 100644 puppet/modules/shorewall/manifests/rules/ekeyd.pp create mode 100644 puppet/modules/shorewall/manifests/rules/ftp.pp create mode 100644 puppet/modules/shorewall/manifests/rules/gitdaemon.pp create mode 100644 puppet/modules/shorewall/manifests/rules/gitdaemon/absent.pp create mode 100644 puppet/modules/shorewall/manifests/rules/http.pp create mode 100644 puppet/modules/shorewall/manifests/rules/http/disable.pp create mode 100644 puppet/modules/shorewall/manifests/rules/https.pp create mode 100644 puppet/modules/shorewall/manifests/rules/identd.pp create mode 100644 puppet/modules/shorewall/manifests/rules/imap.pp create mode 100644 puppet/modules/shorewall/manifests/rules/ipsec.pp create mode 100644 puppet/modules/shorewall/manifests/rules/ipsec_nat.pp create mode 100644 puppet/modules/shorewall/manifests/rules/jabberserver.pp create mode 100644 puppet/modules/shorewall/manifests/rules/jetty.pp create mode 100644 puppet/modules/shorewall/manifests/rules/jetty/http.pp create mode 100644 puppet/modules/shorewall/manifests/rules/jetty/ssl.pp create mode 100644 puppet/modules/shorewall/manifests/rules/keyserver.pp create mode 100644 puppet/modules/shorewall/manifests/rules/libvirt/host.pp create mode 100644 puppet/modules/shorewall/manifests/rules/managesieve.pp create mode 100644 puppet/modules/shorewall/manifests/rules/mdns.pp create mode 100644 puppet/modules/shorewall/manifests/rules/munin.pp create mode 100644 puppet/modules/shorewall/manifests/rules/mysql.pp create mode 100644 puppet/modules/shorewall/manifests/rules/nfsd.pp create mode 100644 puppet/modules/shorewall/manifests/rules/ntp/client.pp create mode 100644 puppet/modules/shorewall/manifests/rules/ntp/server.pp create mode 100644 puppet/modules/shorewall/manifests/rules/openfire.pp create mode 100644 puppet/modules/shorewall/manifests/rules/openvpn.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/ekeyd.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/git.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/ibackup.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/imap.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/irc.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/ircs.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/keyserver.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/managesieve.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/munin.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/mysql.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/pop3.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/postgres.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/puppet.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/pyzor.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/razor.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/silc.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/smtp.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/ssh.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/ssh/disable.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/ssh/remove.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/whois.pp create mode 100644 puppet/modules/shorewall/manifests/rules/out/xmpp.pp create mode 100644 puppet/modules/shorewall/manifests/rules/pop3.pp create mode 100644 puppet/modules/shorewall/manifests/rules/postgres.pp create mode 100644 puppet/modules/shorewall/manifests/rules/puppet.pp create mode 100644 puppet/modules/shorewall/manifests/rules/puppet/master.pp create mode 100644 puppet/modules/shorewall/manifests/rules/rsync.pp create mode 100644 puppet/modules/shorewall/manifests/rules/silcd.pp create mode 100644 puppet/modules/shorewall/manifests/rules/smtp.pp create mode 100644 puppet/modules/shorewall/manifests/rules/smtp/disable.pp create mode 100644 puppet/modules/shorewall/manifests/rules/smtp_submission.pp create mode 100644 puppet/modules/shorewall/manifests/rules/smtp_submission/disable.pp create mode 100644 puppet/modules/shorewall/manifests/rules/smtps.pp create mode 100644 puppet/modules/shorewall/manifests/rules/smtps/disable.pp create mode 100644 puppet/modules/shorewall/manifests/rules/sobby/instance.pp create mode 100644 puppet/modules/shorewall/manifests/rules/ssh.pp create mode 100644 puppet/modules/shorewall/manifests/rules/syslog.pp create mode 100644 puppet/modules/shorewall/manifests/rules/tftp.pp create mode 100644 puppet/modules/shorewall/manifests/rules/tinc.pp create mode 100644 puppet/modules/shorewall/manifests/rules/tomcat.pp create mode 100644 puppet/modules/shorewall/manifests/rules/torify.pp create mode 100644 puppet/modules/shorewall/manifests/rules/torify/allow_tor_transparent_proxy.pp create mode 100644 puppet/modules/shorewall/manifests/rules/torify/allow_tor_user.pp create mode 100644 puppet/modules/shorewall/manifests/rules/torify/redirect_tcp_to_tor.pp create mode 100644 puppet/modules/shorewall/manifests/rules/torify/reject_non_tor.pp create mode 100644 puppet/modules/shorewall/manifests/rules/torify/user.pp create mode 100644 puppet/modules/shorewall/manifests/tcclasses.pp create mode 100644 puppet/modules/shorewall/manifests/tcdevices.pp create mode 100644 puppet/modules/shorewall/manifests/tcrules.pp create mode 100644 puppet/modules/shorewall/manifests/tunnel.pp create mode 100644 puppet/modules/shorewall/manifests/zone.pp create mode 100644 puppet/modules/shorewall/templates/debian_default.erb (limited to 'puppet/modules') diff --git a/puppet/modules/shorewall/.gitrepo b/puppet/modules/shorewall/.gitrepo new file mode 100644 index 00000000..7ae31f9d --- /dev/null +++ b/puppet/modules/shorewall/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_shorewall + branch = master + commit = 06e89ed3486916ae12186e46b8ec59c8c7c79142 + parent = 6083b23278927189de58c11bbb5bc7d93ccced24 + cmdver = 0.3.0 diff --git a/puppet/modules/shorewall/LICENSE b/puppet/modules/shorewall/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/puppet/modules/shorewall/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/puppet/modules/shorewall/README.md b/puppet/modules/shorewall/README.md new file mode 100644 index 00000000..e7e29859 --- /dev/null +++ b/puppet/modules/shorewall/README.md @@ -0,0 +1,224 @@ +Puppet Module for Shorewall +--------------------------- +This module manages the configuration of Shorewall (http://www.shorewall.net/) + +Requirements +------------ + +This module requires the augeas module, you can find that here: +https://gitlab.com/shared-puppet-modules-group/augeas.git + +This module requires the concat module, you can find that here: +https://github.com/puppetlabs/puppetlabs-concat.git + +Copyright +--------- + +Copyright (C) 2007 David Schmitt +adapted by immerda project group - admin+puppet(at)immerda.ch +adapted by Puzzle ITC - haerry+puppet(at)puzzle.ch + +Copyright (c) 2009 Riseup Networks - micah(shift+2)riseup.net + +Copyright (c) 2010 intrigeri - intrigeri(at)boum.org +See LICENSE for the full license granted to you. + +Based on the work of ADNET Ghislain from AQUEOS +at https://reductivelabs.com/trac/puppet/wiki/AqueosShorewall + +Merged from: +- git://git.puppet.immerda.ch/module-shorewall.git +- git://labs.riseup.net/module_shorewall +- https://gitlab.com/shared-puppet-modules-group/shorewall.git + + +Todo +---- +- check if shorewall compiles without errors, otherwise fail ! + +Configuration +------------- + +If you need to install a specific version of shorewall other than +the default one that would be installed by 'ensure => present', then +you can set the following variable and that specific version will be +installed instead: + + $shorewall_ensure_version = "4.0.15-1" + +The main shorewall.conf is not managed by this module, rather the default one +that your operatingsystem provides is used, and any modifications you wish to do +to it should be configured with augeas, for example, to set IP_FORWARDING=Yes in +shorewall.conf, simply do this: + + augeas { 'enable_ip_forwarding': + changes => 'set /files/etc/shorewall/shorewall.conf/IP_FORWARDING Yes', + lens => 'Shellvars.lns', + incl => '/etc/shorewall/shorewall.conf', + notify => Service[shorewall]; + } + +NOTE: this requires the augeas ruby bindings newer than 0.7.3. + +If you need to, you can provide an entire shorewall.conf by passing its +source to the main class: + + class{'shorewall': + conf_source => "puppet:///modules/site_shorewall/${::fqdn}/shorewall.conf.${::operatingsystem}", + } + +NOTE: if you distribute a file, you cannot also use augeas, puppet and augeas +will fight forever. Secondly, you will *need* to make sure that if you are shipping your own +shorewall.conf that you have the following value set in your shorewall.conf otherwise this +module will not work: + + CONFIG_PATH="/etc/shorewall/puppet:/etc/shorewall:/usr/share/shorewall" + +Documentation +------------- + +see also: http://reductivelabs.com/trac/puppet/wiki/Recipes/AqueosShorewall + +Torify +------ + +The shorewall::rules::torify define can be used to force some outgoing +TCP traffic through the Tor transparent proxy. The corresponding +non-TCP traffic is rejected accordingly. + +Beware! This define only is part of a torified setup. DNS requests and +IPv6, amongst others, might leak network activity you would prefer not +to. You really need to read proper documentation about these matters +before using this feature e.g.: + + https://www.torproject.org/download/download.html.en#warning + +The Tor transparent proxy location defaults to 127.0.0.1:9040 and can +be configured by setting the $tor_transparent_proxy_host and +$tor_transparent_proxy_port variables before including the main +shorewall class. + +Example usage follows. + +Torify any outgoing TCP traffic originating from user bob or alice and +aimed at 6.6.6.6 or 7.7.7.7: + + shorewall::rules::torify { + 'torify-some-bits': + users => [ 'bob', 'alice' ], + destinations => [ '6.6.6.6', '7.7.7.7' ]; + } + +Torify any outgoing TCP traffic to 8.8.8.8: + + shorewall::rules::torify { + 'torify-to-this-host': + destinations => [ '8.8.8.8' ]; + } + +When no destination nor user is provided any outgoing TCP traffic (see +restrictions bellow) is torified. In that case the user running the +Tor client ($tor_user) is whitelisted; this variable defaults to +"debian-tor" on Debian systems and to "tor" on others. if this does +not suit your configuration you need to set the $tor_user variable +before including the main shorewall class. + +When no destination is provided traffic directed to RFC1918 addresses +is by default allowed and (obviously) not torified. This behaviour can +be changed by setting the allow_rfc1918 parameter to false. + +Torify any outgoing TCP traffic but connections to RFC1918 addresses: + + shorewall::rules::torify { + 'torify-everything-but-lan': + } + +Torify any outgoing TCP traffic: + + shorewall::rules::torify { + 'torify-everything: + allow_rfc1918 => false; + } + +In some cases (e.g. when providing no specific destination nor user +and denying access to RFC1918 addresses) UDP DNS requests may be +rejected. This is intentional: it does not make sense leaking -via DNS +requests- network activity that would otherwise be torified. In that +case you probably want to read proper documentation about such +matters, enable the Tor DNS resolver and redirect DNS requests through +it. + +Example +------- + +Example from node.pp: + + node xy { + class{'config::site_shorewall': + startup => "0" # create shorewall ruleset but don't startup + } + shorewall::rule { + 'incoming-ssh': source => 'all', destination => '$FW', action => 'SSH(ACCEPT)', order => 200; + 'incoming-puppetmaster': source => 'all', destination => '$FW', action => 'Puppetmaster(ACCEPT)', order => 300; + 'incoming-imap': source => 'all', destination => '$FW', action => 'IMAP(ACCEPT)', order => 300; + 'incoming-smtp': source => 'all', destination => '$FW', action => 'SMTP(ACCEPT)', order => 300; + } + } + + + class config::site_shorewall($startup = '1') { + class{'shorewall': + startup => $startup + } + + # If you want logging: + #shorewall::params { + # 'LOG': value => 'debug'; + #} + + shorewall::zone {'net': + type => 'ipv4'; + } + + shorewall::rule_section { 'NEW': + order => 100; + } + + shorewall::interface { 'eth0': + zone => 'net', + rfc1918 => true, + options => 'tcpflags,blacklist,nosmurfs'; + } + + shorewall::policy { + 'fw-to-fw': + sourcezone => '$FW', + destinationzone => '$FW', + policy => 'ACCEPT', + order => 100; + 'fw-to-net': + sourcezone => '$FW', + destinationzone => 'net', + policy => 'ACCEPT', + shloglevel => '$LOG', + order => 110; + 'net-to-fw': + sourcezone => 'net', + destinationzone => '$FW', + policy => 'DROP', + shloglevel => '$LOG', + order => 120; + } + + + # default Rules : ICMP + shorewall::rule { + 'allicmp-to-host': + source => 'all', + destination => '$FW', + order => 200, + action => 'AllowICMPs/(ACCEPT)'; + } + } + + diff --git a/puppet/modules/shorewall/files/boilerplate/blacklist.footer b/puppet/modules/shorewall/files/boilerplate/blacklist.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/blacklist.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/blacklist.header b/puppet/modules/shorewall/files/boilerplate/blacklist.header new file mode 100644 index 00000000..2392e176 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/blacklist.header @@ -0,0 +1,10 @@ +# +# Shorewall version 3.4 - Blacklist File +# +# For information about entries in this file, type "man shorewall-blacklist" +# +# Please see http://shorewall.net/blacklisting_support.htm for additional +# information. +# +############################################################################### +#ADDRESS/SUBNET PROTOCOL PORT diff --git a/puppet/modules/shorewall/files/boilerplate/clear.footer b/puppet/modules/shorewall/files/boilerplate/clear.footer new file mode 100644 index 00000000..662ac1cc --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/clear.footer @@ -0,0 +1 @@ +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/clear.header b/puppet/modules/shorewall/files/boilerplate/clear.header new file mode 100644 index 00000000..6a39b0b6 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/clear.header @@ -0,0 +1,13 @@ +# +# Shorewall version 4 - Clear +# +# /etc/shorewall/stop +# +# Add commands below that you want to be executed at the beginning of a +# "shorewall stop" command. +# +# See http://shorewall.net/shorewall_extension_scripts.htm for additional +# information. +# +############################################################################### +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/continue.footer b/puppet/modules/shorewall/files/boilerplate/continue.footer new file mode 100644 index 00000000..662ac1cc --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/continue.footer @@ -0,0 +1 @@ +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/continue.header b/puppet/modules/shorewall/files/boilerplate/continue.header new file mode 100644 index 00000000..d2ee48a5 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/continue.header @@ -0,0 +1,14 @@ +# +# Shorewall version 4 - Continue File +# +# /etc/shorewall/continue +# +# Add commands below that you want to be executed after shorewall has +# cleared any existing Netfilter rules and has enabled existing +# connections. +# +# For additional information, see +# http://shorewall.net/shorewall_extension_scripts.htm +# +############################################################################### + diff --git a/puppet/modules/shorewall/files/boilerplate/hosts.footer b/puppet/modules/shorewall/files/boilerplate/hosts.footer new file mode 100644 index 00000000..dc2fef52 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/hosts.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS LINE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/hosts.header b/puppet/modules/shorewall/files/boilerplate/hosts.header new file mode 100644 index 00000000..e39d6145 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/hosts.header @@ -0,0 +1,9 @@ +# +# Shorewall version 3.4 - Hosts file +# +# For information about entries in this file, type "man shorewall-hosts" +# +# For additional information, see http://shorewall.net/Documentation.htm#Hosts +# +############################################################################### +#ZONE HOST(S) OPTIONS diff --git a/puppet/modules/shorewall/files/boilerplate/init.footer b/puppet/modules/shorewall/files/boilerplate/init.footer new file mode 100644 index 00000000..662ac1cc --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/init.footer @@ -0,0 +1 @@ +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/init.header b/puppet/modules/shorewall/files/boilerplate/init.header new file mode 100644 index 00000000..cbb0393e --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/init.header @@ -0,0 +1,13 @@ +# +# Shorewall version 4 - Init File +# +# /etc/shorewall/init +# +# Add commands below that you want to be executed at the beginning of +# a "shorewall start" or "shorewall restart" command. +# +# For additional information, see +# http://shorewall.net/shorewall_extension_scripts.htm +# +############################################################################### + diff --git a/puppet/modules/shorewall/files/boilerplate/initdone.footer b/puppet/modules/shorewall/files/boilerplate/initdone.footer new file mode 100644 index 00000000..662ac1cc --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/initdone.footer @@ -0,0 +1 @@ +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/initdone.header b/puppet/modules/shorewall/files/boilerplate/initdone.header new file mode 100644 index 00000000..9252a3bc --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/initdone.header @@ -0,0 +1,14 @@ +# +# Shorewall version 4 - Initdone File +# +# /etc/shorewall/initdone +# +# Add commands below that you want to be executed during +# "shorewall start" or "shorewall restart" commands at the point where +# Shorewall has not yet added any perminent rules to the builtin chains. +# +# For additional information, see +# http://shorewall.net/shorewall_extension_scripts.htm +# +############################################################################### + diff --git a/puppet/modules/shorewall/files/boilerplate/interfaces.footer b/puppet/modules/shorewall/files/boilerplate/interfaces.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/interfaces.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/interfaces.header b/puppet/modules/shorewall/files/boilerplate/interfaces.header new file mode 100644 index 00000000..663e4367 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/interfaces.header @@ -0,0 +1,10 @@ +# +# Shorewall version 4 - Interfaces File +# +# For information about entries in this file, type "man shorewall-interfaces" +# +# For additional information, see +# http://www.shorewall.net/manpages/shorewall-interfaces.html +# +############################################################################### +#ZONE INTERFACE BROADCAST OPTIONS diff --git a/puppet/modules/shorewall/files/boilerplate/maclog.footer b/puppet/modules/shorewall/files/boilerplate/maclog.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/maclog.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/maclog.header b/puppet/modules/shorewall/files/boilerplate/maclog.header new file mode 100644 index 00000000..b0c382ab --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/maclog.header @@ -0,0 +1,14 @@ +# +# Shorewall version 4 - Maclog File (Added in Shorewall version 3.2.5) +# +# /etc/shorewall/start +# +# Add commands below that you want executed while mac filtering rules are +# being created. These will be executed once for each interface having +# 'maclist' speciied and it is invoked just before the logging rule is +# added to the current chain (the name of that chain will be in $CHAIN) +# +# See http://shorewall.net/shorewall_extension_scripts.htm for additional +# information. +# +############################################################################### diff --git a/puppet/modules/shorewall/files/boilerplate/mangle.footer b/puppet/modules/shorewall/files/boilerplate/mangle.footer new file mode 100644 index 00000000..6bebc05c --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/mangle.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/mangle.header b/puppet/modules/shorewall/files/boilerplate/mangle.header new file mode 100644 index 00000000..7a7b12ab --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/mangle.header @@ -0,0 +1,7 @@ +# +# Shorewall - Mangle File +# +# For additional information, see http://shorewall.net/manpages/shorewall-mangle.html +# +####################################################################################### +#ACTION SOURCE DESTINATION PROTO DSTPORT SRCPORT USER TEST LENGTH TOS CONNBYTES HELPER HEADERS diff --git a/puppet/modules/shorewall/files/boilerplate/masq.footer b/puppet/modules/shorewall/files/boilerplate/masq.footer new file mode 100644 index 00000000..6bebc05c --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/masq.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/masq.header b/puppet/modules/shorewall/files/boilerplate/masq.header new file mode 100644 index 00000000..f8233210 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/masq.header @@ -0,0 +1,9 @@ +# +# Shorewall version 3.4 - Masq file +# +# For information about entries in this file, type "man shorewall-masq" +# +# For additional information, see http://shorewall.net/Documentation.htm#Masq +# +############################################################################### +#INTERFACE SOURCE ADDRESS PROTO PORT(S) IPSEC MARK diff --git a/puppet/modules/shorewall/files/boilerplate/nat.footer b/puppet/modules/shorewall/files/boilerplate/nat.footer new file mode 100644 index 00000000..6bebc05c --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/nat.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/nat.header b/puppet/modules/shorewall/files/boilerplate/nat.header new file mode 100644 index 00000000..c2e0d922 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/nat.header @@ -0,0 +1,9 @@ +# +# Shorewall version 3.4 - Nat File +# +# For information about entries in this file, type "man shorewall-nat" +# +# For additional information, see http://shorewall.net/NAT.htm +# +############################################################################### +#EXTERNAL INTERFACE INTERNAL ALL LOCAL diff --git a/puppet/modules/shorewall/files/boilerplate/params.footer b/puppet/modules/shorewall/files/boilerplate/params.footer new file mode 100644 index 00000000..662ac1cc --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/params.footer @@ -0,0 +1 @@ +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/params.header b/puppet/modules/shorewall/files/boilerplate/params.header new file mode 100644 index 00000000..b258b0de --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/params.header @@ -0,0 +1,26 @@ +# +# Shorewall version 3.4 - Params File +# +# /etc/shorewall/params +# +# Assign any variables that you need here. +# +# It is suggested that variable names begin with an upper case letter +# to distinguish them from variables used internally within the +# Shorewall programs +# +# Example: +# +# NET_IF=eth0 +# NET_BCAST=130.252.100.255 +# NET_OPTIONS=routefilter,norfc1918 +# +# Example (/etc/shorewall/interfaces record): +# +# net $NET_IF $NET_BCAST $NET_OPTIONS +# +# The result will be the same as if the record had been written +# +# net eth0 130.252.100.255 routefilter,norfc1918 +# +############################################################################### diff --git a/puppet/modules/shorewall/files/boilerplate/policy.footer b/puppet/modules/shorewall/files/boilerplate/policy.footer new file mode 100644 index 00000000..16c86d0e --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/policy.footer @@ -0,0 +1 @@ +#LAST LINE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/policy.header b/puppet/modules/shorewall/files/boilerplate/policy.header new file mode 100644 index 00000000..cc9781f0 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/policy.header @@ -0,0 +1,11 @@ +# +# Shorewall version 4 - Policy File +# +# For information about entries in this file, type "man shorewall-policy" +# +# The manpage is also online at +# http://www.shorewall.net/manpages/shorewall-policy.html +# +############################################################################### +#SOURCE DEST POLICY LOG LIMIT: CONNLIMIT: +# LEVEL BURST MASK diff --git a/puppet/modules/shorewall/files/boilerplate/providers.footer b/puppet/modules/shorewall/files/boilerplate/providers.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/providers.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/providers.header b/puppet/modules/shorewall/files/boilerplate/providers.header new file mode 100644 index 00000000..b4a5990f --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/providers.header @@ -0,0 +1,9 @@ +# +# Shorewall version 4 - Providers File +# +# For information about entries in this file, type "man shorewall-providers" +# +# For additional information, see http://shorewall.net/MultiISP.html +# +############################################################################################ +#NAME NUMBER MARK DUPLICATE INTERFACE GATEWAY OPTIONS COPY diff --git a/puppet/modules/shorewall/files/boilerplate/proxyarp.footer b/puppet/modules/shorewall/files/boilerplate/proxyarp.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/proxyarp.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/proxyarp.header b/puppet/modules/shorewall/files/boilerplate/proxyarp.header new file mode 100644 index 00000000..1e168532 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/proxyarp.header @@ -0,0 +1,9 @@ +# +# Shorewall version 3.4 - Proxyarp File +# +# For information about entries in this file, type "man shorewall-proxyarp" +# +# See http://shorewall.net/ProxyARP.htm for additional information. +# +############################################################################### +#ADDRESS INTERFACE EXTERNAL HAVEROUTE PERSISTENT diff --git a/puppet/modules/shorewall/files/boilerplate/rfc1918.footer b/puppet/modules/shorewall/files/boilerplate/rfc1918.footer new file mode 100644 index 00000000..e07fdb15 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/rfc1918.footer @@ -0,0 +1,5 @@ +# The real subnets from RFC1918 +172.16.0.0/12 logdrop # RFC 1918 +192.168.0.0/16 logdrop # RFC 1918 +10.0.0.0/8 logdrop # RFC 1918 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/rfc1918.header b/puppet/modules/shorewall/files/boilerplate/rfc1918.header new file mode 100644 index 00000000..8d6a4162 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/rfc1918.header @@ -0,0 +1,5 @@ +# +# Shorewall version 3.4 - Rfc1918 File +# +############################################################################### +#SUBNETS TARGET diff --git a/puppet/modules/shorewall/files/boilerplate/routestopped.footer b/puppet/modules/shorewall/files/boilerplate/routestopped.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/routestopped.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/routestopped.header b/puppet/modules/shorewall/files/boilerplate/routestopped.header new file mode 100644 index 00000000..5408aace --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/routestopped.header @@ -0,0 +1,11 @@ +# +# Shorewall version 3.4 - Routestopped File +# +# For information about entries in this file, type "man shorewall-routestopped" +# +# See http://shorewall.net/Documentation.htm#Routestopped and +# http://shorewall.net/starting_and_stopping_shorewall.htm for additional +# information. +# +############################################################################### +#INTERFACE HOST(S) OPTIONS diff --git a/puppet/modules/shorewall/files/boilerplate/rtrules.footer b/puppet/modules/shorewall/files/boilerplate/rtrules.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/rtrules.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/rtrules.header b/puppet/modules/shorewall/files/boilerplate/rtrules.header new file mode 100644 index 00000000..fd9b2f48 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/rtrules.header @@ -0,0 +1,8 @@ +# +# Shorewall version 4 - route rules File +# +# For information about entries in this file, type "man shorewall-rtrules" +# +# For additional information, see http://www.shorewall.net/MultiISP.html +#################################################################################### +# SOURCE DEST PROVIDER PRIORITY MASK diff --git a/puppet/modules/shorewall/files/boilerplate/rules.footer b/puppet/modules/shorewall/files/boilerplate/rules.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/rules.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/rules.header b/puppet/modules/shorewall/files/boilerplate/rules.header new file mode 100644 index 00000000..764358ac --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/rules.header @@ -0,0 +1,10 @@ +# +# Shorewall version 3.4 - Rules File +# +# For information on the settings in this file, type "man shorewall-rules" +# +# See http://shorewall.net/Documentation.htm#Rules for additional information. +# +############################################################################################################# +#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ MARK +# PORT PORT(S) DEST LIMIT GROUP diff --git a/puppet/modules/shorewall/files/boilerplate/start.footer b/puppet/modules/shorewall/files/boilerplate/start.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/start.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/start.header b/puppet/modules/shorewall/files/boilerplate/start.header new file mode 100644 index 00000000..689dff19 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/start.header @@ -0,0 +1,12 @@ +# +# Shorewall version 4 - Start File +# +# /etc/shorewall/start +# +# Add commands below that you want to be executed after shorewall has +# been started or restarted. +# +# See http://shorewall.net/shorewall_extension_scripts.htm for additional +# information. +# +############################################################################### diff --git a/puppet/modules/shorewall/files/boilerplate/started.footer b/puppet/modules/shorewall/files/boilerplate/started.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/started.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/started.header b/puppet/modules/shorewall/files/boilerplate/started.header new file mode 100644 index 00000000..b7704dba --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/started.header @@ -0,0 +1,20 @@ +# +# Shorewall version 4 - Started File +# +# /etc/shorewall/started +# +# Add commands below that you want to be executed after shorewall has +# been completely started or restarted. The difference between this +# extension script and /etc/shorewall/start is that this one is invoked +# after delayed loading of the blacklist (DELAYBLACKLISTLOAD=Yes) and +# after the 'shorewall' chain has been created (thus signaling that the +# firewall is completely up). +# +# This script should not change the firewall configuration directly but +# may do so indirectly by running /sbin/shorewall with the 'nolock' +# option. +# +# See http://shorewall.net/shorewall_extension_scripts.htm for additional +# information. +# +############################################################################### diff --git a/puppet/modules/shorewall/files/boilerplate/stop.footer b/puppet/modules/shorewall/files/boilerplate/stop.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/stop.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/stop.header b/puppet/modules/shorewall/files/boilerplate/stop.header new file mode 100644 index 00000000..0088abe1 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/stop.header @@ -0,0 +1,13 @@ +# +# Shorewall version 4 - Stop File +# +# /etc/shorewall/stop +# +# Add commands below that you want to be executed at the beginning of a +# "shorewall stop" command. +# +# See http://shorewall.net/shorewall_extension_scripts.htm for additional +# information. +# +############################################################################### +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/stopped.footer b/puppet/modules/shorewall/files/boilerplate/stopped.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/stopped.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/stopped.header b/puppet/modules/shorewall/files/boilerplate/stopped.header new file mode 100644 index 00000000..438e5e05 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/stopped.header @@ -0,0 +1,13 @@ +# +# Shorewall version 4 - Stopped File +# +# /etc/shorewall/stopped +# +# Add commands below that you want to be executed at the completion of a +# "shorewall stop" command. +# +# See http://shorewall.net/shorewall_extension_scripts.htm for additional +# information. +# +############################################################################### +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/tcclasses.footer b/puppet/modules/shorewall/files/boilerplate/tcclasses.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/tcclasses.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/tcclasses.header b/puppet/modules/shorewall/files/boilerplate/tcclasses.header new file mode 100644 index 00000000..025415ba --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/tcclasses.header @@ -0,0 +1,9 @@ +# +# Shorewall version 4 - Tcclasses File +# +# For information about entries in this file, type "man shorewall-tcclasses" +# +# See http://shorewall.net/traffic_shaping.htm for additional information. +# +############################################################################### +#INTERFACE:CLASS MARK RATE CEIL PRIORITY OPTIONS diff --git a/puppet/modules/shorewall/files/boilerplate/tcdevices.footer b/puppet/modules/shorewall/files/boilerplate/tcdevices.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/tcdevices.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/tcdevices.header b/puppet/modules/shorewall/files/boilerplate/tcdevices.header new file mode 100644 index 00000000..fe7c3d1f --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/tcdevices.header @@ -0,0 +1,10 @@ +# +# Shorewall version 4 - Tcdevices File +# +# For information about entries in this file, type "man shorewall-tcdevices" +# +# See http://shorewall.net/traffic_shaping.htm for additional information. +# +############################################################################### +#NUMBER: IN-BANDWITH OUT-BANDWIDTH OPTIONS REDIRECTED +#INTERFACE INTERFACES diff --git a/puppet/modules/shorewall/files/boilerplate/tcrules.footer b/puppet/modules/shorewall/files/boilerplate/tcrules.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/tcrules.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/tcrules.header b/puppet/modules/shorewall/files/boilerplate/tcrules.header new file mode 100644 index 00000000..e0e7adcf --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/tcrules.header @@ -0,0 +1,15 @@ +# +# Shorewall version 4 - Tcrules File +# +# For information about entries in this file, type "man shorewall-tcrules" +# +# See http://shorewall.net/traffic_shaping.htm for additional information. +# For usage in selecting among multiple ISPs, see +# http://shorewall.net/MultiISP.html +# +# See http://shorewall.net/PacketMarking.html for a detailed description of +# the Netfilter/Shorewall packet marking mechanism. +###################################################################################################################### +#MARK SOURCE DEST PROTO DEST SOURCE USER TEST LENGTH TOS CONNBYTES HELPER +# PORT(S) PORT(S) + diff --git a/puppet/modules/shorewall/files/boilerplate/tunnel.footer b/puppet/modules/shorewall/files/boilerplate/tunnel.footer new file mode 100644 index 00000000..5e12d1da --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/tunnel.footer @@ -0,0 +1 @@ +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/tunnel.header b/puppet/modules/shorewall/files/boilerplate/tunnel.header new file mode 100644 index 00000000..638fd568 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/tunnel.header @@ -0,0 +1,11 @@ +# +# Shorewall version 4 - Tunnels File +# +# For information about entries in this file, type "man shorewall-tunnels" +# +# The manpage is also online at +# http://www.shorewall.net/manpages/shorewall-tunnels.html +# +############################################################################### +#TYPE ZONE GATEWAY GATEWAY +# ZONE diff --git a/puppet/modules/shorewall/files/boilerplate/zones.footer b/puppet/modules/shorewall/files/boilerplate/zones.footer new file mode 100644 index 00000000..662ac1cc --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/zones.footer @@ -0,0 +1 @@ +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE diff --git a/puppet/modules/shorewall/files/boilerplate/zones.header b/puppet/modules/shorewall/files/boilerplate/zones.header new file mode 100644 index 00000000..5dada523 --- /dev/null +++ b/puppet/modules/shorewall/files/boilerplate/zones.header @@ -0,0 +1,12 @@ +# +# Shorewall version 4 - Zones File +# +# For information about this file, type "man shorewall-zones" +# +# The manpage is also online at +# http://www.shorewall.net/manpages/shorewall-zones.html +# +############################################################################### +#ZONE TYPE OPTIONS IN OUT +# OPTIONS OPTIONS +fw firewall diff --git a/puppet/modules/shorewall/files/empty/.ignore b/puppet/modules/shorewall/files/empty/.ignore new file mode 100644 index 00000000..89cb1fe9 --- /dev/null +++ b/puppet/modules/shorewall/files/empty/.ignore @@ -0,0 +1 @@ +# file needed for git - don't remove it diff --git a/puppet/modules/shorewall/manifests/base.pp b/puppet/modules/shorewall/manifests/base.pp new file mode 100644 index 00000000..6599759e --- /dev/null +++ b/puppet/modules/shorewall/manifests/base.pp @@ -0,0 +1,78 @@ +# base things for shorewall +class shorewall::base { + + package { 'shorewall': + ensure => $shorewall::ensure_version, + } + + # This file has to be managed in place, so shorewall can find it + file { + '/etc/shorewall/shorewall.conf': + require => Package['shorewall'], + notify => Exec['shorewall_check'], + owner => 'root', + group => 'root', + mode => '0644'; + '/etc/shorewall/puppet': + ensure => directory, + require => Package['shorewall'], + owner => 'root', + group => 'root', + mode => '0644'; + } + + if $shorewall::conf_source { + File['/etc/shorewall/shorewall.conf']{ + source => $shorewall::conf_source, + } + } else { + + include ::augeas + Class['augeas'] -> Class['shorewall::base'] + + augeas { 'shorewall_module_config_path': + changes => 'set /files/etc/shorewall/shorewall.conf/CONFIG_PATH \'"/etc/shorewall/puppet:/etc/shorewall:/usr/share/shorewall"\'', + lens => 'Shellvars.lns', + incl => '/etc/shorewall/shorewall.conf', + notify => Exec['shorewall_check'], + require => Package['shorewall']; + } + } + + exec{'shorewall_check': + command => 'shorewall check', + refreshonly => true, + notify => Service['shorewall'], + } + service{'shorewall': + ensure => running, + enable => true, + hasstatus => true, + hasrestart => true, + require => Package['shorewall'], + } + + file{'/etc/cron.daily/shorewall_check':} + if $shorewall::daily_check { + File['/etc/cron.daily/shorewall_check']{ + content => '#!/bin/bash + +output=$(shorewall check 2>&1) +if [ $? -gt 0 ]; then + echo "Error while checking firewall!" + echo $output + exit 1 +fi +exit 0 +', + owner => root, + group => 0, + mode => '0700', + require => Service['shorewall'], + } + } else { + File['/etc/cron.daily/shorewall_check']{ + ensure => absent, + } + } +} diff --git a/puppet/modules/shorewall/manifests/blacklist.pp b/puppet/modules/shorewall/manifests/blacklist.pp new file mode 100644 index 00000000..afbe2165 --- /dev/null +++ b/puppet/modules/shorewall/manifests/blacklist.pp @@ -0,0 +1,9 @@ +define shorewall::blacklist( + $proto = '-', + $port = '-', + $order='100' +){ + shorewall::entry{"blacklist-${order}-${name}": + line => "${name} ${proto} ${port}", + } +} diff --git a/puppet/modules/shorewall/manifests/centos.pp b/puppet/modules/shorewall/manifests/centos.pp new file mode 100644 index 00000000..1f8b37dd --- /dev/null +++ b/puppet/modules/shorewall/manifests/centos.pp @@ -0,0 +1,13 @@ +# things needed on centos +class shorewall::centos inherits shorewall::base { + if versioncmp($::operatingsystemmajrelease,'5') > 0 { + augeas{'enable_shorewall': + context => '/files/etc/sysconfig/shorewall', + changes => 'set startup 1', + lens => 'Shellvars.lns', + incl => '/etc/sysconfig/shorewall', + require => Package['shorewall'], + notify => Exec['shorewall_check'], + } + } +} diff --git a/puppet/modules/shorewall/manifests/debian.pp b/puppet/modules/shorewall/manifests/debian.pp new file mode 100644 index 00000000..07176a32 --- /dev/null +++ b/puppet/modules/shorewall/manifests/debian.pp @@ -0,0 +1,11 @@ +# debian specific things +class shorewall::debian inherits shorewall::base { + file{'/etc/default/shorewall': + content => template('shorewall/debian_default.erb'), + require => Package['shorewall'], + notify => Exec['shorewall_check'], + owner => 'root', + group => 'root', + mode => '0644'; + } +} diff --git a/puppet/modules/shorewall/manifests/entry.pp b/puppet/modules/shorewall/manifests/entry.pp new file mode 100644 index 00000000..c8fffc72 --- /dev/null +++ b/puppet/modules/shorewall/manifests/entry.pp @@ -0,0 +1,12 @@ +define shorewall::entry( + $ensure = present, + $line +){ + $parts = split($name,'-') + concat::fragment{$name: + ensure => $ensure, + content => "${line}\n", + order => $parts[1], + target => "/etc/shorewall/puppet/${parts[0]}", + } +} diff --git a/puppet/modules/shorewall/manifests/extension_script.pp b/puppet/modules/shorewall/manifests/extension_script.pp new file mode 100644 index 00000000..80b83d3b --- /dev/null +++ b/puppet/modules/shorewall/manifests/extension_script.pp @@ -0,0 +1,16 @@ +# See http://shorewall.net/shorewall_extension_scripts.htm +define shorewall::extension_script( + $script +) { + case $name { + 'init', 'initdone', 'start', 'started', 'stop', 'stopped', 'clear', 'refresh', 'continue', 'maclog': { + file { "/etc/shorewall/puppet/${name}": + content => "${script}\n", + notify => Exec['shorewall_check']; + } + } + default: { + err("${name}: unknown shorewall extension script") + } + } +} diff --git a/puppet/modules/shorewall/manifests/gentoo.pp b/puppet/modules/shorewall/manifests/gentoo.pp new file mode 100644 index 00000000..7b307a4e --- /dev/null +++ b/puppet/modules/shorewall/manifests/gentoo.pp @@ -0,0 +1,5 @@ +class shorewall::gentoo inherits shorewall::base { + Package[shorewall]{ + category => 'net-firewall', + } +} diff --git a/puppet/modules/shorewall/manifests/host.pp b/puppet/modules/shorewall/manifests/host.pp new file mode 100644 index 00000000..f4002232 --- /dev/null +++ b/puppet/modules/shorewall/manifests/host.pp @@ -0,0 +1,10 @@ +define shorewall::host( + $zone, + $options = 'tcpflags,blacklist,norfc1918', + $order='100' +){ + shorewall::entry{"hosts-${order}-${name}": + line => "${zone} ${name} ${options}" + } +} + diff --git a/puppet/modules/shorewall/manifests/init.pp b/puppet/modules/shorewall/manifests/init.pp new file mode 100644 index 00000000..d6b2d2a4 --- /dev/null +++ b/puppet/modules/shorewall/manifests/init.pp @@ -0,0 +1,123 @@ +# Manage shorewall on your system +class shorewall( + $startup = '1', + $conf_source = false, + $ensure_version = 'present', + $tor_transparent_proxy_host = '127.0.0.1', + $tor_transparent_proxy_port = '9040', + $tor_user = $::operatingsystem ? { + 'Debian' => 'debian-tor', + default => 'tor' + }, + $zones = {}, + $zones_defaults = {}, + $interfaces = {}, + $interfaces_defaults = {}, + $hosts = {}, + $hosts_defaults = {}, + $policy = {}, + $policy_defaults = {}, + $rules = {}, + $rules_defaults = {}, + $rulesections = {}, + $rulesections_defaults = {}, + $masq = {}, + $masq_defaults = {}, + $proxyarp = {}, + $proxyarp_defaults = {}, + $nat = {}, + $nat_defaults = {}, + $blacklist = {}, + $blacklist_defaults = {}, + $rfc1918 = {}, + $rfc1918_defaults = {}, + $routestopped = {}, + $routestopped_defaults = {}, + $params = {}, + $params_defaults = {}, + $tcdevices = {}, + $tcdevices_defaults = {}, + $tcrules = {}, + $tcrules_defaults = {}, + $tcclasses = {}, + $tcclasses_defaults = {}, + $tunnels = {}, + $tunnels_defaults = {}, + $rtrules = {}, + $rtrules_defaults = {}, + $daily_check = true, +) { + + case $::operatingsystem { + 'Gentoo': { include ::shorewall::gentoo } + 'Debian','Ubuntu': { include ::shorewall::debian } + 'CentOS': { include ::shorewall::centos } + default: { + notice "unknown operatingsystem: ${::operatingsystem}" + include ::shorewall::base + } + } + + shorewall::managed_file{ + [ + # See http://www.shorewall.net/3.0/Documentation.htm#Zones + 'zones', + # See http://www.shorewall.net/3.0/Documentation.htm#Interfaces + 'interfaces', + # See http://www.shorewall.net/3.0/Documentation.htm#Hosts + 'hosts', + # See http://www.shorewall.net/3.0/Documentation.htm#Policy + 'policy', + # See http://www.shorewall.net/3.0/Documentation.htm#Rules + 'rules', + # See http://www.shorewall.net/3.0/Documentation.htm#Masq + 'masq', + # See http://www.shorewall.net/3.0/Documentation.htm#ProxyArp + 'proxyarp', + # See http://www.shorewall.net/3.0/Documentation.htm#NAT + 'nat', + # See http://www.shorewall.net/3.0/Documentation.htm#Blacklist + 'blacklist', + # See http://www.shorewall.net/3.0/Documentation.htm#rfc1918 + 'rfc1918', + # See http://www.shorewall.net/3.0/Documentation.htm#Routestopped + 'routestopped', + # See http://www.shorewall.net/3.0/Documentation.htm#Variables + 'params', + # See http://www.shorewall.net/3.0/traffic_shaping.htm + 'tcdevices', + # See http://www.shorewall.net/3.0/traffic_shaping.htm + 'tcrules', + # See http://www.shorewall.net/3.0/traffic_shaping.htm + 'tcclasses', + # http://www.shorewall.net/manpages/shorewall-providers.html + 'providers', + # See http://www.shorewall.net/manpages/shorewall-tunnels.html + 'tunnel', + # See http://www.shorewall.net/MultiISP.html + 'rtrules', + # See http://www.shorewall.net/manpages/shorewall-mangle.html + 'mangle', + ]:; + } + + create_resources('shorewall::zone',$zones,$zones_defaults) + create_resources('shorewall::interface',$interfaces,$interfaces_defaults) + create_resources('shorewall::host',$hosts,$hosts_defaults) + create_resources('shorewall::policy',$policy,$policy_defaults) + create_resources('shorewall::rule',$rules,$rules_defaults) + create_resources('shorewall::rule_section',$rulesections,$rulesections_defaults) + create_resources('shorewall::masq',$masq,$masq_defaults) + create_resources('shorewall::proxyarp',$proxyarp,$proxyarp_defaults) + create_resources('shorewall::nat',$nat,$nat_defaults) + create_resources('shorewall::blacklist',$blacklist,$blacklist_defaults) + create_resources('shorewall::rfc1918',$rfc1918,$rfc1918_defaults) + create_resources('shorewall::routestopped',$routestopped, + $routestopped_defaults) + create_resources('shorewall::params',$params,$params_defaults) + create_resources('shorewall::tcdevices',$tcdevices,$tcdevices_defaults) + create_resources('shorewall::tcrules',$tcrules,$tcrules_defaults) + create_resources('shorewall::tcclasses',$tcclasses,$tcclasses_defaults) + create_resources('shorewall::tunnel',$tunnels,$tunnels_defaults) + create_resources('shorewall::rtrules',$rtrules,$rtrules_defaults) +} diff --git a/puppet/modules/shorewall/manifests/interface.pp b/puppet/modules/shorewall/manifests/interface.pp new file mode 100644 index 00000000..403ee749 --- /dev/null +++ b/puppet/modules/shorewall/manifests/interface.pp @@ -0,0 +1,29 @@ +define shorewall::interface( + $zone, + $broadcast = 'detect', + $options = 'tcpflags,blacklist,routefilter,nosmurfs,logmartians', + $add_options = '', + $rfc1918 = false, + $dhcp = false, + $order = 100 +){ + $added_opts = $add_options ? { + '' => '', + default => ",${add_options}", + } + + $dhcp_opt = $dhcp ? { + false => '', + default => ',dhcp', + } + + $rfc1918_opt = $rfc1918 ? { + false => ',norfc1918', + default => '', + } + + shorewall::entry { "interfaces-${order}-${name}": + line => "${zone} ${name} ${broadcast} ${options}${dhcp_opt}${rfc1918_opt}${added_opts}", + } +} + diff --git a/puppet/modules/shorewall/manifests/managed_file.pp b/puppet/modules/shorewall/manifests/managed_file.pp new file mode 100644 index 00000000..b3538145 --- /dev/null +++ b/puppet/modules/shorewall/manifests/managed_file.pp @@ -0,0 +1,20 @@ +# manage a certain file +define shorewall::managed_file() { + concat{ "/etc/shorewall/puppet/${name}": + notify => Exec['shorewall_check'], + require => File['/etc/shorewall/puppet'], + owner => 'root', + group => 'root', + mode => '0600'; + } + concat::fragment { + "${name}-header": + source => "puppet:///modules/shorewall/boilerplate/${name}.header", + target => "/etc/shorewall/puppet/${name}", + order => '000'; + "${name}-footer": + source => "puppet:///modules/shorewall/boilerplate/${name}.footer", + target => "/etc/shorewall/puppet/${name}", + order => '999'; + } +} diff --git a/puppet/modules/shorewall/manifests/mangle.pp b/puppet/modules/shorewall/manifests/mangle.pp new file mode 100644 index 00000000..cd404e7c --- /dev/null +++ b/puppet/modules/shorewall/manifests/mangle.pp @@ -0,0 +1,20 @@ +define shorewall::mangle( + $source, + $destination, + $action = $name, + $proto = '-', + $destinationport = '-', + $sourceport = '-', + $user = '-', + $test = '-', + $length = '-', + $tos = '-', + $connbytes = '-', + $helper = '-', + $headers = '-', + $order = '100' +){ + shorewall::entry{"mangle-${order}-${name}": + line => "${action} ${source} ${destination} ${proto} ${destinationport} ${sourceport} ${user} ${test} ${length} ${tos} ${connbytes} ${helper} ${headers}" + } +} diff --git a/puppet/modules/shorewall/manifests/masq.pp b/puppet/modules/shorewall/manifests/masq.pp new file mode 100644 index 00000000..fb097e5e --- /dev/null +++ b/puppet/modules/shorewall/manifests/masq.pp @@ -0,0 +1,17 @@ +# mark is new in 3.4.4 +# source (= subnet) = Set of hosts that you wish to masquerade. +# address = If you specify an address here, SNAT will be used and this will be the source address. +define shorewall::masq( + $interface, + $source, $address = '-', + $proto = '-', + $port = '-', + $ipsec = '-', + $mark = '', + $order='100' +){ + shorewall::entry{"masq-${order}-${name}": + line => "# ${name}\n${interface} ${source} ${address} ${proto} ${port} ${ipsec} ${mark}" + } +} + diff --git a/puppet/modules/shorewall/manifests/nat.pp b/puppet/modules/shorewall/manifests/nat.pp new file mode 100644 index 00000000..e29b7849 --- /dev/null +++ b/puppet/modules/shorewall/manifests/nat.pp @@ -0,0 +1,11 @@ +define shorewall::nat( + $interface, + $internal, + $all = 'no', + $local = 'yes', + $order='100' +){ + shorewall::entry{"nat-${order}-${name}": + line => "${name} ${interface} ${internal} ${all} ${local}" + } +} diff --git a/puppet/modules/shorewall/manifests/params.pp b/puppet/modules/shorewall/manifests/params.pp new file mode 100644 index 00000000..3bc56630 --- /dev/null +++ b/puppet/modules/shorewall/manifests/params.pp @@ -0,0 +1,5 @@ +define shorewall::params($value, $order='100'){ + shorewall::entry{"params-${order}-${name}": + line => "${name}=${value}", + } +} diff --git a/puppet/modules/shorewall/manifests/policy.pp b/puppet/modules/shorewall/manifests/policy.pp new file mode 100644 index 00000000..efee05b5 --- /dev/null +++ b/puppet/modules/shorewall/manifests/policy.pp @@ -0,0 +1,12 @@ +define shorewall::policy( + $sourcezone, + $destinationzone, + $policy, $shloglevel = '-', + $limitburst = '-', + $order +){ + shorewall::entry{"policy-${order}-${name}": + line => "# ${name}\n${sourcezone} ${destinationzone} ${policy} ${shloglevel} ${limitburst}", + } +} + diff --git a/puppet/modules/shorewall/manifests/providers.pp b/puppet/modules/shorewall/manifests/providers.pp new file mode 100644 index 00000000..a1f8726a --- /dev/null +++ b/puppet/modules/shorewall/manifests/providers.pp @@ -0,0 +1,16 @@ +# manage providers +define shorewall::providers( + $provider = $name, + $number = '', + $mark = '', + $duplicate = 'main', + $interface = '', + $gateway = '', + $options = '', + $copy = '', + $order = '100' +){ + shorewall::entry{"providers-${order}-${name}": + line => "# ${name}\n${provider} ${number} ${mark} ${duplicate} ${interface} ${gateway} ${options} ${copy}" + } +} diff --git a/puppet/modules/shorewall/manifests/proxyarp.pp b/puppet/modules/shorewall/manifests/proxyarp.pp new file mode 100644 index 00000000..1af554fb --- /dev/null +++ b/puppet/modules/shorewall/manifests/proxyarp.pp @@ -0,0 +1,11 @@ +define shorewall::proxyarp( + $interface, + $external, + $haveroute = yes, + $persistent = no, + $order='100' + ){ + shorewall::entry{"proxyarp-${order}-${name}": + line => "# ${name}\n${name} ${interface} ${external} ${haveroute} ${persistent}" + } +} diff --git a/puppet/modules/shorewall/manifests/rfc1918.pp b/puppet/modules/shorewall/manifests/rfc1918.pp new file mode 100644 index 00000000..31dce5dc --- /dev/null +++ b/puppet/modules/shorewall/manifests/rfc1918.pp @@ -0,0 +1,8 @@ +define shorewall::rfc1918( + $action = 'logdrop', + $order='100' +){ + shorewall::entry{"rfc1918-${order}-${name}": + line => "${name} ${action}" + } +} diff --git a/puppet/modules/shorewall/manifests/routestopped.pp b/puppet/modules/shorewall/manifests/routestopped.pp new file mode 100644 index 00000000..aca57b51 --- /dev/null +++ b/puppet/modules/shorewall/manifests/routestopped.pp @@ -0,0 +1,14 @@ +define shorewall::routestopped( + $interface = $name, + $host = '-', + $options = '', + $order='100' +){ + $real_interface = $interface ? { + '' => $name, + default => $interface, + } + shorewall::entry{"routestopped-${order}-${name}": + line => "${real_interface} ${host} ${options}", + } +} diff --git a/puppet/modules/shorewall/manifests/rtrules.pp b/puppet/modules/shorewall/manifests/rtrules.pp new file mode 100644 index 00000000..3810f26d --- /dev/null +++ b/puppet/modules/shorewall/manifests/rtrules.pp @@ -0,0 +1,11 @@ +define shorewall::rtrules( + $source = '-', + $destination = '-', + $provider, + $priority = '10000', + $mark, +){ + shorewall::entry { "rtrules-${mark}-${name}": + line => "# ${name}\n${source} ${destination} ${provider} ${priority} ${mark}", + } +} diff --git a/puppet/modules/shorewall/manifests/rule.pp b/puppet/modules/shorewall/manifests/rule.pp new file mode 100644 index 00000000..2fe91e27 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rule.pp @@ -0,0 +1,20 @@ +# mark is new in 3.4.4 +define shorewall::rule( + $ensure = present, + $action, + $source, + $destination, + $proto = '-', + $destinationport = '-', + $sourceport = '-', + $originaldest = '-', + $ratelimit = '-', + $user = '-', + $mark = '', + $order +){ + shorewall::entry{"rules-${order}-${name}": + ensure => $ensure, + line => "# ${name}\n${action} ${source} ${destination} ${proto} ${destinationport} ${sourceport} ${originaldest} ${ratelimit} ${user} ${mark}", + } +} diff --git a/puppet/modules/shorewall/manifests/rule_section.pp b/puppet/modules/shorewall/manifests/rule_section.pp new file mode 100644 index 00000000..82984ca2 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rule_section.pp @@ -0,0 +1,7 @@ +define shorewall::rule_section( + $order +){ + shorewall::entry{"rules-${order}-${name}": + line => "SECTION ${name}", + } +} diff --git a/puppet/modules/shorewall/manifests/rules/cobbler.pp b/puppet/modules/shorewall/manifests/rules/cobbler.pp new file mode 100644 index 00000000..e04e4925 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/cobbler.pp @@ -0,0 +1,19 @@ +class shorewall::rules::cobbler { + shorewall::rule{'net-me-syslog-xmlrpc-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '25150:25151', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule{'net-me-syslog-xmlrpc-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '25150:25151', + order => 240, + action => 'ACCEPT'; + } + include shorewall::rules::rsync +} diff --git a/puppet/modules/shorewall/manifests/rules/dns.pp b/puppet/modules/shorewall/manifests/rules/dns.pp new file mode 100644 index 00000000..e775eeed --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/dns.pp @@ -0,0 +1,6 @@ +# open dns port +class shorewall::rules::dns { + shorewall::rules::dns_rules{ + 'net': + } +} diff --git a/puppet/modules/shorewall/manifests/rules/dns/disable.pp b/puppet/modules/shorewall/manifests/rules/dns/disable.pp new file mode 100644 index 00000000..7de923bd --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/dns/disable.pp @@ -0,0 +1,6 @@ +# disable dns acccess +class shorewall::rules::dns::disable inherits shorewall::rules::dns { + Shorewall::Rules::Dns_rules['net']{ + action => 'DROP', + } +} diff --git a/puppet/modules/shorewall/manifests/rules/dns_rules.pp b/puppet/modules/shorewall/manifests/rules/dns_rules.pp new file mode 100644 index 00000000..abe0eb5a --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/dns_rules.pp @@ -0,0 +1,22 @@ +# open dns port +define shorewall::rules::dns_rules( + $source = $name, + $action = 'ACCEPT', +) { + shorewall::rule { + "${source}-me-tcp_dns": + source => $source, + destination => '$FW', + proto => 'tcp', + destinationport => '53', + order => 240, + action => $action; + "${source}-me-udp_dns": + source => $source, + destination => '$FW', + proto => 'udp', + destinationport => '53', + order => 240, + action => $action; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/ekeyd.pp b/puppet/modules/shorewall/manifests/rules/ekeyd.pp new file mode 100644 index 00000000..dbff02fe --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/ekeyd.pp @@ -0,0 +1,10 @@ +class shorewall::rules::ekeyd { + shorewall::rule { 'net-me-tcp_ekeyd': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '8888', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/ftp.pp b/puppet/modules/shorewall/manifests/rules/ftp.pp new file mode 100644 index 00000000..6d34c78f --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/ftp.pp @@ -0,0 +1,10 @@ +class shorewall::rules::ftp { + shorewall::rule { 'net-me-ftp-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '21', + order => 240, + action => 'FTP/ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/gitdaemon.pp b/puppet/modules/shorewall/manifests/rules/gitdaemon.pp new file mode 100644 index 00000000..21372f63 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/gitdaemon.pp @@ -0,0 +1,10 @@ +class shorewall::rules::gitdaemon { + shorewall::rule {'net-me-tcp_gitdaemon': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '9418', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/gitdaemon/absent.pp b/puppet/modules/shorewall/manifests/rules/gitdaemon/absent.pp new file mode 100644 index 00000000..ade6fba0 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/gitdaemon/absent.pp @@ -0,0 +1,5 @@ +class shorewall::rules::gitdaemon::absent inherits shorewall::rules::gitdaemon { + Shorewall::Rule['net-me-tcp_gitdaemon']{ + ensure => absent, + } +} diff --git a/puppet/modules/shorewall/manifests/rules/http.pp b/puppet/modules/shorewall/manifests/rules/http.pp new file mode 100644 index 00000000..e6a9bdef --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/http.pp @@ -0,0 +1,10 @@ +class shorewall::rules::http { + shorewall::rule { 'net-me-http-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '80', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/http/disable.pp b/puppet/modules/shorewall/manifests/rules/http/disable.pp new file mode 100644 index 00000000..5d9170ca --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/http/disable.pp @@ -0,0 +1,5 @@ +class shorewall::rules::http::disable inherits shorewall::rules::http { + Shorewall::Rule['net-me-http-tcp']{ + action => 'DROP', + } +} diff --git a/puppet/modules/shorewall/manifests/rules/https.pp b/puppet/modules/shorewall/manifests/rules/https.pp new file mode 100644 index 00000000..cc49d100 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/https.pp @@ -0,0 +1,10 @@ +class shorewall::rules::https { + shorewall::rule { 'net-me-https-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '443', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/identd.pp b/puppet/modules/shorewall/manifests/rules/identd.pp new file mode 100644 index 00000000..719e581c --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/identd.pp @@ -0,0 +1,10 @@ +class shorewall::rules::identd { + shorewall::rule { 'net-me-identd-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '113', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/imap.pp b/puppet/modules/shorewall/manifests/rules/imap.pp new file mode 100644 index 00000000..7fbe1818 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/imap.pp @@ -0,0 +1,11 @@ +class shorewall::rules::imap { + shorewall::rule { + 'net-me-tcp_imap_s': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '143,993', + order => 260, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/ipsec.pp b/puppet/modules/shorewall/manifests/rules/ipsec.pp new file mode 100644 index 00000000..413406e1 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/ipsec.pp @@ -0,0 +1,32 @@ +# manage ipsec rules for zone specified in +# $name +define shorewall::rules::ipsec() { + shorewall::rule { + "${name}-me-ipsec-udp": + source => $name, + destination => '$FW', + proto => 'udp', + destinationport => '500', + order => 240, + action => 'ACCEPT'; + "me-${name}-ipsec-udp": + source => '$FW', + destination => $name, + proto => 'udp', + destinationport => '500', + order => 240, + action => 'ACCEPT'; + "${name}-me-ipsec": + source => $name, + destination => '$FW', + proto => 'esp', + order => 240, + action => 'ACCEPT'; + "me-${name}-ipsec": + source => '$FW', + destination => $name, + proto => 'esp', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/ipsec_nat.pp b/puppet/modules/shorewall/manifests/rules/ipsec_nat.pp new file mode 100644 index 00000000..6c0d5072 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/ipsec_nat.pp @@ -0,0 +1,18 @@ +class shorewall::rules::ipsec_nat { + shorewall::rule { + 'net-me-ipsec-nat-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '4500', + order => 240, + action => 'ACCEPT'; + 'me-net-ipsec-nat-udp': + source => '$FW', + destination => 'net', + proto => 'udp', + destinationport => '4500', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/jabberserver.pp b/puppet/modules/shorewall/manifests/rules/jabberserver.pp new file mode 100644 index 00000000..226d6274 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/jabberserver.pp @@ -0,0 +1,34 @@ +# open ports used by a jabberserver +# in and outbound. +class shorewall::rules::jabberserver( + $open_stun = true, +) { + shorewall::rule { + 'net-me-tcp_jabber': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '5222,5223,5269', + order => 240, + action => 'ACCEPT'; + 'me-net-tcp_jabber_s2s': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '5260,5269,5270,5271,5272', + order => 240, + action => 'ACCEPT'; + } + + if $open_stun { + shorewall::rule { + 'net-me-udp_jabber_stun_server': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '3478', + order => 240, + action => 'ACCEPT'; + } + } +} diff --git a/puppet/modules/shorewall/manifests/rules/jetty.pp b/puppet/modules/shorewall/manifests/rules/jetty.pp new file mode 100644 index 00000000..4080e7e6 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/jetty.pp @@ -0,0 +1,12 @@ +class shorewall::rules::jetty { + # open jetty port + shorewall::rule { + 'net-me-jetty-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '8080', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/jetty/http.pp b/puppet/modules/shorewall/manifests/rules/jetty/http.pp new file mode 100644 index 00000000..4c0652be --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/jetty/http.pp @@ -0,0 +1,9 @@ +class shorewall::rules::jetty::http { + # dnat + shorewall::rule { + 'dnat-http-to-jetty': + destination => "net:${::ipaddress}:8080", + destinationport => '80', + source => 'net', proto => 'tcp', order => 140, action => 'DNAT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/jetty/ssl.pp b/puppet/modules/shorewall/manifests/rules/jetty/ssl.pp new file mode 100644 index 00000000..f7517493 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/jetty/ssl.pp @@ -0,0 +1,11 @@ +class shorewall::rules::jetty::ssl { + shorewall::rule { + 'net-me-jettyssl-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '8443', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/keyserver.pp b/puppet/modules/shorewall/manifests/rules/keyserver.pp new file mode 100644 index 00000000..2ade9c1e --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/keyserver.pp @@ -0,0 +1,11 @@ +class shorewall::rules::keyserver { + shorewall::rule { + 'net-me-tcp_keyserver': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '11371,11372', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/libvirt/host.pp b/puppet/modules/shorewall/manifests/rules/libvirt/host.pp new file mode 100644 index 00000000..dc3970d1 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/libvirt/host.pp @@ -0,0 +1,80 @@ +class shorewall::rules::libvirt::host ( + $vmz = 'vmz', + $masq_iface = 'eth0', + $debproxy_port = 8000, + $accept_dhcp = true, + $vmz_iface = 'virbr0', + ) { + + define shorewall::rule::accept::from_vmz ( + $proto = '-', + $destinationport = '-', + $action = 'ACCEPT' + ) { + shorewall::rule { $name: + source => $shorewall::rules::libvirt::host::vmz, + destination => '$FW', + order => 300, + proto => $proto, + destinationport => $destinationport, + action => $action; + } + } + + shorewall::policy { + 'fw-to-vmz': + sourcezone => '$FW', + destinationzone => $vmz, + policy => 'ACCEPT', + order => 110; + 'vmz-to-net': + sourcezone => $vmz, + destinationzone => 'net', + policy => 'ACCEPT', + order => 200; + 'vmz-to-all': + sourcezone => $vmz, + destinationzone => 'all', + policy => 'DROP', + shloglevel => 'info', + order => 800; + } + + shorewall::rule::accept::from_vmz { + 'accept_dns_from_vmz': + action => 'DNS(ACCEPT)'; + 'accept_tftp_from_vmz': + action => 'TFTP(ACCEPT)'; + 'accept_puppet_from_vmz': + proto => 'tcp', + destinationport => '8140', + action => 'ACCEPT'; + } + + if $accept_dhcp { + shorewall::mangle { "CHECKSUM:T_${vmz_iface}": + action => 'CHECKSUM:T', + source => '-', + destination => $vmz_iface, + proto => 'udp', + destinationport => '68'; + } + } + + if $debproxy_port { + shorewall::rule::accept::from_vmz { 'accept_debproxy_from_vmz': + proto => 'tcp', + destinationport => $debproxy_port, + action => 'ACCEPT'; + } + } + + if $masq_iface { + shorewall::masq { + "masq-${masq_iface}": + interface => $masq_iface, + source => '10.0.0.0/8,169.254.0.0/16,172.16.0.0/12,192.168.0.0/16'; + } + } + +} diff --git a/puppet/modules/shorewall/manifests/rules/managesieve.pp b/puppet/modules/shorewall/manifests/rules/managesieve.pp new file mode 100644 index 00000000..ce1c321f --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/managesieve.pp @@ -0,0 +1,25 @@ +# manage managesieve ports +class shorewall::rules::managesieve( + $legacy_port = false, +) { + shorewall::rule { + 'net-me-tcp_managesieve': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '4190', + order => 260, + action => 'ACCEPT'; + } + if $legacy_port { + shorewall::rule { + 'net-me-tcp_managesieve_legacy': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '2000', + order => 260, + action => 'ACCEPT'; + } + } +} diff --git a/puppet/modules/shorewall/manifests/rules/mdns.pp b/puppet/modules/shorewall/manifests/rules/mdns.pp new file mode 100644 index 00000000..76b1fd90 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/mdns.pp @@ -0,0 +1,8 @@ +class shorewall::rules::mdns { + shorewall::rule { 'net-me-mdns': + source => 'net', + destination => '$FW', + order => 240, + action => 'mDNS(ACCEPT)'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/munin.pp b/puppet/modules/shorewall/manifests/rules/munin.pp new file mode 100644 index 00000000..a20a4e0a --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/munin.pp @@ -0,0 +1,16 @@ +class shorewall::rules::munin( + $munin_port = '4949', + $munin_collector = ['127.0.0.1'], + $collector_source = 'net' +){ + shorewall::params { 'MUNINPORT': value => $munin_port } + shorewall::params { 'MUNINCOLLECTOR': value => join(any2array($munin_collector),',') } + shorewall::rule{'net-me-munin-tcp': + source => "${collector_source}:\$MUNINCOLLECTOR", + destination => '$FW', + proto => 'tcp', + destinationport => '$MUNINPORT', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/mysql.pp b/puppet/modules/shorewall/manifests/rules/mysql.pp new file mode 100644 index 00000000..0da68a19 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/mysql.pp @@ -0,0 +1,11 @@ +class shorewall::rules::mysql { + shorewall::rule { + 'net-me-tcp_mysql': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '3306', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/nfsd.pp b/puppet/modules/shorewall/manifests/rules/nfsd.pp new file mode 100644 index 00000000..bd509cf2 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/nfsd.pp @@ -0,0 +1,115 @@ +class shorewall::rules::nfsd { + shorewall::rule { 'net-me-portmap-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '111', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-portmap-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '111', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-rpc.statd-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '662', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-rpc.statd-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '662', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'me-net-rpc.statd-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '2020', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'me-net-rpc.statd-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '2020', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-rpc.lockd-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '32803', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-rpc.lockd-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '32769', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-rpc.mountd-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '892', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-rpc.mountd-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '892', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-rpc.rquotad-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '875', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-rpc.rquoata-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '875', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-rpc.nfsd-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '2049', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-rpc.nfsd-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '2049', + order => 240, + action => 'ACCEPT'; + } + +} diff --git a/puppet/modules/shorewall/manifests/rules/ntp/client.pp b/puppet/modules/shorewall/manifests/rules/ntp/client.pp new file mode 100644 index 00000000..e0db8d45 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/ntp/client.pp @@ -0,0 +1,11 @@ +class shorewall::rules::ntp::client { + # open ntp udp port to fetch time + shorewall::rule {'me-net-udp_ntp': + source => '$FW', + destination => 'net', + proto => 'udp', + destinationport => '123', + order => 251, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/ntp/server.pp b/puppet/modules/shorewall/manifests/rules/ntp/server.pp new file mode 100644 index 00000000..ed0968db --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/ntp/server.pp @@ -0,0 +1,10 @@ +class shorewall::rules::ntp::server { + shorewall::rule {'net-me-udp_ntp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '123', + order => 241, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/openfire.pp b/puppet/modules/shorewall/manifests/rules/openfire.pp new file mode 100644 index 00000000..0e6d1d80 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/openfire.pp @@ -0,0 +1,12 @@ +class shorewall::rules::openfire { + include shorewall::rules::jaberserver + + shorewall::rule { 'me-all-openfire-tcp': + source => '$FW', + destination => 'all', + proto => 'tcp', + destinationport => '7070,7443,7777', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/openvpn.pp b/puppet/modules/shorewall/manifests/rules/openvpn.pp new file mode 100644 index 00000000..55a20d2d --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/openvpn.pp @@ -0,0 +1,18 @@ +class shorewall::rules::openvpn { + shorewall::rule { 'net-me-openvpn-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '1194', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'me-net-openvpn-udp': + source => '$FW', + destination => 'net', + proto => 'udp', + destinationport => '1194', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/ekeyd.pp b/puppet/modules/shorewall/manifests/rules/out/ekeyd.pp new file mode 100644 index 00000000..8acdaad5 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/ekeyd.pp @@ -0,0 +1,10 @@ +define shorewall::rules::out::ekeyd($host) { + shorewall::rule { "me-${name}-tcp_ekeyd": + source => '$FW', + destination => "${name}:${host}", + proto => 'tcp', + destinationport => '8888', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/git.pp b/puppet/modules/shorewall/manifests/rules/out/git.pp new file mode 100644 index 00000000..cb88da85 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/git.pp @@ -0,0 +1,10 @@ +class shorewall::rules::out::git { + shorewall::rule{'me-net-git-tcp': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '9418', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/ibackup.pp b/puppet/modules/shorewall/manifests/rules/out/ibackup.pp new file mode 100644 index 00000000..856bcdb9 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/ibackup.pp @@ -0,0 +1,12 @@ +class shorewall::rules::out::ibackup( + $backup_host +){ + shorewall::rule { 'me-net-tcp_backupssh': + source => '$FW', + destination => "net:${backup_host}", + proto => 'tcp', + destinationport => 'ssh', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/imap.pp b/puppet/modules/shorewall/manifests/rules/out/imap.pp new file mode 100644 index 00000000..f1313d2c --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/imap.pp @@ -0,0 +1,11 @@ +class shorewall::rules::out::imap { + shorewall::rule { + 'me-net-tcp_imap_s': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '143,993', + order => 260, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/irc.pp b/puppet/modules/shorewall/manifests/rules/out/irc.pp new file mode 100644 index 00000000..9c8590ab --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/irc.pp @@ -0,0 +1,10 @@ +class shorewall::rules::out::irc { + shorewall::rule{'me-net-irc-tcp': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '6667', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/ircs.pp b/puppet/modules/shorewall/manifests/rules/out/ircs.pp new file mode 100644 index 00000000..a71585d8 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/ircs.pp @@ -0,0 +1,10 @@ +class shorewall::rules::out::ircs { + shorewall::rule{'me-net-ircs-tcp': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '6669', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/keyserver.pp b/puppet/modules/shorewall/manifests/rules/out/keyserver.pp new file mode 100644 index 00000000..aa7147e0 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/keyserver.pp @@ -0,0 +1,11 @@ +class shorewall::rules::out::keyserver { + shorewall::rule { + 'me-net-tcp_keyserver': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '11371,11372', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/managesieve.pp b/puppet/modules/shorewall/manifests/rules/out/managesieve.pp new file mode 100644 index 00000000..c4147d4b --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/managesieve.pp @@ -0,0 +1,25 @@ +# manage outgoing traffic to managesieve +class shorewall::rules::out::managesieve( + $legacy_port = false +) { + shorewall::rule { + 'me-net-tcp_managesieve': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '4190', + order => 260, + action => 'ACCEPT'; + } + if $legacy_port { + shorewall::rule { + 'me-net-tcp_managesieve_legacy': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '2000', + order => 260, + action => 'ACCEPT'; + } + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/munin.pp b/puppet/modules/shorewall/manifests/rules/out/munin.pp new file mode 100644 index 00000000..004a3d5b --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/munin.pp @@ -0,0 +1,10 @@ +class shorewall::rules::out::munin { + shorewall::rule { 'me-net-rcp_muninhost': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '4949', + order => 340, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/mysql.pp b/puppet/modules/shorewall/manifests/rules/out/mysql.pp new file mode 100644 index 00000000..1334ba6a --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/mysql.pp @@ -0,0 +1,11 @@ +class shorewall::rules::out::mysql { + shorewall::rule { + 'me-net-tcp_mysql': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '3306', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/pop3.pp b/puppet/modules/shorewall/manifests/rules/out/pop3.pp new file mode 100644 index 00000000..ebd4828f --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/pop3.pp @@ -0,0 +1,11 @@ +class shorewall::rules::out::pop3 { + shorewall::rule { + 'me-net-tcp_pop3_s': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => 'pop3,pop3s', + order => 260, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/postgres.pp b/puppet/modules/shorewall/manifests/rules/out/postgres.pp new file mode 100644 index 00000000..a62d75d7 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/postgres.pp @@ -0,0 +1,11 @@ +class shorewall::rules::out::postgres { + shorewall::rule { + 'me-net-tcp_postgres': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '5432', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/puppet.pp b/puppet/modules/shorewall/manifests/rules/out/puppet.pp new file mode 100644 index 00000000..cbe8cce7 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/puppet.pp @@ -0,0 +1,20 @@ +class shorewall::rules::out::puppet( + $puppetserver = "puppet.${::domain}", + $puppetserver_port = 8140, + $puppetserver_signport = 8141 +) { + class{'shorewall::rules::puppet': + puppetserver => $puppetserver, + puppetserver_port => $puppetserver_port, + puppetserver_signport => $puppetserver_signport, + } + # we want to connect to the puppet server + shorewall::rule { 'me-net-puppet_tcp': + source => '$FW', + destination => 'net:$PUPPETSERVER', + proto => 'tcp', + destinationport => '$PUPPETSERVER_PORT,$PUPPETSERVER_SIGN_PORT', + order => 340, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/pyzor.pp b/puppet/modules/shorewall/manifests/rules/out/pyzor.pp new file mode 100644 index 00000000..f4f5151a --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/pyzor.pp @@ -0,0 +1,12 @@ +# pyzor calls out on 24441 +# https://wiki.apache.org/spamassassin/NetTestFirewallIssues +class shorewall::rules::out::pyzor { + shorewall::rule { 'me-net-udp_pyzor': + source => '$FW', + destination => 'net', + proto => 'udp', + destinationport => '24441', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/razor.pp b/puppet/modules/shorewall/manifests/rules/out/razor.pp new file mode 100644 index 00000000..1f8397ce --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/razor.pp @@ -0,0 +1,12 @@ +# razor calls out on 2703 +# https://wiki.apache.org/spamassassin/NetTestFirewallIssues +class shorewall::rules::out::razor { + shorewall::rule { 'me-net-tcp_razor': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '2703', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/silc.pp b/puppet/modules/shorewall/manifests/rules/out/silc.pp new file mode 100644 index 00000000..830df9c3 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/silc.pp @@ -0,0 +1,19 @@ +class shorewall::rules::out::silc { + shorewall::rule{ + 'me-net-silc-tcp': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '706', + order => 240, + action => 'ACCEPT'; + 'me-net-silc-udp': + source => '$FW', + destination => 'net', + proto => 'udp', + destinationport => '706', + order => 240, + action => 'ACCEPT'; + + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/smtp.pp b/puppet/modules/shorewall/manifests/rules/out/smtp.pp new file mode 100644 index 00000000..2cc77cc3 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/smtp.pp @@ -0,0 +1,11 @@ +class shorewall::rules::out::smtp { + shorewall::rule { + 'me-net-tcp_smtp': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => 'smtp', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/ssh.pp b/puppet/modules/shorewall/manifests/rules/out/ssh.pp new file mode 100644 index 00000000..c18e299b --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/ssh.pp @@ -0,0 +1,10 @@ +class shorewall::rules::out::ssh { + shorewall::rule { 'me-net-tcp_ssh': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => 'ssh', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/ssh/disable.pp b/puppet/modules/shorewall/manifests/rules/out/ssh/disable.pp new file mode 100644 index 00000000..223bf73b --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/ssh/disable.pp @@ -0,0 +1,5 @@ +class shorewall::rules::out::ssh::disable inherits shorewall::rules::out::ssh { + Shorewall::Rule['me-net-tcp_ssh']{ + action => 'DROP', + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/ssh/remove.pp b/puppet/modules/shorewall/manifests/rules/out/ssh/remove.pp new file mode 100644 index 00000000..bc0acf37 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/ssh/remove.pp @@ -0,0 +1,5 @@ +class shorewall::rules::out::ssh::remove inherits shorewall::rules::out::ssh { + Shorewall::Rule['me-net-tcp_ssh']{ + ensure => absent, + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/whois.pp b/puppet/modules/shorewall/manifests/rules/out/whois.pp new file mode 100644 index 00000000..d003d5c1 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/whois.pp @@ -0,0 +1,11 @@ +class shorewall::rules::out::whois { + # open whois tcp port + shorewall::rule {'me-net-tcp_whois': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '43', + order => 251, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/out/xmpp.pp b/puppet/modules/shorewall/manifests/rules/out/xmpp.pp new file mode 100644 index 00000000..a1b4577c --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/out/xmpp.pp @@ -0,0 +1,10 @@ +class shorewall::rules::out::xmpp { + shorewall::rule{'me-net-xmpp-tcp': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '5222', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/pop3.pp b/puppet/modules/shorewall/manifests/rules/pop3.pp new file mode 100644 index 00000000..25878568 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/pop3.pp @@ -0,0 +1,11 @@ +class shorewall::rules::pop3 { + shorewall::rule { + 'net-me-tcp_pop3_s': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => 'pop3,pop3s', + order => 260, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/postgres.pp b/puppet/modules/shorewall/manifests/rules/postgres.pp new file mode 100644 index 00000000..1a22027e --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/postgres.pp @@ -0,0 +1,10 @@ +class shorewall::rules::postgres { + shorewall::rule { 'net-me-tcp_postgres': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '5432', + order => 250, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/puppet.pp b/puppet/modules/shorewall/manifests/rules/puppet.pp new file mode 100644 index 00000000..84e7d813 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/puppet.pp @@ -0,0 +1,11 @@ +class shorewall::rules::puppet( + $puppetserver = "puppet.${::domain}", + $puppetserver_port = 8140, + $puppetserver_signport = 8141 +){ + shorewall::params{ + 'PUPPETSERVER': value => $puppetserver; + 'PUPPETSERVER_PORT': value => $puppetserver_port; + 'PUPPETSERVER_SIGN_PORT': value => $puppetserver_signport; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/puppet/master.pp b/puppet/modules/shorewall/manifests/rules/puppet/master.pp new file mode 100644 index 00000000..925979c3 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/puppet/master.pp @@ -0,0 +1,10 @@ +class shorewall::rules::puppet::master { + shorewall::rule { 'net-me-tcp_puppet-main': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '$PUPPETSERVER_PORT,$PUPPETSERVER_SIGN_PORT', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/rsync.pp b/puppet/modules/shorewall/manifests/rules/rsync.pp new file mode 100644 index 00000000..144624db --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/rsync.pp @@ -0,0 +1,10 @@ +class shorewall::rules::rsync { + shorewall::rule{'me-net-rsync-tcp': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '873', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/silcd.pp b/puppet/modules/shorewall/manifests/rules/silcd.pp new file mode 100644 index 00000000..91ee4a59 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/silcd.pp @@ -0,0 +1,19 @@ +class shorewall::rules::silcd { + shorewall::rule{ + 'net-me-silcd-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '706', + order => 240, + action => 'ACCEPT'; + 'net-me-silcd-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '706', + order => 240, + action => 'ACCEPT'; + + } +} diff --git a/puppet/modules/shorewall/manifests/rules/smtp.pp b/puppet/modules/shorewall/manifests/rules/smtp.pp new file mode 100644 index 00000000..b0389012 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/smtp.pp @@ -0,0 +1,10 @@ +class shorewall::rules::smtp { + shorewall::rule { 'net-me-smtp-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '25', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/smtp/disable.pp b/puppet/modules/shorewall/manifests/rules/smtp/disable.pp new file mode 100644 index 00000000..cee85b08 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/smtp/disable.pp @@ -0,0 +1,5 @@ +class shorewall::rules::smtp::disable inherits shorewall::rules::smtp { + Shorewall::Rule['net-me-smtp-tcp']{ + action => 'DROP' + } +} diff --git a/puppet/modules/shorewall/manifests/rules/smtp_submission.pp b/puppet/modules/shorewall/manifests/rules/smtp_submission.pp new file mode 100644 index 00000000..dff90f35 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/smtp_submission.pp @@ -0,0 +1,10 @@ +class shorewall::rules::smtp_submission { + shorewall::rule { 'net-me-smtp_submission-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '587', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/smtp_submission/disable.pp b/puppet/modules/shorewall/manifests/rules/smtp_submission/disable.pp new file mode 100644 index 00000000..9724fe79 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/smtp_submission/disable.pp @@ -0,0 +1,5 @@ +class shorewall::rules::smtp_submission::disable inherits shorewall::rules::smtp_submission { + Shorewall::Rule['net-me-smtp_submission-tcp']{ + action => 'DROP' + } +} diff --git a/puppet/modules/shorewall/manifests/rules/smtps.pp b/puppet/modules/shorewall/manifests/rules/smtps.pp new file mode 100644 index 00000000..48183f74 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/smtps.pp @@ -0,0 +1,10 @@ +class shorewall::rules::smtps { + shorewall::rule {'net-me-smtps-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '465', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/smtps/disable.pp b/puppet/modules/shorewall/manifests/rules/smtps/disable.pp new file mode 100644 index 00000000..24bd21fb --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/smtps/disable.pp @@ -0,0 +1,5 @@ +class shorewall::rules::smtps::disable inherits shorewall::rules::smtps { + Shorewall::Rule['net-me-smtps-tcp']{ + action => 'DROP', + } +} diff --git a/puppet/modules/shorewall/manifests/rules/sobby/instance.pp b/puppet/modules/shorewall/manifests/rules/sobby/instance.pp new file mode 100644 index 00000000..7151976b --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/sobby/instance.pp @@ -0,0 +1,11 @@ +define shorewall::rules::sobby::instance( $port ){ + shorewall::rule { + "net-me-tcp_sobby_${name}": + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => $port, + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/ssh.pp b/puppet/modules/shorewall/manifests/rules/ssh.pp new file mode 100644 index 00000000..3a1b5309 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/ssh.pp @@ -0,0 +1,13 @@ +class shorewall::rules::ssh( + $ports, + $source = 'net' +) { + shorewall::rule { 'net-me-tcp_ssh': + source => $shorewall::rules::ssh::source, + destination => '$FW', + proto => 'tcp', + destinationport => join($shorewall::rules::ssh::ports,','), + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/syslog.pp b/puppet/modules/shorewall/manifests/rules/syslog.pp new file mode 100644 index 00000000..de802e25 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/syslog.pp @@ -0,0 +1,12 @@ +class shorewall::rules::syslog { + shorewall::rule { 'net-me-syslog-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '514', + order => 240, + action => 'ACCEPT'; + } +} + + diff --git a/puppet/modules/shorewall/manifests/rules/tftp.pp b/puppet/modules/shorewall/manifests/rules/tftp.pp new file mode 100644 index 00000000..78877293 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/tftp.pp @@ -0,0 +1,18 @@ +class shorewall::rules::tftp { + shorewall::rule { 'net-me-tftp-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '69', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-tftp-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '69', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/tinc.pp b/puppet/modules/shorewall/manifests/rules/tinc.pp new file mode 100644 index 00000000..79cf92e4 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/tinc.pp @@ -0,0 +1,34 @@ +class shorewall::rules::tinc { + shorewall::rule { 'net-me-tinc-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '655', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'me-net-tinc-tcp': + source => '$FW', + destination => 'net', + proto => 'tcp', + destinationport => '655', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'net-me-tinc-udp': + source => 'net', + destination => '$FW', + proto => 'udp', + destinationport => '655', + order => 240, + action => 'ACCEPT'; + } + shorewall::rule { 'me-net-tinc-udp': + source => '$FW', + destination => 'net', + proto => 'udp', + destinationport => '655', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/tomcat.pp b/puppet/modules/shorewall/manifests/rules/tomcat.pp new file mode 100644 index 00000000..3c6f9df0 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/tomcat.pp @@ -0,0 +1,12 @@ +class shorewall::rules::tomcat { + # open tomcat port + shorewall::rule { + 'net-me-tomcat-tcp': + source => 'net', + destination => '$FW', + proto => 'tcp', + destinationport => '8080', + order => 240, + action => 'ACCEPT'; + } +} diff --git a/puppet/modules/shorewall/manifests/rules/torify.pp b/puppet/modules/shorewall/manifests/rules/torify.pp new file mode 100644 index 00000000..f6e62d81 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/torify.pp @@ -0,0 +1,29 @@ +# shorewall::rules::torify +# +# Note: shorewall::rules::torify cannot be used several times with the +# same user listed in the $users array. This restriction applies to +# using this define multiple times without providing a $users +# parameter. +# +# Parameters: +# +# - users: every element of this array must be valid in shorewall +# rules user/group column. +# - destinations: every element of this array must be valid in +# shorewall rules original destination column. + +define shorewall::rules::torify( + $users = ['-'], + $destinations = ['-'], + $allow_rfc1918 = true +){ + + $originaldest = join($destinations,',') + + shorewall::rules::torify::user { + $users: + originaldest => $originaldest, + allow_rfc1918 => $allow_rfc1918; + } + +} diff --git a/puppet/modules/shorewall/manifests/rules/torify/allow_tor_transparent_proxy.pp b/puppet/modules/shorewall/manifests/rules/torify/allow_tor_transparent_proxy.pp new file mode 100644 index 00000000..3c18db69 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/torify/allow_tor_transparent_proxy.pp @@ -0,0 +1,21 @@ +class shorewall::rules::torify::allow_tor_transparent_proxy { + + $rule = "allow-tor-transparent-proxy" + + if !defined(Shorewall::Rule["$rule"]) { + # A weirdness in shorewall forces us to explicitly allow traffic to + # net:$tor_transparent_proxy_host:$tor_transparent_proxy_port even + # if $FW->$FW traffic is allowed. This anyway avoids us special-casing + # the remote Tor transparent proxy situation. + shorewall::rule { + "$rule": + source => '$FW', + destination => "net:${shorewall::tor_transparent_proxy_host}", + proto => 'tcp', + destinationport => $shorewall::tor_transparent_proxy_port, + order => 100, + action => 'ACCEPT'; + } + } + +} diff --git a/puppet/modules/shorewall/manifests/rules/torify/allow_tor_user.pp b/puppet/modules/shorewall/manifests/rules/torify/allow_tor_user.pp new file mode 100644 index 00000000..f44c1f01 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/torify/allow_tor_user.pp @@ -0,0 +1,15 @@ +class shorewall::rules::torify::allow_tor_user { + + $whitelist_rule = "allow-from-tor-user" + if !defined(Shorewall::Rule["$whitelist_rule"]) { + shorewall::rule { + "$whitelist_rule": + source => '$FW', + destination => 'all', + user => $shorewall::tor_user, + order => 101, + action => 'ACCEPT'; + } + } + +} diff --git a/puppet/modules/shorewall/manifests/rules/torify/redirect_tcp_to_tor.pp b/puppet/modules/shorewall/manifests/rules/torify/redirect_tcp_to_tor.pp new file mode 100644 index 00000000..2bee6584 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/torify/redirect_tcp_to_tor.pp @@ -0,0 +1,40 @@ +define shorewall::rules::torify::redirect_tcp_to_tor( + $user = '-', + $originaldest = '-' +){ + + # hash the destination as it may contain slashes + $originaldest_sha1 = sha1($originaldest) + $rule = "redirect-to-tor-user=${user}-to=${originaldest_sha1}" + + if !defined(Shorewall::Rule["$rule"]) { + + $originaldest_real = $originaldest ? { + '-' => '!127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16', + default => $originaldest, + } + + $user_real = $user ? { + '-' => "!${shorewall::tor_user}", + default => $user, + } + + $destzone = $shorewall::tor_transparent_proxy_host ? { + '127.0.0.1' => '$FW', + default => 'net' + } + + shorewall::rule { + "$rule": + source => '$FW', + destination => "${destzone}:${shorewall::tor_transparent_proxy_host}:${shorewall::tor_transparent_proxy_port}", + proto => 'tcp:syn', + originaldest => $originaldest_real, + user => $user_real, + order => 110, + action => 'DNAT'; + } + + } + +} diff --git a/puppet/modules/shorewall/manifests/rules/torify/reject_non_tor.pp b/puppet/modules/shorewall/manifests/rules/torify/reject_non_tor.pp new file mode 100644 index 00000000..80240ec7 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/torify/reject_non_tor.pp @@ -0,0 +1,32 @@ +define shorewall::rules::torify::reject_non_tor( + $user = '-', + $originaldest = '-', + $allow_rfc1918 = true +){ + + # hash the destination as it may contain slashes + $originaldest_sha1 = sha1($originaldest) + $rule = "reject-non-tor-from-${user}-to=${originaldest_sha1}" + + if $originaldest == '-' { + $originaldest_real = $allow_rfc1918 ? { + false => '!127.0.0.1', + default => '!127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16', + } + } else { + $originaldest_real = $originaldest + } + + if !defined(Shorewall::Rule["$rule"]) { + shorewall::rule { + "$rule": + source => '$FW', + destination => 'all', + originaldest => $originaldest_real, + user => $user, + order => 120, + action => 'REJECT'; + } + } + +} diff --git a/puppet/modules/shorewall/manifests/rules/torify/user.pp b/puppet/modules/shorewall/manifests/rules/torify/user.pp new file mode 100644 index 00000000..5caccfd6 --- /dev/null +++ b/puppet/modules/shorewall/manifests/rules/torify/user.pp @@ -0,0 +1,27 @@ +define shorewall::rules::torify::user( + $originaldest = '-', + $allow_rfc1918 = true +){ + + $user = $name + + include shorewall::rules::torify::allow_tor_transparent_proxy + + if $originaldest == '-' and $user == '-' { + include shorewall::rules::torify::allow_tor_user + } + + shorewall::rules::torify::redirect_tcp_to_tor { + "redirect-to-tor-user=${user}-to=${originaldest}": + user => $user, + originaldest => $originaldest + } + + shorewall::rules::torify::reject_non_tor { + "reject-non-tor-user=${user}-to=${originaldest}": + user => "$user", + originaldest => $originaldest, + allow_rfc1918 => $allow_rfc1918; + } + +} diff --git a/puppet/modules/shorewall/manifests/tcclasses.pp b/puppet/modules/shorewall/manifests/tcclasses.pp new file mode 100644 index 00000000..4e30a556 --- /dev/null +++ b/puppet/modules/shorewall/manifests/tcclasses.pp @@ -0,0 +1,12 @@ +define shorewall::tcclasses( + $interface, + $rate, + $ceil, + $priority, + $options = '', + $order = '1' +){ + shorewall::entry { "tcclasses-${order}-${name}": + line => "# ${name}\n${interface} ${order} ${rate} ${ceil} ${priority} ${options}", + } +} diff --git a/puppet/modules/shorewall/manifests/tcdevices.pp b/puppet/modules/shorewall/manifests/tcdevices.pp new file mode 100644 index 00000000..f4e88d80 --- /dev/null +++ b/puppet/modules/shorewall/manifests/tcdevices.pp @@ -0,0 +1,11 @@ +define shorewall::tcdevices( + $in_bandwidth, + $out_bandwidth, + $options = '', + $redirected_interfaces = '', + $order = '100' +){ + shorewall::entry { "tcdevices-${order}-${name}": + line => "${name} ${in_bandwidth} ${out_bandwidth} ${options} ${redirected_interfaces}", + } +} diff --git a/puppet/modules/shorewall/manifests/tcrules.pp b/puppet/modules/shorewall/manifests/tcrules.pp new file mode 100644 index 00000000..b9ab4a9d --- /dev/null +++ b/puppet/modules/shorewall/manifests/tcrules.pp @@ -0,0 +1,12 @@ +define shorewall::tcrules( + $source, + $destination, + $protocol = 'all', + $ports, + $client_ports = '', + $order = '1' +){ + shorewall::entry { "tcrules-${order}-${name}": + line => "# ${name}\n${order} ${source} ${destination} ${protocol} ${ports} ${client_ports}", + } +} diff --git a/puppet/modules/shorewall/manifests/tunnel.pp b/puppet/modules/shorewall/manifests/tunnel.pp new file mode 100644 index 00000000..2cac9227 --- /dev/null +++ b/puppet/modules/shorewall/manifests/tunnel.pp @@ -0,0 +1,11 @@ +define shorewall::tunnel( + $tunnel_type, + $zone, + $gateway = '0.0.0.0/0', + $gateway_zones = '', + $order = '1' +) { + shorewall::entry { "tunnel-${order}-${name}": + line => "# ${name}\n${tunnel_type} ${zone} ${gateway} ${gateway_zones}", + } +} diff --git a/puppet/modules/shorewall/manifests/zone.pp b/puppet/modules/shorewall/manifests/zone.pp new file mode 100644 index 00000000..81e57711 --- /dev/null +++ b/puppet/modules/shorewall/manifests/zone.pp @@ -0,0 +1,14 @@ +define shorewall::zone( + $type, + $options = '-', + $in = '-', + $out = '-', + $parent = '-', + $order = 100 +){ + $real_name = $parent ? { '-' => $name, default => "${name}:${parent}" } + shorewall::entry { "zones-${order}-${name}": + line => "${real_name} ${type} ${options} ${in} ${out}" + } +} + diff --git a/puppet/modules/shorewall/templates/debian_default.erb b/puppet/modules/shorewall/templates/debian_default.erb new file mode 100644 index 00000000..ec64cbe0 --- /dev/null +++ b/puppet/modules/shorewall/templates/debian_default.erb @@ -0,0 +1,26 @@ +# prevent startup with default configuration +# set the following varible to 1 in order to allow Shorewall to start + +# This file is brought to you by puppet + +startup=<%= scope.lookupvar('shorewall::startup') == "0" ? '0' : '1' %> + +# if your Shorewall configuration requires detection of the ip address of a ppp +# interface, you must list such interfaces in "wait_interface" to get Shorewall to +# wait until the interface is configured. Otherwise the script will fail because +# it won't be able to detect the IP address. +# +# Example: +# wait_interface="ppp0" +# or +# wait_interface="ppp0 ppp1" +# or, if you have defined in /etc/shorewall/params +# wait_interface= + +# +# Startup options +# + +OPTIONS="" + +# EOF -- cgit v1.2.3 From 81210aea5cf136194598e7a399ce307ecbe088f1 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:52 -0400 Subject: git subrepo clone https://leap.se/git/puppet_resolvconf puppet/modules/resolvconf subrepo: subdir: "puppet/modules/resolvconf" merged: "c7eca07" upstream: origin: "https://leap.se/git/puppet_resolvconf" branch: "master" commit: "c7eca07" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I41a76bde0943f76786b7a67c3b9ee4a6b4db7f28 --- puppet/modules/resolvconf/.gitrepo | 11 +++++++++ puppet/modules/resolvconf/manifests/init.pp | 27 ++++++++++++++++++++++ .../resolvconf/templates/resolvconf.OpenBSD.erb | 5 ++++ puppet/modules/resolvconf/templates/resolvconf.erb | 7 ++++++ 4 files changed, 50 insertions(+) create mode 100644 puppet/modules/resolvconf/.gitrepo create mode 100644 puppet/modules/resolvconf/manifests/init.pp create mode 100644 puppet/modules/resolvconf/templates/resolvconf.OpenBSD.erb create mode 100644 puppet/modules/resolvconf/templates/resolvconf.erb (limited to 'puppet/modules') diff --git a/puppet/modules/resolvconf/.gitrepo b/puppet/modules/resolvconf/.gitrepo new file mode 100644 index 00000000..3359b659 --- /dev/null +++ b/puppet/modules/resolvconf/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_resolvconf + branch = master + commit = c7eca077fdda063edc96d3bea02c4774569e4b10 + parent = 6209061fd112fed1715676abb7b6ae4697f21d83 + cmdver = 0.3.0 diff --git a/puppet/modules/resolvconf/manifests/init.pp b/puppet/modules/resolvconf/manifests/init.pp new file mode 100644 index 00000000..c22c4ea6 --- /dev/null +++ b/puppet/modules/resolvconf/manifests/init.pp @@ -0,0 +1,27 @@ +# +# resolvconf module +# +# Copyright 2008, admin(at)immerda.ch +# Copyright 2008, Puzzle ITC GmbH +# Marcel Härry haerry+puppet(at)puzzle.ch +# Simon Josi josi+puppet(at)puzzle.ch +# +# This program is free software; you can redistribute +# it and/or modify it under the terms of the GNU +# General Public License version 3 as published by +# the Free Software Foundation. +# + +class resolvconf( + $domain = $::domain, + $search = $::domain, + $nameservers = [ '8.8.8.8' ] +) { + file{'/etc/resolv.conf': + content => $::operatingsystem ? { + openbsd => template("resolvconf/resolvconf.${::operatingsystem}.erb"), + default => template('resolvconf/resolvconf.erb'), + }, + owner => root, group => 0, mode => 0444; + } +} diff --git a/puppet/modules/resolvconf/templates/resolvconf.OpenBSD.erb b/puppet/modules/resolvconf/templates/resolvconf.OpenBSD.erb new file mode 100644 index 00000000..48daf279 --- /dev/null +++ b/puppet/modules/resolvconf/templates/resolvconf.OpenBSD.erb @@ -0,0 +1,5 @@ +# managed by puppet +lookup file bind +<% scope.lookupvar('resolvconf::nameservers').each do |nameserver| -%> +nameserver <%= nameserver %> +<% end -%> diff --git a/puppet/modules/resolvconf/templates/resolvconf.erb b/puppet/modules/resolvconf/templates/resolvconf.erb new file mode 100644 index 00000000..d8136bfb --- /dev/null +++ b/puppet/modules/resolvconf/templates/resolvconf.erb @@ -0,0 +1,7 @@ +# managed by puppet +domain <%= scope.lookupvar('resolvconf::domain') %> +search <%= scope.lookupvar('resolvconf::search') %> + +<% scope.lookupvar('resolvconf::nameservers').each do |nameserver| -%> +nameserver <%= nameserver %> +<% end -%> -- cgit v1.2.3 From f2019755fd724fb1020cb2d97cdf82b751450ebc Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:54 -0400 Subject: git subrepo clone https://leap.se/git/puppet_couchdb puppet/modules/couchdb subrepo: subdir: "puppet/modules/couchdb" merged: "76ff149" upstream: origin: "https://leap.se/git/puppet_couchdb" branch: "master" commit: "76ff149" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I9ccb1a9dfdaa083814ea395132c42a778052f59b --- puppet/modules/couchdb/.fixtures.yml | 6 + puppet/modules/couchdb/.gitrepo | 11 ++ puppet/modules/couchdb/Gemfile | 11 ++ puppet/modules/couchdb/README.md | 32 +++ puppet/modules/couchdb/Rakefile | 19 ++ puppet/modules/couchdb/files/Debian/couchdb | 160 +++++++++++++++ puppet/modules/couchdb/files/couch-doc-diff | 17 ++ puppet/modules/couchdb/files/couch-doc-update | 219 +++++++++++++++++++++ puppet/modules/couchdb/files/local.ini | 84 ++++++++ .../couchdb/lib/facter/couchdb_pwhash_alg.rb | 43 ++++ .../modules/couchdb/lib/facter/couchdb_version.rb | 34 ++++ .../lib/puppet/parser/functions/couchdblookup.rb | 55 ++++++ .../couchdb/lib/puppet/parser/functions/pbkdf2.rb | 62 ++++++ puppet/modules/couchdb/manifests/add_user.pp | 39 ++++ puppet/modules/couchdb/manifests/backup.pp | 51 +++++ puppet/modules/couchdb/manifests/base.pp | 124 ++++++++++++ puppet/modules/couchdb/manifests/bigcouch.pp | 51 +++++ .../modules/couchdb/manifests/bigcouch/add_node.pp | 8 + .../modules/couchdb/manifests/bigcouch/debian.pp | 11 ++ .../modules/couchdb/manifests/bigcouch/document.pp | 14 ++ .../couchdb/manifests/bigcouch/package/cloudant.pp | 35 ++++ puppet/modules/couchdb/manifests/create_db.pp | 21 ++ puppet/modules/couchdb/manifests/debian.pp | 15 ++ puppet/modules/couchdb/manifests/deploy_config.pp | 12 ++ puppet/modules/couchdb/manifests/document.pp | 47 +++++ puppet/modules/couchdb/manifests/init.pp | 31 +++ puppet/modules/couchdb/manifests/mirror_db.pp | 21 ++ puppet/modules/couchdb/manifests/params.pp | 23 +++ puppet/modules/couchdb/manifests/query.pp | 12 ++ puppet/modules/couchdb/manifests/query/setup.pp | 10 + puppet/modules/couchdb/manifests/redhat.pp | 1 + .../modules/couchdb/manifests/ssl/deploy_cert.pp | 28 +++ .../modules/couchdb/manifests/ssl/generate_cert.pp | 25 +++ puppet/modules/couchdb/manifests/update.pp | 12 ++ .../modules/couchdb/spec/classes/couchdb_spec.rb | 35 ++++ .../couchdb/spec/fixtures/manifests/site.pp | 8 + .../couchdb/spec/functions/versioncmp_spec.rb | 9 + puppet/modules/couchdb/spec/spec_helper.rb | 9 + puppet/modules/couchdb/templates/admin.ini.erb | 9 + .../modules/couchdb/templates/bigcouch/default.ini | 172 ++++++++++++++++ puppet/modules/couchdb/templates/bigcouch/vm.args | 32 +++ .../couchdb/templates/couchdb-backup.py.erb | 32 +++ 42 files changed, 1650 insertions(+) create mode 100644 puppet/modules/couchdb/.fixtures.yml create mode 100644 puppet/modules/couchdb/.gitrepo create mode 100644 puppet/modules/couchdb/Gemfile create mode 100644 puppet/modules/couchdb/README.md create mode 100644 puppet/modules/couchdb/Rakefile create mode 100755 puppet/modules/couchdb/files/Debian/couchdb create mode 100644 puppet/modules/couchdb/files/couch-doc-diff create mode 100644 puppet/modules/couchdb/files/couch-doc-update create mode 100644 puppet/modules/couchdb/files/local.ini create mode 100644 puppet/modules/couchdb/lib/facter/couchdb_pwhash_alg.rb create mode 100644 puppet/modules/couchdb/lib/facter/couchdb_version.rb create mode 100644 puppet/modules/couchdb/lib/puppet/parser/functions/couchdblookup.rb create mode 100644 puppet/modules/couchdb/lib/puppet/parser/functions/pbkdf2.rb create mode 100644 puppet/modules/couchdb/manifests/add_user.pp create mode 100644 puppet/modules/couchdb/manifests/backup.pp create mode 100644 puppet/modules/couchdb/manifests/base.pp create mode 100644 puppet/modules/couchdb/manifests/bigcouch.pp create mode 100644 puppet/modules/couchdb/manifests/bigcouch/add_node.pp create mode 100644 puppet/modules/couchdb/manifests/bigcouch/debian.pp create mode 100644 puppet/modules/couchdb/manifests/bigcouch/document.pp create mode 100644 puppet/modules/couchdb/manifests/bigcouch/package/cloudant.pp create mode 100644 puppet/modules/couchdb/manifests/create_db.pp create mode 100644 puppet/modules/couchdb/manifests/debian.pp create mode 100644 puppet/modules/couchdb/manifests/deploy_config.pp create mode 100644 puppet/modules/couchdb/manifests/document.pp create mode 100644 puppet/modules/couchdb/manifests/init.pp create mode 100644 puppet/modules/couchdb/manifests/mirror_db.pp create mode 100644 puppet/modules/couchdb/manifests/params.pp create mode 100644 puppet/modules/couchdb/manifests/query.pp create mode 100644 puppet/modules/couchdb/manifests/query/setup.pp create mode 100644 puppet/modules/couchdb/manifests/redhat.pp create mode 100644 puppet/modules/couchdb/manifests/ssl/deploy_cert.pp create mode 100644 puppet/modules/couchdb/manifests/ssl/generate_cert.pp create mode 100644 puppet/modules/couchdb/manifests/update.pp create mode 100644 puppet/modules/couchdb/spec/classes/couchdb_spec.rb create mode 100644 puppet/modules/couchdb/spec/fixtures/manifests/site.pp create mode 100644 puppet/modules/couchdb/spec/functions/versioncmp_spec.rb create mode 100644 puppet/modules/couchdb/spec/spec_helper.rb create mode 100644 puppet/modules/couchdb/templates/admin.ini.erb create mode 100644 puppet/modules/couchdb/templates/bigcouch/default.ini create mode 100644 puppet/modules/couchdb/templates/bigcouch/vm.args create mode 100644 puppet/modules/couchdb/templates/couchdb-backup.py.erb (limited to 'puppet/modules') diff --git a/puppet/modules/couchdb/.fixtures.yml b/puppet/modules/couchdb/.fixtures.yml new file mode 100644 index 00000000..50c6c9ac --- /dev/null +++ b/puppet/modules/couchdb/.fixtures.yml @@ -0,0 +1,6 @@ +fixtures: + symlinks: + couchdb: "#{source_dir}" + repositories: + stdlib: " https://leap.se/git/puppet_stdlib" + diff --git a/puppet/modules/couchdb/.gitrepo b/puppet/modules/couchdb/.gitrepo new file mode 100644 index 00000000..d72ab390 --- /dev/null +++ b/puppet/modules/couchdb/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_couchdb + branch = master + commit = 76ff149a095023611c05bbb00157d06f87b07c05 + parent = 81210aea5cf136194598e7a399ce307ecbe088f1 + cmdver = 0.3.0 diff --git a/puppet/modules/couchdb/Gemfile b/puppet/modules/couchdb/Gemfile new file mode 100644 index 00000000..1c86e980 --- /dev/null +++ b/puppet/modules/couchdb/Gemfile @@ -0,0 +1,11 @@ +source "https://rubygems.org" + +group :test do + gem "rake" + gem "puppet", ENV['PUPPET_VERSION'] || '~> 3.7.0' + gem "rspec", '< 3.2.0' + gem "rspec-puppet" + gem "puppetlabs_spec_helper" + gem "metadata-json-lint" + gem "rspec-puppet-facts" +end diff --git a/puppet/modules/couchdb/README.md b/puppet/modules/couchdb/README.md new file mode 100644 index 00000000..096221a4 --- /dev/null +++ b/puppet/modules/couchdb/README.md @@ -0,0 +1,32 @@ +# Couchdb Puppet module + +This module is based on the one from Camptocamp_. + +.. _Camptocamp: http://www.camptocamp.com/ + +For more information about couchdb see http://couchdb.apache.org/ + +# Dependencies + +- ruby module from the shared-modules group + +# Couchdb debian packages + +## Jessie + +There are no couchdb packages for jessie, so the only way is to +to configure apt to install couchdb from unstable by adding a +sources list file to `/etc/apt/sources.list.d`. + +## Example usage + +This will setup couchdb: + + # needed for wget call, which is unqualified by purpose so we don't force + # a location for the wget binary + Exec { path => '/usr/bin:/usr/sbin/:/bin:/sbin:/usr/local/bin:/usr/local/sbin' } + + class { 'couchdb': + admin_pw => '123' + } + diff --git a/puppet/modules/couchdb/Rakefile b/puppet/modules/couchdb/Rakefile new file mode 100644 index 00000000..85326bb4 --- /dev/null +++ b/puppet/modules/couchdb/Rakefile @@ -0,0 +1,19 @@ +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' +PuppetLint.configuration.send('disable_80chars') +PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"] + +desc "Validate manifests, templates, and ruby files" +task :validate do + Dir['manifests/**/*.pp'].each do |manifest| + sh "puppet parser validate --noop #{manifest}" + end + Dir['spec/**/*.rb','lib/**/*.rb'].each do |ruby_file| + sh "ruby -c #{ruby_file}" unless ruby_file =~ /spec\/fixtures/ + end + Dir['templates/**/*.erb'].each do |template| + sh "erb -P -x -T '-' #{template} | ruby -c" + end +end + +task :test => [:lint, :syntax , :validate, :spec] diff --git a/puppet/modules/couchdb/files/Debian/couchdb b/puppet/modules/couchdb/files/Debian/couchdb new file mode 100755 index 00000000..ccdfe716 --- /dev/null +++ b/puppet/modules/couchdb/files/Debian/couchdb @@ -0,0 +1,160 @@ +#!/bin/sh -e + +# 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. + +### BEGIN INIT INFO +# Provides: couchdb +# Required-Start: $local_fs $remote_fs +# Required-Stop: $local_fs $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Apache CouchDB init script +# Description: Apache CouchDB init script for the database server. +### END INIT INFO + +SCRIPT_OK=0 +SCRIPT_ERROR=1 + +DESCRIPTION="database server" +NAME=couchdb +SCRIPT_NAME=`basename $0` +COUCHDB=/usr/bin/couchdb +CONFIGURATION_FILE=/etc/default/couchdb +RUN_DIR=/var/run/couchdb +LSB_LIBRARY=/lib/lsb/init-functions + +if test ! -x $COUCHDB; then + exit $SCRIPT_ERROR +fi + +if test -r $CONFIGURATION_FILE; then + . $CONFIGURATION_FILE +fi + +log_daemon_msg () { + # Dummy function to be replaced by LSB library. + + echo $@ +} + +log_end_msg () { + # Dummy function to be replaced by LSB library. + + if test "$1" != "0"; then + echo "Error with $DESCRIPTION: $NAME" + fi + return $1 +} + +if test -r $LSB_LIBRARY; then + . $LSB_LIBRARY +fi + +run_command () { + command="$1" + if test -n "$COUCHDB_OPTIONS"; then + command="$command $COUCHDB_OPTIONS" + fi + if test -n "$COUCHDB_USER"; then + if su $COUCHDB_USER -c "$command"; then + return $SCRIPT_OK + else + return $SCRIPT_ERROR + fi + else + if $command; then + return $SCRIPT_OK + else + return $SCRIPT_ERROR + fi + fi +} + +start_couchdb () { + # Start Apache CouchDB as a background process. + + mkdir -p "$RUN_DIR" + chown -R "$COUCHDB_USER" "$RUN_DIR" + command="$COUCHDB -b" + if test -n "$COUCHDB_STDOUT_FILE"; then + command="$command -o $COUCHDB_STDOUT_FILE" + fi + if test -n "$COUCHDB_STDERR_FILE"; then + command="$command -e $COUCHDB_STDERR_FILE" + fi + if test -n "$COUCHDB_RESPAWN_TIMEOUT"; then + command="$command -r $COUCHDB_RESPAWN_TIMEOUT" + fi + run_command "$command" > /dev/null +} + +stop_couchdb () { + # Stop the running Apache CouchDB process. + + run_command "$COUCHDB -d" > /dev/null + pkill -u couchdb + # always return true even if no remaining couchdb procs got killed + /bin/true +} + +display_status () { + # Display the status of the running Apache CouchDB process. + + run_command "$COUCHDB -s" +} + +parse_script_option_list () { + # Parse arguments passed to the script and take appropriate action. + + case "$1" in + start) + log_daemon_msg "Starting $DESCRIPTION" $NAME + if start_couchdb; then + log_end_msg $SCRIPT_OK + else + log_end_msg $SCRIPT_ERROR + fi + ;; + stop) + log_daemon_msg "Stopping $DESCRIPTION" $NAME + if stop_couchdb; then + log_end_msg $SCRIPT_OK + else + log_end_msg $SCRIPT_ERROR + fi + ;; + restart|force-reload) + log_daemon_msg "Restarting $DESCRIPTION" $NAME + if stop_couchdb; then + if start_couchdb; then + log_end_msg $SCRIPT_OK + else + log_end_msg $SCRIPT_ERROR + fi + else + log_end_msg $SCRIPT_ERROR + fi + ;; + status) + display_status + ;; + *) + cat << EOF >&2 +Usage: $SCRIPT_NAME {start|stop|restart|force-reload|status} +EOF + exit $SCRIPT_ERROR + ;; + esac +} + +parse_script_option_list $@ diff --git a/puppet/modules/couchdb/files/couch-doc-diff b/puppet/modules/couchdb/files/couch-doc-diff new file mode 100644 index 00000000..a5907d5e --- /dev/null +++ b/puppet/modules/couchdb/files/couch-doc-diff @@ -0,0 +1,17 @@ +#!/bin/bash + +# Run a diff between a couch document specified as the first parameter +# and the second parameter. +# Diff returns 0 if there is no difference. This way you can tell the data +# is already on the couch. +# Both the couch document and the second paramter will be pretty printed +# before comparison so differences in spaces etc. do not matter. +# All keys starting with an underscore on the couch such as _id and _rev +# will be removed before the comparison - we assume we want to compare +# the real data, not the metadata about the document as we usually do not +# know or care about what the id and revision will be. + +curl -s --netrc-file /etc/couchdb/couchdb.netrc $1 \ + | python -mjson.tool \ + | grep -v '^\s*"_' \ + | diff -w - <(echo $2 | python -mjson.tool) diff --git a/puppet/modules/couchdb/files/couch-doc-update b/puppet/modules/couchdb/files/couch-doc-update new file mode 100644 index 00000000..a137e7ff --- /dev/null +++ b/puppet/modules/couchdb/files/couch-doc-update @@ -0,0 +1,219 @@ +#!/usr/bin/ruby +require 'syslog' + +# +# This script will delete or update the values of a particular couchdb document. The benefit of this little script over +# using a simple curl command for updating a document is this: +# +# * exit non-zero status if document was not updated. +# * updates existing documents easily, taking care of the _rev id for you. +# * if document doesn't exist, it is created +# +# REQUIREMENTS +# +# gem 'couchrest' +# +# USAGE +# +# see the ouput of +# +# couch-doc-update +# +# the content of will be merged with the data provided. +# If you only want the file content use --data '{}' +# +# EXAMPLE +# +# create a new user: +# couch-doc-update --db _users --id org.couchdb.user:ca_daemon --data '{"type": "user", "name": "ca_daemon", "roles": ["certs"], "password": "sshhhh"}' +# +# update a user: +# couch-doc-update --db _users --id org.couchdb.user:ca_daemon --data '{"password":"sssshhh"}' +# +# To update the _users DB on bigcouch, you must connect to port 5986 instead of the default couchdb port 5984 +# +# delete a doc: +# couch-doc-update --delete --db invite_codes --id dfaf0ee65670c16d5a9161dc86f3bff8 +# + +begin; require 'rubygems'; rescue LoadError; end # optionally load rubygems +require 'couchrest' + +def main + db, id, data, delete = process_options + + result = if delete + delete_document(db, id) + else + set_document(db, id, data) + end + + exit 0 if result['ok'] + raise StandardError.new(result.inspect) +rescue StandardError => exc + db_without_password = db.to_s.sub(/:[^\/]*@/, ':PASSWORD_HIDDEN@') + indent = " " + log "ERROR: " + exc.to_s + log indent + $@[0..4].join("\n#{indent}") + log indent + "Failed writing to #{db_without_password}/#{id}" + exit 1 +end + +def log(message) + $stderr.puts message + Syslog.open('couch-doc-update') do |logger| + logger.log(Syslog::LOG_CRIT, message) + end +end + +def process_options + # + # parse options + # + host = nil + db_name = nil + doc_id = nil + new_data = nil + filename = nil + netrc_file = nil + delete = false + loop do + case ARGV[0] + when '--host' then ARGV.shift; host = ARGV.shift + when '--db' then ARGV.shift; db_name = ARGV.shift + when '--id' then ARGV.shift; doc_id = ARGV.shift + when '--data' then ARGV.shift; new_data = ARGV.shift + when '--file' then ARGV.shift; filename = ARGV.shift + when '--netrc-file' then ARGV.shift; netrc_file = ARGV.shift + when '--delete' then ARGV.shift; delete = true + when /^-/ then usage("Unknown option: #{ARGV[0].inspect}") + else break + end + end + usage("Missing required option") unless db_name && doc_id && (new_data || delete) + + unless delete + new_data = MultiJson.load(new_data) + new_data.merge!(read_file(filename)) if filename + end + db = CouchRest.database(connection_string(db_name, host, netrc_file)) + return db, doc_id, new_data, delete +end + +def read_file(filename) + data = MultiJson.load( IO.read(filename) ) + # strip off _id and _rev to avoid conflicts + data.delete_if {|k,v| k.start_with? '_'} +end + + # + # update document + # +def set_document(db, id, data) + attempt ||= 1 + doc = get_document(db, id) + if doc + doc.id ||= id + update_document(db, doc, data) + else + create_document(db, id, data) + end +rescue RestClient::Conflict + # retry once, reraise if that does not work + raise if attempt > 1 + attempt += 1 + retry +end + +COUCH_RESPONSE_OK = { 'ok' => true } + +# Deletes document, if exists, with retry +def delete_document(db, id) + attempts ||= 1 + doc = get_document(db, id) + if doc + db.delete_doc(doc) + else + COUCH_RESPONSE_OK + end +rescue RestClient::ExceptionWithResponse => e + if attempts < 6 && !e.response.nil? && RETRY_CODES.include?(e.response.code) + attempts += 1 + sleep 10 + retry + else + raise e + end +end + +def get_document(db, doc_id) + begin + db.get(doc_id) + rescue RestClient::ResourceNotFound + nil + end +end + +# if the response status code is one of these +# then retry instead of failing. +RETRY_CODES = [500, 422].freeze + +def update_document(db, doc, data) + attempts ||= 1 + doc.reject! {|k,v| !["_id", "_rev"].include? k} + doc.merge! data + db.save_doc(doc) +rescue RestClient::ExceptionWithResponse => e + if attempts < 6 && !e.response.nil? && RETRY_CODES.include?(e.response.code) + attempts += 1 + sleep 10 + retry + else + raise e + end +end + +def create_document(db, doc_id, data) + attempts ||= 1 + data["_id"] = doc_id + db.save_doc(data) +rescue RestClient::ExceptionWithResponse => e + if attempts < 6 && !e.response.nil? && RETRY_CODES.include?(e.response.code) + attempts += 1 + sleep 10 + retry + else + raise e + end +end + +def connection_string(database, host, netrc_file = nil) + protocol = "http" + #hostname = "127.0.0.1" + port = "5984" + username = "admin" + password = "" + + netrc = File.read(netrc_file || '/etc/couchdb/couchdb.netrc') + netrc.scan(/\w+ [\w\.]+/).each do |key_value| + key, value = key_value.split ' ' + case key + when "machine" then host ||= value + ':' + port + when "login" then username = value + when "password" then password = value + end + end + + host ||= '127.0.0.1:5984' + + "%s://%s:%s@%s/%s" % [protocol, username, password, host, database] +end + +def usage(s) + $stderr.puts(s) + $stderr.puts("Usage: #{File.basename($0)} --host --db --id --data [--file ] [--netrc-file ]") + $stderr.puts(" #{File.basename($0)} --host --db --id --delete [--netrc-file ]") + exit(2) +end + +main() diff --git a/puppet/modules/couchdb/files/local.ini b/puppet/modules/couchdb/files/local.ini new file mode 100644 index 00000000..7365b6c6 --- /dev/null +++ b/puppet/modules/couchdb/files/local.ini @@ -0,0 +1,84 @@ +; CouchDB Configuration Settings + +; Custom settings should be made in this file. They will override settings +; in default.ini, but unlike changes made to default.ini, this file won't be +; overwritten on server upgrade. + +[couchdb] +;max_document_size = 4294967296 ; bytes + +[httpd] +;port = 5984 +;bind_address = 127.0.0.1 +; Options for the MochiWeb HTTP server. +;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] +; For more socket options, consult Erlang's module 'inet' man page. +;socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}] + +; Uncomment next line to trigger basic-auth popup on unauthorized requests. +;WWW-Authenticate = Basic realm="administrator" + +; Uncomment next line to set the configuration modification whitelist. Only +; whitelisted values may be changed via the /_config URLs. To allow the admin +; to change this value over HTTP, remember to include {httpd,config_whitelist} +; itself. Excluding it from the list would require editing this file to update +; the whitelist. +;config_whitelist = [{httpd,config_whitelist}, {log,level}, {etc,etc}] + +[httpd_global_handlers] +;_google = {couch_httpd_proxy, handle_proxy_req, <<"http://www.google.com">>} + +[couch_httpd_auth] +; If you set this to true, you should also uncomment the WWW-Authenticate line +; above. If you don't configure a WWW-Authenticate header, CouchDB will send +; Basic realm="server" in order to prevent you getting logged out. +; require_valid_user = false + +[log] +;level = debug + +[os_daemons] +; For any commands listed here, CouchDB will attempt to ensure that +; the process remains alive while CouchDB runs as well as shut them +; down when CouchDB exits. +;foo = /path/to/command -with args + +[daemons] +; enable SSL support by uncommenting the following line and supply the PEM's below. +; the default ssl port CouchDB listens on is 6984 +; httpsd = {couch_httpd, start_link, [https]} + +[ssl] +;cert_file = /full/path/to/server_cert.pem +;key_file = /full/path/to/server_key.pem +;password = somepassword +; set to true to validate peer certificates +verify_ssl_certificates = false +; Path to file containing PEM encoded CA certificates (trusted +; certificates used for verifying a peer certificate). May be omitted if +; you do not want to verify the peer. +;cacert_file = /full/path/to/cacertf +; The verification fun (optionnal) if not specidied, the default +; verification fun will be used. +;verify_fun = {Module, VerifyFun} +ssl_certificate_max_depth = 1 +; To enable Virtual Hosts in CouchDB, add a vhost = path directive. All requests to +; the Virual Host will be redirected to the path. In the example below all requests +; to http://example.com/ are redirected to /database. +; If you run CouchDB on a specific port, include the port number in the vhost: +; example.com:5984 = /database + +[vhosts] +;example.com = /database/ + +[update_notification] +;unique notifier name=/full/path/to/exe -with "cmd line arg" + +; To create an admin account uncomment the '[admins]' section below and add a +; line in the format 'username = password'. When you next start CouchDB, it +; will change the password to a hash (so that your passwords don't linger +; around in plain-text files). You can add more admin accounts with more +; 'username = password' lines. Don't forget to restart CouchDB after +; changing this. +[admins] +;admin = mysecretpassword diff --git a/puppet/modules/couchdb/lib/facter/couchdb_pwhash_alg.rb b/puppet/modules/couchdb/lib/facter/couchdb_pwhash_alg.rb new file mode 100644 index 00000000..60ae701a --- /dev/null +++ b/puppet/modules/couchdb/lib/facter/couchdb_pwhash_alg.rb @@ -0,0 +1,43 @@ +require 'facter' + +def version_parts ( version ) + # gives back a hash containing major, minor and patch numbers + # of a give version string + + parts = Hash.new + first, *rest = version.split(".") + parts["major"] = first + parts["minor"] = rest[0] + parts["patch"] = rest[1] + return parts +end + +def couchdb_pwhash_alg + # couchdb uses sha1 as pw hash algorithm until v. 1.2, + # but pbkdf2 from v.1.3 on. + # see http://docs.couchdb.org/en/1.4.x/configuring.html for + # details + + couchdb_version = Facter.value(:couchdb_version) + version = version_parts(couchdb_version) + major = version["major"].to_i + alg = case major + when 0 then alg = 'n/a' + when 1 then + minor = version['minor'].to_i + if minor < 3 + alg = 'sha1' + else + alg = 'pbkdf2' + end + else + alg = 'pbkdf2' + end + return alg +end + +Facter.add(:couchdb_pwhash_alg) do + setcode do + couchdb_pwhash_alg + end +end diff --git a/puppet/modules/couchdb/lib/facter/couchdb_version.rb b/puppet/modules/couchdb/lib/facter/couchdb_version.rb new file mode 100644 index 00000000..3a721169 --- /dev/null +++ b/puppet/modules/couchdb/lib/facter/couchdb_version.rb @@ -0,0 +1,34 @@ +require 'facter' + +def deb_installed_version ( name ) + # returns an empty string if package is not installed, + # otherwise the version + + version = `apt-cache policy #{name} | grep Installed 2>&1` + version.slice! " Installed: " + version.slice! "(none)" + return version.strip.chomp +end + +def couchdb_version + bigcouch = deb_installed_version("bigcouch") + if bigcouch.empty? + couchdb = deb_installed_version("couchdb") + if couchdb.empty? + version = 'n/a' + else + version = couchdb + end + else + # bigcouch is currently only available in one version (0.4.2), + # which includes couchdb 1.1.1 + version = '1.1.1' + end + return version +end + +Facter.add(:couchdb_version) do + setcode do + couchdb_version + end +end diff --git a/puppet/modules/couchdb/lib/puppet/parser/functions/couchdblookup.rb b/puppet/modules/couchdb/lib/puppet/parser/functions/couchdblookup.rb new file mode 100644 index 00000000..b9067d2a --- /dev/null +++ b/puppet/modules/couchdb/lib/puppet/parser/functions/couchdblookup.rb @@ -0,0 +1,55 @@ +# +# A basic function to retrieve data in couchdb +# + + +module Puppet::Parser::Functions + newfunction(:couchdblookup, :type => :rvalue) do |args| + require 'json' + require 'open-uri' + + raise Puppet::ParseError, ("couchdblookup(): wrong number of arguments (#{args.length}; must be 2 or 3)") unless args.length.between?(2, 3) + + url = args[0] + key = args[1] + default = args[2] if args.length >= 3 + + begin + json = JSON.parse(open(URI.parse(url)).read) + rescue OpenURI::HTTPError => error + raise Puppet::ParseError, "couchdblookup(): fetching URL #{url} failed with status '#{error.message}'" + rescue Timeout::Error => error + raise Puppet::ParseError, "couchdblookup(): connection to couchdb server timed out: '#{error.message}'" + rescue Errno::ECONNREFUSED => error + raise Puppet::ParseError, "couchdblookup(): connection to couchdb server failed: '#{error.message}'" + rescue JSON::ParserError => error + raise Puppet::ParseError, "couchdblookup(): failed to parse JSON received from couchdb: '#{error.message}'" + rescue StandardError => error + raise Puppet::ParseError, "couchdblookup(): something unexpected happened: '#{error.inspect}'" + end + + result = nil + + if json.has_key?("rows") + + if json['rows'].length > 1 + arr = json['rows'].collect do |x| + x[key] if x.is_a?(Hash) and x.has_key?(key) + end + arr.compact! + result = arr unless arr.empty? + + elsif json['rows'].length == 1 + hash = json['rows'].pop + result = hash[key] if hash.is_a?(Hash) + end + + elsif json.has_key?(key) + result = json[key] + end + + result or default or raise Puppet::ParseError, "couchdblookup(): key '#{key}' not found in JSON object !" + + end +end + diff --git a/puppet/modules/couchdb/lib/puppet/parser/functions/pbkdf2.rb b/puppet/modules/couchdb/lib/puppet/parser/functions/pbkdf2.rb new file mode 100644 index 00000000..46400c9c --- /dev/null +++ b/puppet/modules/couchdb/lib/puppet/parser/functions/pbkdf2.rb @@ -0,0 +1,62 @@ +# +# pbkdf2.rb +# + +module Puppet::Parser::Functions + newfunction(:pbkdf2, :type => :rvalue, :doc => <<-EOS +This converts a password and a salt (and optional iterations and keylength +parameters) to a hash containing the salted SHA1 password hash, salt, +iterations and keylength. +pbkdf2 is used i.e. for couchdb passwords since v1.3. + +Example usage: + $pbkdf2 = pbkdf2($::couchdb::admin_pw, $::couchdb::admin_salt) + $sha1 = $pbkdf2['sha1'] +EOS + ) do |arguments| + require 'openssl' + require 'base64' + + raise(Puppet::ParseError, "pbkdf2(): Wrong number of arguments " + + "passed (#{arguments.size} but we require at least 2)") if arguments.size < 2 + + unless arguments.is_a?(Array) + raise(Puppet::ParseError, 'pbkdf2(): Requires a ' + + "Array argument, you passed: #{password.class}") + end + + password = arguments[0] + salt = arguments[1] + + if arguments.size > 2 + iterations = arguments[2].to_i + else + iterations = 1000 + end + + if arguments.size > 3 + keylength = arguments[3].to_i + else + keylength = 20 + end + + pbkdf2 = OpenSSL::PKCS5::pbkdf2_hmac_sha1( + password, + salt, + iterations, + keylength + ) + + return_hash = Hash.new() + # return hex encoded string + return_hash['sha1'] = pbkdf2.unpack('H*')[0] + return_hash['password'] = password + return_hash['salt'] = salt + return_hash['iterations'] = iterations + return_hash['keylength'] = keylength + + return return_hash + end +end + +# vim: set ts=2 sw=2 et : diff --git a/puppet/modules/couchdb/manifests/add_user.pp b/puppet/modules/couchdb/manifests/add_user.pp new file mode 100644 index 00000000..29c6a8c8 --- /dev/null +++ b/puppet/modules/couchdb/manifests/add_user.pp @@ -0,0 +1,39 @@ +define couchdb::add_user ( $roles, $pw, $salt = '' ) { + # Couchdb < 1.2 needs a pre-hashed pw and salt + # If you provide a salt, couchdb::add_user will assume that + # $pw is prehashed and pass both parameters to couchdb::update + # If $salt is empty, couchdb::add_user will assume that the pw + # is plaintext and will pass it to couchdb::update + + if $::couchdb::bigcouch == true { + $port = 5986 + } else { + $port = 5984 + } + + if $salt == '' { + # unhashed, plaintext pw, no salt. For couchdb >= 1.2 + $data = "{\"type\": \"user\", \"name\": \"${name}\", \"roles\": ${roles}, \"password\": \"${pw}\"}" + } else { + # prehashed pw with salt, for couchdb < 1.2 + # salt and encrypt pw + # str_and_salt2sha1 is a function from leap's stdlib module + $pw_and_salt = [ $pw, $salt ] + $sha = str_and_salt2sha1($pw_and_salt) + $data = "{\"type\": \"user\", \"name\": \"${name}\", \"roles\": ${roles}, \"password_sha\": \"${sha}\", \"salt\": \"${salt}\"}" + } + + # update the user with the given password unless they already work + couchdb::document { "update_user_${name}": + host => "127.0.0.1:${port}", + db => '_users', + id => "org.couchdb.user:${name}", + data => $data + } + + couchdb::query::setup { $name: + user => $name, + pw => $pw, + } + +} diff --git a/puppet/modules/couchdb/manifests/backup.pp b/puppet/modules/couchdb/manifests/backup.pp new file mode 100644 index 00000000..a477b5b1 --- /dev/null +++ b/puppet/modules/couchdb/manifests/backup.pp @@ -0,0 +1,51 @@ +# configure backup using couchdb-backup.py +class couchdb::backup { + + include couchdb::params + + # used in ERB templates + $bind_address = $couchdb::params::bind_address + $port = $couchdb::params::port + $backupdir = $couchdb::params::backupdir + + file { $couchdb::params::backupdir: + ensure => directory, + mode => '0755', + require => Package['couchdb'], + } + + file { '/usr/local/sbin/couchdb-backup.py': + ensure => present, + owner => root, + group => root, + mode => '0755', + content => template('couchdb/couchdb-backup.py.erb'), + require => File[$couchdb::params::backupdir], + } + + cron { 'couchdb-backup': + command => '/usr/local/sbin/couchdb-backup.py 2> /dev/null', + hour => 3, + minute => 0, + require => File['/usr/local/sbin/couchdb-backup.py'], + } + + case $::operatingsystem { + /Debian|Ubunu/: { + # note: python-couchdb >= 0.8 required, which is found in debian wheezy. + ensure_packages (['python-couchdb', 'python-simplejson'], { + before => File['/usr/local/sbin/couchdb-backup.py'] + }) + } + /RedHat|Centos/: { + exec {'install python-couchdb using easy_install': + command => 'easy_install http://pypi.python.org/packages/2.6/C/CouchDB/CouchDB-0.8-py2.6.egg', + creates => '/usr/lib/python2.6/site-packages/CouchDB-0.8-py2.6.egg', + } + } + default: { + err('This module has not been written to support your operating system') + } + } + +} diff --git a/puppet/modules/couchdb/manifests/base.pp b/puppet/modules/couchdb/manifests/base.pp new file mode 100644 index 00000000..6c7bf25f --- /dev/null +++ b/puppet/modules/couchdb/manifests/base.pp @@ -0,0 +1,124 @@ +# configure couchdb +class couchdb::base { + + if $::couchdb::bigcouch == true { + $couchdb_user = 'bigcouch' + include couchdb::bigcouch + } else { + $couchdb_user = 'couchdb' + } + + # we use package{} here because bigcouch.pp overwrites it and + # this won't work with ensure_packages() + package {'couchdb': + ensure => installed + } + + service { 'couchdb': + ensure => running, + hasstatus => true, + enable => true, + require => Package['couchdb'] + } + + # todo: make host/port configurable + exec { 'wait_for_couchdb': + command => 'wget --retry-connrefused --tries 10 --quiet "http://127.0.0.1:5984" -O /dev/null', + require => Service['couchdb'] + } + + + # couchrest gem is required for couch-doc-update script, + # and it needs the ruby-dev package installed to build + + if versioncmp($::operatingsystemrelease, '8') < 0 { + $couchrest_version = '1.2' + } + else { + # couchrest v1.2.1 doesn't build with default debian jessie rake version + # shipped as debian package (10.3.2) + # see https://leap.se/code/issues/7754 + $couchrest_version = '1.2.0' + } + + ensure_packages('ruby-dev') + ensure_packages('couchrest', { + provider => 'gem', + ensure => $couchrest_version, + require => Package['ruby-dev'] + }) + + File['/usr/local/bin/couch-doc-update'] -> Couchdb::Update <| |> + File['/usr/local/bin/couch-doc-diff'] -> Couchdb::Update <| |> + + Couchdb::Update <| |> -> Couchdb::Document <| |> + + file { + '/usr/local/bin/couch-doc-update': + source => 'puppet:///modules/couchdb/couch-doc-update', + mode => '0755', + owner => 'root', + group => 'root', + require => Package['couchrest']; + + '/usr/local/bin/couch-doc-diff': + source => 'puppet:///modules/couchdb/couch-doc-diff', + mode => '0755', + owner => 'root', + group => 'root', + require => Package['couchrest']; + + '/etc/couchdb/local.ini': + source => [ "puppet:///modules/site_couchdb/${::fqdn}/local.ini", + 'puppet:///modules/site_couchdb/local.ini', + 'puppet:///modules/couchdb/local.ini' ], + notify => Service[couchdb], + owner => $couchdb_user, + group => $couchdb_user, + mode => '0660', + require => Package['couchdb']; + + '/etc/couchdb/local.d': + ensure => directory, + require => Package['couchdb']; + } + + $alg = $::couchdb::pwhash_alg + $salt = $::couchdb::admin_salt + case $alg { + 'sha1': { + # str_and_salt2sha1 is a function from leap's stdlib module + $pw_and_salt = [ $::couchdb::admin_pw, $salt ] + $sha1 = str_and_salt2sha1($pw_and_salt) + $admin_hash = "-hashed-${sha1},${salt}" + } + 'pbkdf2': { + $pbkdf2 = pbkdf2($::couchdb::admin_pw, $::couchdb::admin_salt, 10) + $sha1 = $pbkdf2['sha1'] + $admin_hash = "-pbkdf2-${sha1},${salt},10" + } + default: { fail ("Unknown fact couchdb_pwhash_alg ${::couchdb_pwhash_alg} - Exiting.") } + } + + file { '/etc/couchdb/local.d/admin.ini': + content => template('couchdb/admin.ini.erb'), + mode => '0600', + owner => $couchdb_user, + group => $couchdb_user, + notify => Service[couchdb], + require => File['/etc/couchdb/local.d']; + } + + case $::couchdb::bigcouch { + true: { $restart_command = '/etc/init.d/bigcouch restart; sleep 6' } + default: { $restart_command = '/etc/init.d/couchdb restart; sleep 6' } + } + + exec { 'couchdb_restart': + command => $restart_command, + path => ['/bin', '/usr/bin',], + subscribe => File['/etc/couchdb/local.d/admin.ini', + '/etc/couchdb/local.ini'], + refreshonly => true + } +} diff --git a/puppet/modules/couchdb/manifests/bigcouch.pp b/puppet/modules/couchdb/manifests/bigcouch.pp new file mode 100644 index 00000000..a97411bf --- /dev/null +++ b/puppet/modules/couchdb/manifests/bigcouch.pp @@ -0,0 +1,51 @@ +class couchdb::bigcouch inherits couchdb::base { + + file { + '/opt/bigcouch': + ensure => directory, + mode => '0755'; + + '/etc/couchdb': + ensure => directory, + mode => '0755', + before => Package['couchdb']; + + '/opt/bigcouch/etc': + ensure => link, + target => '/etc/couchdb', + before => Package['couchdb']; + } + + # there's no bigcouch in the official debian repo, you need + # to setup a repository for that. You can use class + # couchdb::bigcouch::package::cloudant for unauthenticated 0.4.0 packages, + # or site_apt::leap_repo from the leap_platfrom repository + # for signed 0.4.2 packages + + Package['couchdb'] { + name => 'bigcouch' + } + + file { '/opt/bigcouch/etc/vm.args': + content => template('couchdb/bigcouch/vm.args'), + mode => '0640', + owner => 'bigcouch', + group => 'bigcouch', + require => Package['couchdb'], + notify => Service[couchdb] + } + + file { '/opt/bigcouch/etc/default.ini': + content => template('couchdb/bigcouch/default.ini'), + mode => '0640', + owner => 'bigcouch', + group => 'bigcouch', + require => Package['couchdb'], + notify => Service[couchdb] + } + + Service['couchdb'] { + name => 'bigcouch' + } + +} diff --git a/puppet/modules/couchdb/manifests/bigcouch/add_node.pp b/puppet/modules/couchdb/manifests/bigcouch/add_node.pp new file mode 100644 index 00000000..ed9db94b --- /dev/null +++ b/puppet/modules/couchdb/manifests/bigcouch/add_node.pp @@ -0,0 +1,8 @@ +define couchdb::bigcouch::add_node { + + couchdb::bigcouch::document { "add_${name}": + db => 'nodes', + id => "bigcouch@${name}", + ensure => 'present' + } +} diff --git a/puppet/modules/couchdb/manifests/bigcouch/debian.pp b/puppet/modules/couchdb/manifests/bigcouch/debian.pp new file mode 100644 index 00000000..645c6da8 --- /dev/null +++ b/puppet/modules/couchdb/manifests/bigcouch/debian.pp @@ -0,0 +1,11 @@ +class couchdb::bigcouch::debian inherits couchdb::debian { + + File['/etc/init.d/couchdb'] { + ensure => absent + } + + file {'/etc/init.d/bigcouch': + ensure => link, + target => '/usr/bin/sv' + } +} diff --git a/puppet/modules/couchdb/manifests/bigcouch/document.pp b/puppet/modules/couchdb/manifests/bigcouch/document.pp new file mode 100644 index 00000000..13f4ac17 --- /dev/null +++ b/puppet/modules/couchdb/manifests/bigcouch/document.pp @@ -0,0 +1,14 @@ +define couchdb::bigcouch::document ( + $db, + $id, + $host = '127.0.0.1:5986', + $data ='{}', + $ensure ='content') { + couchdb::document { $name: + ensure => $ensure, + host => $host, + db => $db, + id => $id, + data => $data + } +} diff --git a/puppet/modules/couchdb/manifests/bigcouch/package/cloudant.pp b/puppet/modules/couchdb/manifests/bigcouch/package/cloudant.pp new file mode 100644 index 00000000..cfdcf10c --- /dev/null +++ b/puppet/modules/couchdb/manifests/bigcouch/package/cloudant.pp @@ -0,0 +1,35 @@ +class couchdb::bigcouch::package::cloudant ( + $ensure = 'present' +) { + + # cloudant's signing key can be fetched from + # http://packages.cloudant.com/KEYS, please use the apt module to + # distribute it on your servers after verifying its fingerprint + + # cloudant's wheezy repo will fail cause in their Release file + # (http://packages.cloudant.com/debian/dists/wheezy/Release) they + # wrongly marked the packages for squeeze + # so we will use their squeeze repo here + apt::sources_list {'bigcouch-cloudant.list': + ensure => $ensure, + content => 'deb http://packages.cloudant.com/debian squeeze main' + } + + # right now, cloudant only provides authenticated bigcouch 0.4.2 packages + # for squeeze, therefore we need to allow the installation of the depending + # packages libicu44 and libssl0.9.8 from squeeze + + if $::lsbdistcodename == 'wheezy' { + apt::sources_list {'squeeze.list': + ensure => $ensure, + content => 'deb http://http.debian.net/debian squeeze main +deb http://security.debian.org/ squeeze/updates main +' } + apt::preferences_snippet { 'bigcouch_squeeze_deps': + ensure => $ensure, + package => 'libicu44 libssl0.9.8', + priority => '980', + pin => 'release o=Debian,n=squeeze' + } + } +} diff --git a/puppet/modules/couchdb/manifests/create_db.pp b/puppet/modules/couchdb/manifests/create_db.pp new file mode 100644 index 00000000..8a8d1144 --- /dev/null +++ b/puppet/modules/couchdb/manifests/create_db.pp @@ -0,0 +1,21 @@ +define couchdb::create_db ( + $host='127.0.0.1:5984', + $admins="{\"names\": [], \"roles\": [] }", + $members="{\"names\": [], \"roles\": [] }" ) +{ + + couchdb::query { "create_db_${name}": + cmd => 'PUT', + host => $host, + path => $name, + unless => "/usr/bin/curl -s -f --netrc-file /etc/couchdb/couchdb.netrc ${host}/${name}" + } + + couchdb::document { "${name}_security": + db => $name, + id => '_security', + host => $host, + data => "{ \"admins\": ${admins}, \"members\": ${members} }", + require => Couchdb::Query["create_db_${name}"] + } +} diff --git a/puppet/modules/couchdb/manifests/debian.pp b/puppet/modules/couchdb/manifests/debian.pp new file mode 100644 index 00000000..b83b227a --- /dev/null +++ b/puppet/modules/couchdb/manifests/debian.pp @@ -0,0 +1,15 @@ +# installs initscript and dependent packages on debian +class couchdb::debian inherits couchdb::base { + + ensure_packages('libjs-jquery') + + file { '/etc/init.d/couchdb': + source => [ + 'puppet:///modules/site_couchdb/Debian/couchdb', + 'puppet:///modules/couchdb/Debian/couchdb' ], + mode => '0755', + owner => 'root', + group => 'root', + require => Package['couchdb'] + } +} diff --git a/puppet/modules/couchdb/manifests/deploy_config.pp b/puppet/modules/couchdb/manifests/deploy_config.pp new file mode 100644 index 00000000..2ce1fd20 --- /dev/null +++ b/puppet/modules/couchdb/manifests/deploy_config.pp @@ -0,0 +1,12 @@ +class couchdb::deploy_config { + + file { '/etc/couchdb/local.ini': + source => [ "puppet:///modules/site_couchdb/${::fqdn}/local.ini", + 'puppet:///modules/site_couchdb/local.ini', + 'puppet:///modules/couchdb/local.ini' ], + notify => Service[couchdb], + owner => couchdb, + group => couchdb, + mode => '0660' + } +} diff --git a/puppet/modules/couchdb/manifests/document.pp b/puppet/modules/couchdb/manifests/document.pp new file mode 100644 index 00000000..6180474b --- /dev/null +++ b/puppet/modules/couchdb/manifests/document.pp @@ -0,0 +1,47 @@ +# Usage: +# couchdb::document { id: +# db => "database", +# data => "content", +# ensure => {absent,present,*content*} +# } +# +define couchdb::document( + $db, + $id, + $host = '127.0.0.1:5984', + $data = '{}', + $netrc = '/etc/couchdb/couchdb.netrc', + $ensure = 'content') { + + $url = "${host}/${db}/${id}" + + case $ensure { + default: { err ( "unknown ensure value '${ensure}'" ) } + content: { + exec { "couch-doc-update --netrc-file ${netrc} --host ${host} --db ${db} --id ${id} --data \'${data}\'": + require => Exec['wait_for_couchdb'], + unless => "couch-doc-diff $url '$data'" + } + } + + present: { + couchdb::query { "create_${db}_${id}": + cmd => 'PUT', + host => $host, + path => "${db}/${id}", + require => Exec['wait_for_couchdb'], + unless => "/usr/bin/curl -s -f --netrc-file ${netrc} ${url}" + } + } + + absent: { + couchdb::query { "destroy_${db}_${id}": + cmd => 'DELETE', + host => $host, + path => "${db}/${id}", + require => Exec['wait_for_couchdb'], + unless => "/usr/bin/curl -s -f --netrc-file ${netrc} ${url}" + } + } + } +} diff --git a/puppet/modules/couchdb/manifests/init.pp b/puppet/modules/couchdb/manifests/init.pp new file mode 100644 index 00000000..12598ba0 --- /dev/null +++ b/puppet/modules/couchdb/manifests/init.pp @@ -0,0 +1,31 @@ +# initial couchdb class +class couchdb ( + $admin_pw, + $admin_salt = '', + $bigcouch = false, + $bigcouch_cookie = '', + $ednp_port = '9001', + $chttpd_bind_address = '0.0.0.0', + $pwhash_alg = 'pbkdf2' ) +{ + + # stdlib is needed i.e. for ensure_packages() + include ::stdlib + + case $::operatingsystem { + Debian: { + case $::lsbdistcodename { + /lenny|squeeze|wheezy|jessie/: { + include couchdb::debian + if $bigcouch == true { + include couchdb::bigcouch::debian + } + } + default: { fail "couchdb not available for ${::operatingsystem}/${::lsbdistcodename}" } + } + } + RedHat: { include couchdb::redhat } + } + + ensure_packages('curl') +} diff --git a/puppet/modules/couchdb/manifests/mirror_db.pp b/puppet/modules/couchdb/manifests/mirror_db.pp new file mode 100644 index 00000000..b07b6749 --- /dev/null +++ b/puppet/modules/couchdb/manifests/mirror_db.pp @@ -0,0 +1,21 @@ +define couchdb::mirror_db ( + $host='127.0.0.1:5984', + $from='', + $to='', + $user='replication', + $role='replication' + ) +{ + $source = "${from}/${name}" + if $to == '' { $target = $name } + else { $target = "${to}/${name}" } + + couchdb::document { "${name}_replication": + db => "_replicator", + id => "${name}_replication", + netrc => "/etc/couchdb/couchdb-${user}.netrc", + host => $host, + data => "{ \"source\": \"${source}\", \"target\": \"${target}\", \"continuous\": true, \"user_ctx\": { \"name\": \"${user}\", \"roles\": [\"${role}\"] }, \"owner\": \"${user}\" }", + require => Couchdb::Query["create_db_${name}"] + } +} diff --git a/puppet/modules/couchdb/manifests/params.pp b/puppet/modules/couchdb/manifests/params.pp new file mode 100644 index 00000000..02d5f02e --- /dev/null +++ b/puppet/modules/couchdb/manifests/params.pp @@ -0,0 +1,23 @@ +class couchdb::params { + + $bind_address = $::couchdb_bind_address ? { + '' => '127.0.0.1', + default => $::couchdb_bind_address, + } + + $port = $::couchdb_port ? { + '' => '5984', + default => $::couchdb_port, + } + + $backupdir = $::couchdb_backupdir ? { + '' => '/var/backups/couchdb', + default => $::couchdb_backupdir, + } + + $cert_path = $::couchdb_cert_path ? { + "" => '/etc/couchdb', + default => $::couchdb_cert_path, + } + +} diff --git a/puppet/modules/couchdb/manifests/query.pp b/puppet/modules/couchdb/manifests/query.pp new file mode 100644 index 00000000..9507ca1e --- /dev/null +++ b/puppet/modules/couchdb/manifests/query.pp @@ -0,0 +1,12 @@ +define couchdb::query ( + $cmd, $path, + $netrc='/etc/couchdb/couchdb.netrc', + $host='127.0.0.1:5984', + $data = '{}', + $unless = undef) { + + exec { "/usr/bin/curl -s --netrc-file ${netrc} -X ${cmd} ${host}/${path} --data \'${data}\'": + require => [ Package['curl'], Exec['wait_for_couchdb'] ], + unless => $unless + } +} diff --git a/puppet/modules/couchdb/manifests/query/setup.pp b/puppet/modules/couchdb/manifests/query/setup.pp new file mode 100644 index 00000000..451eb536 --- /dev/null +++ b/puppet/modules/couchdb/manifests/query/setup.pp @@ -0,0 +1,10 @@ +define couchdb::query::setup ($user, $pw, $host='127.0.0.1') { + + file { "/etc/couchdb/couchdb-${user}.netrc": + content => "machine ${host} login ${user} password ${pw}", + mode => '0600', + owner => $::couchdb::base::couchdb_user, + group => $::couchdb::base::couchdb_user, + require => Package['couchdb']; + } +} diff --git a/puppet/modules/couchdb/manifests/redhat.pp b/puppet/modules/couchdb/manifests/redhat.pp new file mode 100644 index 00000000..defa0a94 --- /dev/null +++ b/puppet/modules/couchdb/manifests/redhat.pp @@ -0,0 +1 @@ +class couchdb::redhat inherits couchdb::base {} diff --git a/puppet/modules/couchdb/manifests/ssl/deploy_cert.pp b/puppet/modules/couchdb/manifests/ssl/deploy_cert.pp new file mode 100644 index 00000000..d3e743f1 --- /dev/null +++ b/puppet/modules/couchdb/manifests/ssl/deploy_cert.pp @@ -0,0 +1,28 @@ +define couchdb::ssl::deploy_cert ($cert, $key) { + + include couchdb::params + + file { 'couchdb_cert_directory': + ensure => 'directory', + path => $couchdb::params::cert_path, + mode => '0600', + owner => 'couchdb', + group => 'couchdb'; + } + + file { 'couchdb_cert': + path => "${couchdb::params::cert_path}/server_cert.pem", + mode => '0644', + owner => 'couchdb', + group => 'couchdb', + content => $cert + } + + file { 'couchdb_key': + path => "${couchdb::params::cert_path}/server_key.pem", + mode => '0600', + owner => 'couchdb', + group => 'couchdb', + content => $key + } +} diff --git a/puppet/modules/couchdb/manifests/ssl/generate_cert.pp b/puppet/modules/couchdb/manifests/ssl/generate_cert.pp new file mode 100644 index 00000000..a443250e --- /dev/null +++ b/puppet/modules/couchdb/manifests/ssl/generate_cert.pp @@ -0,0 +1,25 @@ +# configures cert for ssl access +class couchdb::ssl::generate_cert { + + ensure_packages('openssl') + + file { $couchdb::cert_path: + ensure => 'directory', + mode => '0600', + owner => 'couchdb', + group => 'couchdb'; + } + +exec { 'generate-certs': + command => "/usr/bin/openssl req -new -inform PEM -x509 -nodes -days 150 -subj \ +'/C=ZZ/ST=AutoSign/O=AutoSign/localityName=AutoSign/commonName=${::hostname}/organizationalUnitName=AutoSign/emailAddress=AutoSign/' \ +-newkey rsa:2048 -out ${couchdb::cert_path}/couchdb_cert.pem -keyout ${couchdb::cert_path}/couchdb_key.pem", + unless => "/usr/bin/test -f ${couchdb::cert_path}/couchdb_cert.pem && +/usr/bin/test -f ${couchdb::params::cert_path}/couchdb_key.pem", + require => [ + File[$couchdb::params::cert_path], + Exec['make-install'] + ], + notify => Service['couchdb'], + } +} diff --git a/puppet/modules/couchdb/manifests/update.pp b/puppet/modules/couchdb/manifests/update.pp new file mode 100644 index 00000000..b1dba84c --- /dev/null +++ b/puppet/modules/couchdb/manifests/update.pp @@ -0,0 +1,12 @@ +define couchdb::update ( + $db, + $id, + $data, + $host='127.0.0.1:5984', + $unless=undef) { + + exec { "couch-doc-update --host ${host} --db ${db} --id ${id} --data \'${data}\'": + require => Exec['wait_for_couchdb'], + unless => $unless + } +} diff --git a/puppet/modules/couchdb/spec/classes/couchdb_spec.rb b/puppet/modules/couchdb/spec/classes/couchdb_spec.rb new file mode 100644 index 00000000..e8e4174e --- /dev/null +++ b/puppet/modules/couchdb/spec/classes/couchdb_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +describe 'couchdb' do + context 'given it is a wheezy system' do + let(:params) { {:admin_pw => 'foo'} } + let(:facts) do + { + :operatingsystemrelease => '7', + :operatingsystem => 'Debian', + :lsbdistcodename => 'wheezy', + } + end + it "should install couchrest 1.2" do + should contain_package('couchrest').with({ + 'ensure'=> '1.2', + }) + end + end + context 'given it is a jessie system' do + let(:params) { {:admin_pw => 'foo'} } + let(:facts) do + { + :operatingsystemrelease => '8', + :operatingsystem => 'Debian', + :lsbdistcodename => 'jessie', + } + end + it "should install latest couchrest version" do + should contain_package('couchrest').with({ + 'ensure'=> 'latest', + }) + end + end +end + diff --git a/puppet/modules/couchdb/spec/fixtures/manifests/site.pp b/puppet/modules/couchdb/spec/fixtures/manifests/site.pp new file mode 100644 index 00000000..a959fb77 --- /dev/null +++ b/puppet/modules/couchdb/spec/fixtures/manifests/site.pp @@ -0,0 +1,8 @@ +# set a default exec path +# the logoutput exec parameter defaults to "on_error" in puppet 3, +# but to "false" in puppet 2.7, so we need to set this globally here +Exec { + logoutput => on_failure, + path => '/usr/bin:/usr/sbin/:/bin:/sbin:/usr/local/bin:/usr/local/sbin' +} + diff --git a/puppet/modules/couchdb/spec/functions/versioncmp_spec.rb b/puppet/modules/couchdb/spec/functions/versioncmp_spec.rb new file mode 100644 index 00000000..0a244275 --- /dev/null +++ b/puppet/modules/couchdb/spec/functions/versioncmp_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe 'versioncmp' do + it { should run.with_params('7.2','8').and_return(-1) } + it { should run.with_params('7','8').and_return(-1) } + it { should run.with_params('8','8').and_return(0) } + it { should run.with_params('8.1','8').and_return(1) } +end + diff --git a/puppet/modules/couchdb/spec/spec_helper.rb b/puppet/modules/couchdb/spec/spec_helper.rb new file mode 100644 index 00000000..b55ede81 --- /dev/null +++ b/puppet/modules/couchdb/spec/spec_helper.rb @@ -0,0 +1,9 @@ +require 'rspec-puppet' + +fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures')) + +RSpec.configure do |c| + c.module_path = File.join(fixture_path, 'modules') + c.manifest_dir = File.join(fixture_path, 'manifests') + c.environmentpath = File.join(Dir.pwd, 'spec') +end diff --git a/puppet/modules/couchdb/templates/admin.ini.erb b/puppet/modules/couchdb/templates/admin.ini.erb new file mode 100644 index 00000000..479f8bfc --- /dev/null +++ b/puppet/modules/couchdb/templates/admin.ini.erb @@ -0,0 +1,9 @@ +<%- require 'digest' -%> +[admins] +admin = <%= @admin_hash %> + +[couchdb] +<%- # uuid uniquely identifies this couchdb instance. if not set, couchdb will set a random one + # but we want a stable one so that this config file doesn't change all the time. + # Md5 of hostname and ipaddress seems reasonable, but it could be based on anything. -%> +uuid = <%= Digest::MD5.hexdigest(Facter.value("hostname") + Facter.value("ipaddress")) %> diff --git a/puppet/modules/couchdb/templates/bigcouch/default.ini b/puppet/modules/couchdb/templates/bigcouch/default.ini new file mode 100644 index 00000000..a315ddab --- /dev/null +++ b/puppet/modules/couchdb/templates/bigcouch/default.ini @@ -0,0 +1,172 @@ +[couchdb] +database_dir = /opt/bigcouch/var/lib +view_index_dir = /opt/bigcouch/var/lib +max_document_size = 67108864 +os_process_timeout = 5000 +max_dbs_open = 500 +delayed_commits = false + +[cluster] +; Default number of shards for a new database +q = 8 +; Default number of copies of each shard +n = 3 + +[chttpd] +port = 5984 +docroot = /opt/bigcouch/share/www + +; Options for the MochiWeb HTTP server. +;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] + +; For more socket options, consult Erlang's module 'inet' man page. +;socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}] + +bind_address = <%= scope.lookupvar('couchdb::chttpd_bind_address') %> + +[chttps] +port = 6984 + +; cert_file = /full/path/to/server_cert.pem +; key_file = /full/path/to/server_key.pem +; password = somepassword +; also remember to enable the chttps daemon in [daemons] section. + +; set to true to validate peer certificates +verify_ssl_certificates = false + +; Path to file containing PEM encoded CA certificates (trusted +; certificates used for verifying a peer certificate). May be omitted if +; you do not want to verify the peer. +;cacert_file = /full/path/to/cacertf + +; The verification fun (optional) if not specified, the default +; verification fun will be used. +;verify_fun = {Module, VerifyFun} +ssl_certificate_max_depth = 1 + +[httpd] +port = 5986 +bind_address = 127.0.0.1 +authentication_handlers = {couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler} +default_handler = {couch_httpd_db, handle_request} +secure_rewrites = true +vhost_global_handlers = _utils, _uuids, _session, _oauth, _users +allow_jsonp = false +log_max_chunk_size = 1000000 + +[ssl] +port = 6984 + +[log] +file = /opt/bigcouch/var/log/bigcouch.log +level = info +include_sasl = true + +[couch_httpd_auth] +authentication_db = _users +authentication_redirect = /_utils/session.html +require_valid_user = false +timeout = 43200 ; (default to 12 hours) number of seconds before automatic logout +auth_cache_size = 50 ; size is number of cache entries + +[query_servers] +javascript = /opt/bigcouch/bin/couchjs /opt/bigcouch/share/couchjs/main.js + +[query_server_config] +reduce_limit = true +os_process_soft_limit = 100 + +[daemons] +view_manager={couch_view, start_link, []} +external_manager={couch_external_manager, start_link, []} +query_servers={couch_proc_manager, start_link, []} +httpd={couch_httpd, start_link, []} +stats_aggregator={couch_stats_aggregator, start, []} +stats_collector={couch_stats_collector, start, []} +uuids={couch_uuids, start, []} +auth_cache={couch_auth_cache, start_link, []} +replication_manager={couch_replication_manager, start_link, []} +vhosts={couch_httpd_vhost, start_link, []} +os_daemons={couch_os_daemons, start_link, []} +; Uncomment next line to enable SSL daemon +; chttpsd = {chttpd, start_link, [https]} + +[httpd_global_handlers] +/ = {couch_httpd_misc_handlers, handle_welcome_req, <<"Welcome">>} +favicon.ico = {couch_httpd_misc_handlers, handle_favicon_req, "/opt/bigcouch/share/www"} + +_utils = {couch_httpd_misc_handlers, handle_utils_dir_req, "/opt/bigcouch/share/www"} +_all_dbs = {couch_httpd_misc_handlers, handle_all_dbs_req} +_active_tasks = {couch_httpd_misc_handlers, handle_task_status_req} +_config = {couch_httpd_misc_handlers, handle_config_req} +_replicate = {couch_httpd_misc_handlers, handle_replicate_req} +_uuids = {couch_httpd_misc_handlers, handle_uuids_req} +_restart = {couch_httpd_misc_handlers, handle_restart_req} +_stats = {couch_httpd_stats_handlers, handle_stats_req} +_log = {couch_httpd_misc_handlers, handle_log_req} +_session = {couch_httpd_auth, handle_session_req} +_oauth = {couch_httpd_oauth, handle_oauth_req} +_system = {chttpd_misc, handle_system_req} + +[httpd_db_handlers] +_view_cleanup = {couch_httpd_db, handle_view_cleanup_req} +_compact = {couch_httpd_db, handle_compact_req} +_design = {couch_httpd_db, handle_design_req} +_temp_view = {couch_httpd_view, handle_temp_view_req} +_changes = {couch_httpd_db, handle_changes_req} + +[httpd_design_handlers] +_view = {couch_httpd_view, handle_view_req} +_show = {couch_httpd_show, handle_doc_show_req} +_list = {couch_httpd_show, handle_view_list_req} +_info = {couch_httpd_db, handle_design_info_req} +_rewrite = {couch_httpd_rewrite, handle_rewrite_req} +_update = {couch_httpd_show, handle_doc_update_req} + +; enable external as an httpd handler, then link it with commands here. +; note, this api is still under consideration. +; [external] +; mykey = /path/to/mycommand + +; Here you can setup commands for CouchDB to manage +; while it is alive. It will attempt to keep each command +; alive if it exits. +; [os_daemons] +; some_daemon_name = /path/to/script -with args + + +[uuids] +; Known algorithms: +; random - 128 bits of random awesome +; All awesome, all the time. +; sequential - monotonically increasing ids with random increments +; First 26 hex characters are random. Last 6 increment in +; random amounts until an overflow occurs. On overflow, the +; random prefix is regenerated and the process starts over. +; utc_random - Time since Jan 1, 1970 UTC with microseconds +; First 14 characters are the time in hex. Last 18 are random. +algorithm = sequential + +[stats] +; rate is in milliseconds +rate = 1000 +; sample intervals are in seconds +samples = [0, 60, 300, 900] + +[attachments] +compression_level = 8 ; from 1 (lowest, fastest) to 9 (highest, slowest), 0 to disable compression +compressible_types = text/*, application/javascript, application/json, application/xml + +[replicator] +db = _replicator +; Maximum replicaton retry count can be a non-negative integer or "infinity". +max_replication_retry_count = 10 +max_http_sessions = 20 +max_http_pipeline_size = 50 +; set to true to validate peer certificates +verify_ssl_certificates = false +; file containing a list of peer trusted certificates (PEM format) +; ssl_trusted_certificates_file = /etc/ssl/certs/ca-certificates.crt +; maximum peer certificate depth (must be set even if certificate validation is off) +ssl_certificate_max_depth = 3 diff --git a/puppet/modules/couchdb/templates/bigcouch/vm.args b/puppet/modules/couchdb/templates/bigcouch/vm.args new file mode 100644 index 00000000..4618a52c --- /dev/null +++ b/puppet/modules/couchdb/templates/bigcouch/vm.args @@ -0,0 +1,32 @@ +# Each node in the system must have a unique name. A name can be short +# (specified using -sname) or it can by fully qualified (-name). There can be +# no communication between nodes running with the -sname flag and those running +# with the -name flag. +-name bigcouch + +# All nodes must share the same magic cookie for distributed Erlang to work. +# Comment out this line if you synchronized the cookies by other means (using +# the ~/.erlang.cookie file, for example). +-setcookie <%= scope.lookupvar('couchdb::bigcouch_cookie') %> + +# Tell SASL not to log progress reports +-sasl errlog_type error + +# Use kernel poll functionality if supported by emulator ++K true + +# Start a pool of asynchronous IO threads ++A 16 + +# Comment this line out to enable the interactive Erlang shell on startup ++Bd -noinput + +# read config files +# otherwise /etc/couchdb/local.d/admin.ini wouldn't be read mysteriously +-couch_ini /etc/couchdb/default.ini /etc/couchdb/local.ini /etc/couchdb/local.d/admin.ini /etc/couchdb/default.ini /etc/couchdb/local.ini /etc/couchdb/local.d/admin.ini +# + +# make firewalling easier, see +# http://stackoverflow.com/questions/8459949/bigcouch-cluster-connection-issue#comment10467603_8463814 + +-kernel inet_dist_listen_min <%= scope.lookupvar('couchdb::ednp_port') %> inet_dist_use_interface "{127,0,0,1}" diff --git a/puppet/modules/couchdb/templates/couchdb-backup.py.erb b/puppet/modules/couchdb/templates/couchdb-backup.py.erb new file mode 100644 index 00000000..c49df65b --- /dev/null +++ b/puppet/modules/couchdb/templates/couchdb-backup.py.erb @@ -0,0 +1,32 @@ +#!/usr/bin/env python +# file manage by puppet + +import os +import gzip +import tarfile +import datetime +import urllib2 +import simplejson +import couchdb.tools.dump +from os.path import join + +DB_URL="http://127.0.0.1:5984" +DUMP_DIR="<%= backupdir %>" +TODAY=datetime.datetime.today().strftime("%A").lower() + +ftar = os.path.join(DUMP_DIR,"%s.tar" % TODAY) +tmp_ftar = os.path.join(DUMP_DIR,"_%s.tar" % TODAY) +tar = tarfile.open(tmp_ftar, "w") + +databases = simplejson.load(urllib2.urlopen("%s/_all_dbs" % DB_URL)) + +for db in databases: + db_file = os.path.join(DUMP_DIR,"%s.gz" % db) + f = gzip.open(db_file, 'wb') + couchdb.tools.dump.dump_db(os.path.join(DB_URL,db), output=f) + f.close() + tar.add(db_file,"%s.gz" % db) + os.remove(db_file) + +tar.close() +os.rename(tmp_ftar,ftar) -- cgit v1.2.3 From 4aff06cc2fecc0b59728d7fc825fb36394b847b7 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:45:58 -0400 Subject: git subrepo clone https://leap.se/git/puppet_apache puppet/modules/apache subrepo: subdir: "puppet/modules/apache" merged: "415e950" upstream: origin: "https://leap.se/git/puppet_apache" branch: "master" commit: "415e950" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: Iba7353669969a09c0b4bbd63add67e3245b05ede --- puppet/modules/apache/.gitignore | 6 + puppet/modules/apache/.gitrepo | 11 + puppet/modules/apache/.rspec | 2 + puppet/modules/apache/Gemfile | 13 + puppet/modules/apache/LICENSE | 674 ++++++++++++ puppet/modules/apache/Puppetfile | 15 + puppet/modules/apache/README.md | 233 ++++ puppet/modules/apache/Rakefile | 26 + puppet/modules/apache/files/conf.d/CentOS/ssl.conf | 76 ++ .../apache/files/conf.d/CentOS/welcome.conf | 10 + puppet/modules/apache/files/conf.d/Debian/charset | 6 + puppet/modules/apache/files/conf.d/Debian/security | 50 + puppet/modules/apache/files/conf.d/Debian/ssl.conf | 1 + .../modules/apache/files/conf.d/do_includes.conf | 5 + puppet/modules/apache/files/conf.d/git.conf | 5 + .../apache/files/conf.d/mozilla_autoconfig.conf | 6 + puppet/modules/apache/files/conf.d/status.conf | 24 + puppet/modules/apache/files/conf.d/vhosts.conf | 8 + .../apache/files/config/Debian.jessie/apache2.conf | 221 ++++ .../apache/files/config/Debian.wheezy/apache2.conf | 268 +++++ .../apache/files/config/Debian/apache2.conf | 230 ++++ .../modules/apache/files/config/OpenBSD/httpd.conf | 1120 ++++++++++++++++++++ puppet/modules/apache/files/include.d/defaults.inc | 5 + puppet/modules/apache/files/include.d/joomla.inc | 30 + .../apache/files/include.d/silverstripe.inc | 17 + .../apache/files/itk_plus/conf.d/CentOS/ssl.conf | 75 ++ .../modules.d/Gentoo/00_default_settings.conf | 105 ++ .../files/modules.d/Gentoo/00_error_documents.conf | 66 ++ .../files/modules.d/Gentoo/00_languages.conf | 137 +++ .../files/modules.d/Gentoo/00_mod_autoindex.conf | 83 ++ .../apache/files/modules.d/Gentoo/00_mod_info.conf | 14 + .../files/modules.d/Gentoo/00_mod_log_config.conf | 35 + .../apache/files/modules.d/Gentoo/00_mod_mime.conf | 55 + .../files/modules.d/Gentoo/00_mod_status.conf | 19 + .../files/modules.d/Gentoo/00_mod_userdir.conf | 40 + .../apache/files/modules.d/Gentoo/00_mpm.conf | 102 ++ .../files/modules.d/Gentoo/10_mod_mem_cache.conf | 10 + .../apache/files/modules.d/Gentoo/40_mod_ssl.conf | 65 ++ .../apache/files/modules.d/Gentoo/45_mod_dav.conf | 56 + .../apache/files/modules.d/Gentoo/46_mod_ldap.conf | 29 + .../apache/files/modules.d/Gentoo/70_mod_php5.conf | 18 + puppet/modules/apache/files/munin/apache_activity | 99 ++ .../files/scripts/OpenBSD/bin/apache_logrotate.sh | 7 + .../files/scripts/OpenBSD/bin/restart_apache.sh | 6 + .../scripts/OpenBSD/bin/restart_apache_ssl.sh | 6 + puppet/modules/apache/files/service/CentOS/httpd | 22 + .../modules/apache/files/service/CentOS/httpd.itk | 23 + .../apache/files/service/CentOS/httpd.itk_plus | 24 + .../apache/files/service/CentOS/httpd.worker | 22 + .../apache/files/vhosts.d/CentOS/0-default.conf | 11 + .../apache/files/vhosts.d/Debian/0-default.conf | 41 + .../apache/files/vhosts.d/Gentoo/0-default.conf | 51 + .../files/vhosts.d/Gentoo/default_vhost.include | 79 ++ .../apache/files/vhosts.d/OpenBSD/0-default.conf | 8 + puppet/modules/apache/lib/facter/apache_version.rb | 28 + .../parser/functions/guess_apache_version.rb | 39 + .../lib/puppet/parser/functions/htpasswd_sha1.rb | 8 + puppet/modules/apache/manifests/base.pp | 75 ++ puppet/modules/apache/manifests/base/itk.pp | 6 + puppet/modules/apache/manifests/centos.pp | 86 ++ puppet/modules/apache/manifests/centos/itk.pp | 10 + puppet/modules/apache/manifests/centos/itk_plus.pp | 20 + puppet/modules/apache/manifests/centos/module.pp | 30 + puppet/modules/apache/manifests/centos/worker.pp | 5 + puppet/modules/apache/manifests/config/file.pp | 106 ++ puppet/modules/apache/manifests/config/global.pp | 18 + puppet/modules/apache/manifests/config/include.pp | 17 + puppet/modules/apache/manifests/debian.pp | 44 + puppet/modules/apache/manifests/debian/itk.pp | 9 + puppet/modules/apache/manifests/debian/module.pp | 48 + puppet/modules/apache/manifests/defaultdavdbdir.pp | 17 + puppet/modules/apache/manifests/defaultphpdirs.pp | 31 + puppet/modules/apache/manifests/file.pp | 15 + puppet/modules/apache/manifests/file/readonly.pp | 12 + puppet/modules/apache/manifests/file/rw.pp | 13 + puppet/modules/apache/manifests/gentoo.pp | 39 + puppet/modules/apache/manifests/gentoo/module.pp | 30 + puppet/modules/apache/manifests/htpasswd_user.pp | 34 + puppet/modules/apache/manifests/include/joomla.pp | 3 + .../modules/apache/manifests/include/mod_fcgid.pp | 7 + .../apache/manifests/include/silverstripe.pp | 3 + puppet/modules/apache/manifests/includes.pp | 5 + puppet/modules/apache/manifests/init.pp | 44 + puppet/modules/apache/manifests/itk.pp | 11 + puppet/modules/apache/manifests/itk/lock.pp | 4 + puppet/modules/apache/manifests/itk_plus.pp | 10 + puppet/modules/apache/manifests/itk_plus/lock.pp | 4 + .../modules/apache/manifests/logrotate/centos.pp | 10 + .../apache/manifests/logrotate/centos/vhosts.pp | 11 + puppet/modules/apache/manifests/mod_dav_svn.pp | 7 + puppet/modules/apache/manifests/mod_macro.pp | 7 + puppet/modules/apache/manifests/module.pp | 35 + puppet/modules/apache/manifests/module/alias.pp | 14 + .../modules/apache/manifests/module/auth_basic.pp | 6 + .../modules/apache/manifests/module/authn_core.pp | 6 + .../modules/apache/manifests/module/authn_file.pp | 6 + .../modules/apache/manifests/module/authz_core.pp | 7 + .../modules/apache/manifests/module/authz_host.pp | 6 + .../modules/apache/manifests/module/authz_user.pp | 6 + puppet/modules/apache/manifests/module/cgi.pp | 6 + puppet/modules/apache/manifests/module/dir.pp | 6 + puppet/modules/apache/manifests/module/env.pp | 7 + puppet/modules/apache/manifests/module/expires.pp | 5 + puppet/modules/apache/manifests/module/headers.pp | 6 + puppet/modules/apache/manifests/module/mime.pp | 6 + .../modules/apache/manifests/module/mpm_event.pp | 7 + .../modules/apache/manifests/module/mpm_prefork.pp | 6 + .../modules/apache/manifests/module/negotiation.pp | 6 + puppet/modules/apache/manifests/module/php5.pp | 6 + puppet/modules/apache/manifests/module/removeip.pp | 6 + puppet/modules/apache/manifests/module/rewrite.pp | 6 + .../apache/manifests/module/socache_shmcb.pp | 6 + puppet/modules/apache/manifests/module/status.pp | 6 + .../modules/apache/manifests/mozilla_autoconfig.pp | 37 + puppet/modules/apache/manifests/munin.pp | 12 + puppet/modules/apache/manifests/noiplog.pp | 5 + puppet/modules/apache/manifests/openbsd.pp | 75 ++ puppet/modules/apache/manifests/package.pp | 32 + puppet/modules/apache/manifests/package/itk.pp | 5 + puppet/modules/apache/manifests/sftponly.pp | 5 + puppet/modules/apache/manifests/sftponly/centos.pp | 10 + puppet/modules/apache/manifests/ssl.pp | 13 + puppet/modules/apache/manifests/ssl/base.pp | 15 + puppet/modules/apache/manifests/ssl/centos.pp | 12 + puppet/modules/apache/manifests/ssl/debian.pp | 4 + puppet/modules/apache/manifests/ssl/itk.pp | 8 + puppet/modules/apache/manifests/ssl/itk/centos.pp | 6 + puppet/modules/apache/manifests/ssl/itk_plus.pp | 6 + .../apache/manifests/ssl/itk_plus/centos.pp | 11 + puppet/modules/apache/manifests/ssl/openbsd.pp | 18 + puppet/modules/apache/manifests/status.pp | 13 + puppet/modules/apache/manifests/status/base.pp | 1 + puppet/modules/apache/manifests/status/centos.pp | 5 + puppet/modules/apache/manifests/status/debian.pp | 4 + puppet/modules/apache/manifests/vhost.pp | 127 +++ puppet/modules/apache/manifests/vhost/davdbdir.pp | 40 + puppet/modules/apache/manifests/vhost/file.pp | 151 +++ .../apache/manifests/vhost/file/documentrootdir.pp | 24 + .../manifests/vhost/file/documentrootfile.pp | 27 + puppet/modules/apache/manifests/vhost/gitweb.pp | 59 ++ puppet/modules/apache/manifests/vhost/modperl.pp | 153 +++ puppet/modules/apache/manifests/vhost/passenger.pp | 139 +++ .../modules/apache/manifests/vhost/php/drupal.pp | 144 +++ .../modules/apache/manifests/vhost/php/gallery2.pp | 141 +++ .../manifests/vhost/php/global_exec_bin_dir.pp | 9 + .../modules/apache/manifests/vhost/php/joomla.pp | 174 +++ .../apache/manifests/vhost/php/mediawiki.pp | 106 ++ .../apache/manifests/vhost/php/safe_mode_bin.pp | 17 + .../apache/manifests/vhost/php/silverstripe.pp | 119 +++ .../apache/manifests/vhost/php/simplemachine.pp | 125 +++ puppet/modules/apache/manifests/vhost/php/spip.pp | 114 ++ .../modules/apache/manifests/vhost/php/standard.pp | 304 ++++++ puppet/modules/apache/manifests/vhost/php/typo3.pp | 150 +++ .../modules/apache/manifests/vhost/php/webapp.pp | 148 +++ .../apache/manifests/vhost/php/wordpress.pp | 123 +++ puppet/modules/apache/manifests/vhost/phpdirs.pp | 39 + puppet/modules/apache/manifests/vhost/proxy.pp | 67 ++ puppet/modules/apache/manifests/vhost/redirect.pp | 56 + puppet/modules/apache/manifests/vhost/static.pp | 86 ++ puppet/modules/apache/manifests/vhost/template.pp | 158 +++ puppet/modules/apache/manifests/vhost/webdav.pp | 126 +++ puppet/modules/apache/manifests/vhost/webdir.pp | 130 +++ puppet/modules/apache/manifests/webdav.pp | 8 + puppet/modules/apache/manifests/worker.pp | 5 + puppet/modules/apache/spec/classes/init_spec.rb | 43 + .../modules/apache/spec/defines/vhost_file_spec.rb | 131 +++ .../apache/spec/defines/vhost_php_drupal_spec.rb | 187 ++++ .../apache/spec/defines/vhost_php_gallery2_spec.rb | 162 +++ .../apache/spec/defines/vhost_php_joomla_spec.rb | 279 +++++ .../apache/spec/defines/vhost_php_standard_spec.rb | 534 ++++++++++ .../apache/spec/defines/vhost_php_webapp_spec.rb | 261 +++++ .../spec/defines/vhost_php_wordpress_spec.rb | 171 +++ puppet/modules/apache/spec/defines/vhost_spec.rb | 202 ++++ .../apache/spec/defines/vhost_static_spec.rb | 54 + .../apache/spec/defines/vhost_template_spec.rb | 297 ++++++ .../apache/spec/functions/guess_apache_version.rb | 50 + puppet/modules/apache/spec/spec_helper.rb | 13 + .../apache/templates/default/default_index.erb | 13 + .../templates/include.d/ssl_defaults.inc.erb | 78 ++ .../itk_plus/CentOS/00-listen-ssl.conf.erb | 6 + .../templates/itk_plus/CentOS/00-listen.conf.erb | 8 + .../apache/templates/vhosts/0-default_ssl.conf.erb | 21 + puppet/modules/apache/templates/vhosts/default.erb | 44 + .../apache/templates/vhosts/gitweb/partial.erb | 16 + .../modules/apache/templates/vhosts/itk_plus.erb | 6 + .../apache/templates/vhosts/itk_plus/partial.erb | 31 + .../templates/vhosts/partials/authentication.erb | 6 + .../templates/vhosts/partials/header_default.erb | 22 + .../apache/templates/vhosts/partials/logs.erb | 18 + .../templates/vhosts/partials/mod_security.erb | 27 + .../templates/vhosts/partials/php_settings.erb | 20 + .../apache/templates/vhosts/partials/ssl.erb | 8 + .../vhosts/partials/std_override_options.erb | 4 + .../apache/templates/vhosts/passenger/partial.erb | 7 + .../apache/templates/vhosts/perl/partial.erb | 14 + .../apache/templates/vhosts/php/partial.erb | 5 + .../apache/templates/vhosts/php_drupal/partial.erb | 22 + .../templates/vhosts/php_gallery2/partial.erb | 14 + .../apache/templates/vhosts/php_joomla/partial.erb | 30 + .../templates/vhosts/php_mediawiki/partial.erb | 7 + .../templates/vhosts/php_silverstripe/partial.erb | 12 + .../apache/templates/vhosts/php_typo3/partial.erb | 10 + .../templates/vhosts/php_wordpress/partial.erb | 19 + .../apache/templates/vhosts/proxy/partial.erb | 8 + .../apache/templates/vhosts/redirect/partial.erb | 1 + .../apache/templates/vhosts/static/partial.erb | 4 + .../apache/templates/vhosts/webdav/partial.erb | 21 + .../templates/webfiles/autoconfig/config.shtml.erb | 58 + 208 files changed, 11717 insertions(+) create mode 100644 puppet/modules/apache/.gitignore create mode 100644 puppet/modules/apache/.gitrepo create mode 100644 puppet/modules/apache/.rspec create mode 100644 puppet/modules/apache/Gemfile create mode 100644 puppet/modules/apache/LICENSE create mode 100644 puppet/modules/apache/Puppetfile create mode 100644 puppet/modules/apache/README.md create mode 100644 puppet/modules/apache/Rakefile create mode 100644 puppet/modules/apache/files/conf.d/CentOS/ssl.conf create mode 100644 puppet/modules/apache/files/conf.d/CentOS/welcome.conf create mode 100644 puppet/modules/apache/files/conf.d/Debian/charset create mode 100644 puppet/modules/apache/files/conf.d/Debian/security create mode 100644 puppet/modules/apache/files/conf.d/Debian/ssl.conf create mode 100644 puppet/modules/apache/files/conf.d/do_includes.conf create mode 100644 puppet/modules/apache/files/conf.d/git.conf create mode 100644 puppet/modules/apache/files/conf.d/mozilla_autoconfig.conf create mode 100644 puppet/modules/apache/files/conf.d/status.conf create mode 100644 puppet/modules/apache/files/conf.d/vhosts.conf create mode 100644 puppet/modules/apache/files/config/Debian.jessie/apache2.conf create mode 100644 puppet/modules/apache/files/config/Debian.wheezy/apache2.conf create mode 100644 puppet/modules/apache/files/config/Debian/apache2.conf create mode 100644 puppet/modules/apache/files/config/OpenBSD/httpd.conf create mode 100644 puppet/modules/apache/files/include.d/defaults.inc create mode 100644 puppet/modules/apache/files/include.d/joomla.inc create mode 100644 puppet/modules/apache/files/include.d/silverstripe.inc create mode 100644 puppet/modules/apache/files/itk_plus/conf.d/CentOS/ssl.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/00_default_settings.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/00_error_documents.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/00_languages.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/00_mod_autoindex.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/00_mod_info.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/00_mod_log_config.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/00_mod_mime.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/00_mod_status.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/00_mod_userdir.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/00_mpm.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/10_mod_mem_cache.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/40_mod_ssl.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/45_mod_dav.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/46_mod_ldap.conf create mode 100644 puppet/modules/apache/files/modules.d/Gentoo/70_mod_php5.conf create mode 100755 puppet/modules/apache/files/munin/apache_activity create mode 100644 puppet/modules/apache/files/scripts/OpenBSD/bin/apache_logrotate.sh create mode 100644 puppet/modules/apache/files/scripts/OpenBSD/bin/restart_apache.sh create mode 100644 puppet/modules/apache/files/scripts/OpenBSD/bin/restart_apache_ssl.sh create mode 100644 puppet/modules/apache/files/service/CentOS/httpd create mode 100644 puppet/modules/apache/files/service/CentOS/httpd.itk create mode 100644 puppet/modules/apache/files/service/CentOS/httpd.itk_plus create mode 100644 puppet/modules/apache/files/service/CentOS/httpd.worker create mode 100644 puppet/modules/apache/files/vhosts.d/CentOS/0-default.conf create mode 100644 puppet/modules/apache/files/vhosts.d/Debian/0-default.conf create mode 100644 puppet/modules/apache/files/vhosts.d/Gentoo/0-default.conf create mode 100644 puppet/modules/apache/files/vhosts.d/Gentoo/default_vhost.include create mode 100644 puppet/modules/apache/files/vhosts.d/OpenBSD/0-default.conf create mode 100644 puppet/modules/apache/lib/facter/apache_version.rb create mode 100644 puppet/modules/apache/lib/puppet/parser/functions/guess_apache_version.rb create mode 100644 puppet/modules/apache/lib/puppet/parser/functions/htpasswd_sha1.rb create mode 100644 puppet/modules/apache/manifests/base.pp create mode 100644 puppet/modules/apache/manifests/base/itk.pp create mode 100644 puppet/modules/apache/manifests/centos.pp create mode 100644 puppet/modules/apache/manifests/centos/itk.pp create mode 100644 puppet/modules/apache/manifests/centos/itk_plus.pp create mode 100644 puppet/modules/apache/manifests/centos/module.pp create mode 100644 puppet/modules/apache/manifests/centos/worker.pp create mode 100644 puppet/modules/apache/manifests/config/file.pp create mode 100644 puppet/modules/apache/manifests/config/global.pp create mode 100644 puppet/modules/apache/manifests/config/include.pp create mode 100644 puppet/modules/apache/manifests/debian.pp create mode 100644 puppet/modules/apache/manifests/debian/itk.pp create mode 100644 puppet/modules/apache/manifests/debian/module.pp create mode 100644 puppet/modules/apache/manifests/defaultdavdbdir.pp create mode 100644 puppet/modules/apache/manifests/defaultphpdirs.pp create mode 100644 puppet/modules/apache/manifests/file.pp create mode 100644 puppet/modules/apache/manifests/file/readonly.pp create mode 100644 puppet/modules/apache/manifests/file/rw.pp create mode 100644 puppet/modules/apache/manifests/gentoo.pp create mode 100644 puppet/modules/apache/manifests/gentoo/module.pp create mode 100644 puppet/modules/apache/manifests/htpasswd_user.pp create mode 100644 puppet/modules/apache/manifests/include/joomla.pp create mode 100644 puppet/modules/apache/manifests/include/mod_fcgid.pp create mode 100644 puppet/modules/apache/manifests/include/silverstripe.pp create mode 100644 puppet/modules/apache/manifests/includes.pp create mode 100644 puppet/modules/apache/manifests/init.pp create mode 100644 puppet/modules/apache/manifests/itk.pp create mode 100644 puppet/modules/apache/manifests/itk/lock.pp create mode 100644 puppet/modules/apache/manifests/itk_plus.pp create mode 100644 puppet/modules/apache/manifests/itk_plus/lock.pp create mode 100644 puppet/modules/apache/manifests/logrotate/centos.pp create mode 100644 puppet/modules/apache/manifests/logrotate/centos/vhosts.pp create mode 100644 puppet/modules/apache/manifests/mod_dav_svn.pp create mode 100644 puppet/modules/apache/manifests/mod_macro.pp create mode 100644 puppet/modules/apache/manifests/module.pp create mode 100644 puppet/modules/apache/manifests/module/alias.pp create mode 100644 puppet/modules/apache/manifests/module/auth_basic.pp create mode 100644 puppet/modules/apache/manifests/module/authn_core.pp create mode 100644 puppet/modules/apache/manifests/module/authn_file.pp create mode 100644 puppet/modules/apache/manifests/module/authz_core.pp create mode 100644 puppet/modules/apache/manifests/module/authz_host.pp create mode 100644 puppet/modules/apache/manifests/module/authz_user.pp create mode 100644 puppet/modules/apache/manifests/module/cgi.pp create mode 100644 puppet/modules/apache/manifests/module/dir.pp create mode 100644 puppet/modules/apache/manifests/module/env.pp create mode 100644 puppet/modules/apache/manifests/module/expires.pp create mode 100644 puppet/modules/apache/manifests/module/headers.pp create mode 100644 puppet/modules/apache/manifests/module/mime.pp create mode 100644 puppet/modules/apache/manifests/module/mpm_event.pp create mode 100644 puppet/modules/apache/manifests/module/mpm_prefork.pp create mode 100644 puppet/modules/apache/manifests/module/negotiation.pp create mode 100644 puppet/modules/apache/manifests/module/php5.pp create mode 100644 puppet/modules/apache/manifests/module/removeip.pp create mode 100644 puppet/modules/apache/manifests/module/rewrite.pp create mode 100644 puppet/modules/apache/manifests/module/socache_shmcb.pp create mode 100644 puppet/modules/apache/manifests/module/status.pp create mode 100644 puppet/modules/apache/manifests/mozilla_autoconfig.pp create mode 100644 puppet/modules/apache/manifests/munin.pp create mode 100644 puppet/modules/apache/manifests/noiplog.pp create mode 100644 puppet/modules/apache/manifests/openbsd.pp create mode 100644 puppet/modules/apache/manifests/package.pp create mode 100644 puppet/modules/apache/manifests/package/itk.pp create mode 100644 puppet/modules/apache/manifests/sftponly.pp create mode 100644 puppet/modules/apache/manifests/sftponly/centos.pp create mode 100644 puppet/modules/apache/manifests/ssl.pp create mode 100644 puppet/modules/apache/manifests/ssl/base.pp create mode 100644 puppet/modules/apache/manifests/ssl/centos.pp create mode 100644 puppet/modules/apache/manifests/ssl/debian.pp create mode 100644 puppet/modules/apache/manifests/ssl/itk.pp create mode 100644 puppet/modules/apache/manifests/ssl/itk/centos.pp create mode 100644 puppet/modules/apache/manifests/ssl/itk_plus.pp create mode 100644 puppet/modules/apache/manifests/ssl/itk_plus/centos.pp create mode 100644 puppet/modules/apache/manifests/ssl/openbsd.pp create mode 100644 puppet/modules/apache/manifests/status.pp create mode 100644 puppet/modules/apache/manifests/status/base.pp create mode 100644 puppet/modules/apache/manifests/status/centos.pp create mode 100644 puppet/modules/apache/manifests/status/debian.pp create mode 100644 puppet/modules/apache/manifests/vhost.pp create mode 100644 puppet/modules/apache/manifests/vhost/davdbdir.pp create mode 100644 puppet/modules/apache/manifests/vhost/file.pp create mode 100644 puppet/modules/apache/manifests/vhost/file/documentrootdir.pp create mode 100644 puppet/modules/apache/manifests/vhost/file/documentrootfile.pp create mode 100644 puppet/modules/apache/manifests/vhost/gitweb.pp create mode 100644 puppet/modules/apache/manifests/vhost/modperl.pp create mode 100644 puppet/modules/apache/manifests/vhost/passenger.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/drupal.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/gallery2.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/global_exec_bin_dir.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/joomla.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/mediawiki.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/safe_mode_bin.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/silverstripe.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/simplemachine.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/spip.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/standard.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/typo3.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/webapp.pp create mode 100644 puppet/modules/apache/manifests/vhost/php/wordpress.pp create mode 100644 puppet/modules/apache/manifests/vhost/phpdirs.pp create mode 100644 puppet/modules/apache/manifests/vhost/proxy.pp create mode 100644 puppet/modules/apache/manifests/vhost/redirect.pp create mode 100644 puppet/modules/apache/manifests/vhost/static.pp create mode 100644 puppet/modules/apache/manifests/vhost/template.pp create mode 100644 puppet/modules/apache/manifests/vhost/webdav.pp create mode 100644 puppet/modules/apache/manifests/vhost/webdir.pp create mode 100644 puppet/modules/apache/manifests/webdav.pp create mode 100644 puppet/modules/apache/manifests/worker.pp create mode 100644 puppet/modules/apache/spec/classes/init_spec.rb create mode 100644 puppet/modules/apache/spec/defines/vhost_file_spec.rb create mode 100644 puppet/modules/apache/spec/defines/vhost_php_drupal_spec.rb create mode 100644 puppet/modules/apache/spec/defines/vhost_php_gallery2_spec.rb create mode 100644 puppet/modules/apache/spec/defines/vhost_php_joomla_spec.rb create mode 100644 puppet/modules/apache/spec/defines/vhost_php_standard_spec.rb create mode 100644 puppet/modules/apache/spec/defines/vhost_php_webapp_spec.rb create mode 100644 puppet/modules/apache/spec/defines/vhost_php_wordpress_spec.rb create mode 100644 puppet/modules/apache/spec/defines/vhost_spec.rb create mode 100644 puppet/modules/apache/spec/defines/vhost_static_spec.rb create mode 100644 puppet/modules/apache/spec/defines/vhost_template_spec.rb create mode 100644 puppet/modules/apache/spec/functions/guess_apache_version.rb create mode 100644 puppet/modules/apache/spec/spec_helper.rb create mode 100644 puppet/modules/apache/templates/default/default_index.erb create mode 100644 puppet/modules/apache/templates/include.d/ssl_defaults.inc.erb create mode 100644 puppet/modules/apache/templates/itk_plus/CentOS/00-listen-ssl.conf.erb create mode 100644 puppet/modules/apache/templates/itk_plus/CentOS/00-listen.conf.erb create mode 100644 puppet/modules/apache/templates/vhosts/0-default_ssl.conf.erb create mode 100644 puppet/modules/apache/templates/vhosts/default.erb create mode 100644 puppet/modules/apache/templates/vhosts/gitweb/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/itk_plus.erb create mode 100644 puppet/modules/apache/templates/vhosts/itk_plus/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/partials/authentication.erb create mode 100644 puppet/modules/apache/templates/vhosts/partials/header_default.erb create mode 100644 puppet/modules/apache/templates/vhosts/partials/logs.erb create mode 100644 puppet/modules/apache/templates/vhosts/partials/mod_security.erb create mode 100644 puppet/modules/apache/templates/vhosts/partials/php_settings.erb create mode 100644 puppet/modules/apache/templates/vhosts/partials/ssl.erb create mode 100644 puppet/modules/apache/templates/vhosts/partials/std_override_options.erb create mode 100644 puppet/modules/apache/templates/vhosts/passenger/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/perl/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/php/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/php_drupal/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/php_gallery2/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/php_joomla/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/php_mediawiki/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/php_silverstripe/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/php_typo3/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/php_wordpress/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/proxy/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/redirect/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/static/partial.erb create mode 100644 puppet/modules/apache/templates/vhosts/webdav/partial.erb create mode 100644 puppet/modules/apache/templates/webfiles/autoconfig/config.shtml.erb (limited to 'puppet/modules') diff --git a/puppet/modules/apache/.gitignore b/puppet/modules/apache/.gitignore new file mode 100644 index 00000000..cb918d8c --- /dev/null +++ b/puppet/modules/apache/.gitignore @@ -0,0 +1,6 @@ +.tmp_*~ +.librarian +.tmp +spec/fixtures/modules +spec/fixtures/manifests +*.lock diff --git a/puppet/modules/apache/.gitrepo b/puppet/modules/apache/.gitrepo new file mode 100644 index 00000000..fdeb3d77 --- /dev/null +++ b/puppet/modules/apache/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_apache + branch = master + commit = 415e9504f99dca3ccaa4dfd389dde24ad9d0e01c + parent = f2019755fd724fb1020cb2d97cdf82b751450ebc + cmdver = 0.3.0 diff --git a/puppet/modules/apache/.rspec b/puppet/modules/apache/.rspec new file mode 100644 index 00000000..8c18f1ab --- /dev/null +++ b/puppet/modules/apache/.rspec @@ -0,0 +1,2 @@ +--format documentation +--color diff --git a/puppet/modules/apache/Gemfile b/puppet/modules/apache/Gemfile new file mode 100644 index 00000000..b1fc9814 --- /dev/null +++ b/puppet/modules/apache/Gemfile @@ -0,0 +1,13 @@ +source 'https://rubygems.org' + +if ENV.key?('PUPPET_VERSION') + puppetversion = "~> #{ENV['PUPPET_VERSION']}" +else + puppetversion = ['>= 3.3.1'] +end + +gem 'puppet', puppetversion +gem 'puppet-lint', '>=0.3.2' +gem 'puppetlabs_spec_helper', '>=0.2.0' +gem 'rake', '>=0.9.2.2' +gem 'librarian-puppet', '>=0.9.10' diff --git a/puppet/modules/apache/LICENSE b/puppet/modules/apache/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/puppet/modules/apache/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/puppet/modules/apache/Puppetfile b/puppet/modules/apache/Puppetfile new file mode 100644 index 00000000..86d58ae6 --- /dev/null +++ b/puppet/modules/apache/Puppetfile @@ -0,0 +1,15 @@ +# empty + +forge 'https://forgeapi.puppetlabs.com' + +mod 'shorewall', :git => 'https://git-ipuppet.immerda.ch/module-shorewall' +mod 'templatewlv', :git => 'https://git-ipuppet.immerda.ch/module-templatewlv' +mod 'mod_security', :git => 'https://git-ipuppet.immerda.ch/module-mod_security' +mod 'mod_fcgid', :git => 'https://git-ipuppet.immerda.ch/module-mod_fcgid' +mod 'php', :git => 'https://git-ipuppet.immerda.ch/module-php' +mod 'perl', :git => 'https://git-ipuppet.immerda.ch/module-perl' +mod 'scl', :git => 'https://git-ipuppet.immerda.ch/module-scl' +mod 'yum', :git => 'https://git-ipuppet.immerda.ch/module-yum' +mod 'puppetlabs-stdlib' +mod 'puppetlabs-concat' +#mod 'munin', :git => 'https://git-ipuppet.immerda.ch/module-munin' diff --git a/puppet/modules/apache/README.md b/puppet/modules/apache/README.md new file mode 100644 index 00000000..331c85b0 --- /dev/null +++ b/puppet/modules/apache/README.md @@ -0,0 +1,233 @@ +Puppet module for managing an Apache web server +=============================================== + +This module tries to manage apache on different distros in a similar manner. a +few additional directories have to be created as well some configuration files +have to be deployed to fit this schema. + +! Upgrade Notices ! + + * The $ssl_cipher_suite has been evaluated from the `cert` module in the + past, but is now a hardcoded default for the sake of reducing dependency + to other modules. If you were using the `cert` module before, you should + pass this parameter when declaring the apache class ! + + * this module now only works with puppet 2.7 or newer + + * this module now uses parameterized classes, if you were using global + variables before, you need to change the class declarations in your manifests + + * this module now requires the stdlib module + + * this module no longer requires the common module + + * if using the munin module, you need a version of the munin module that is + at or newer than commit 77e0a70999a8c4c20ee8d9eb521b927c525ac653 (Feb 28, 2013) + + * if using munin, you will need to have the perl module installed + + * you must change your modules/site-apache to modules/site_apache + + * the $apache_no_default_site variable is no longer supported, you should + switch to passing the parameter "no_default_site => true" to the apache class + + * the $use_munin variable is no longer supported, you should switch to + passing the parameter 'manage_munin' to the apache class + + * the $use_shorewall variable is no longer supported, you should switch to + passing the parameter 'manage_shorewall' to the apache class + + * if you were using apache::vhost::file, or apache::vhost::template, there is a + wrapper called apache::vhost now that takes a $vhost_mode (either the default + 'template', or 'file), although you can continue to use the longer defines + + * Previously, apache::config::file resources would require the source to be a + full source specification, this is no longer needed, so please change any: + + source => "puppet:///modules/site-apache/blah" + + to be: + + source => "modules/site-apache/blah" + + +Requirements +------------ + + * puppet 2.7 or newer + * stdlib module + * templatewlv module + * facter >= 2.2 + because we check for $::operatingsystemmajrelease on multiple places. + In Debian wheezy, facter needs to get upgraded from wheezy-backports. + The facter version of Debian jessie is new enough. + +Usage +===== + +Installing Apache +----------------- + +To install Apache, simply include the 'apache' class in your manifests: + + include apache + +This will give you a basic managed setup. You can pass a couple parameters to the +class to have the module do some things for you: + + * manage_shorewall: If you have the shorewall module installed and are using + it then rules will be automatically defined for you to let traffic come from + the exterior into the web server via port 80, and also 443 if you're using + the apache::ssl class. (Default: false) + + * manage_munin: If you have the munin module installed and are using it, then + some apache graphs will be configured for you. (Default: false) + + * no_default_site: If you do not want the 0-default.conf and + 0-default_ssl.conf virtualhosts automatically created in your node + configuration. (Default: false) + + * ssl: If you want to install Apache SSL support enabled, just pass this + parameter (Default: false) + +For example: + + class { 'apache': + manage_shorewall => true, + manage_munin => true, + no_default_site => true, + ssl => true + } + +You can install the ITK worker model to enforce stronger, per-user security: + + include apache::itk + +On CentOS you can include 'apache::itk_plus' to get that mode. Not currently +implemented for other operating systems + +You can combine SSL support and the ITK worker model by including both classes. + + +Configuring Apache +------------------ + +To deploy a configuration files to the conf.d or include.d directory under +Apache's config directory, you can use the following: + + apache::config::file { 'filename': + content => 'Alias /thisApplication /usr/share/thisApplication/htdocs', + } + +by default this will deploy a conf.d global configuration file called 'filename' +with that content. + +You can pass the parameter 'type => include' to add includes for vhosts + + +To manage users in an htpasswd file: + + apache::htpasswd_user { "joe@$domain": + ensure => present, # default: present + site => "$domain", # default: 'absent' - will use $name + username => 'joe', # default: 'absent' - will use $name + password => "pass", + password_iscrypted => false, # default: false - will sha1 hash the value + path => 'absent' # default: 'absent' - /var/www/htpasswds/${site} + } + +This will place an encrypted version of "pass" for user joe into +/var/www/htpasswds/${site} + +You will need to make sure that ${site} exists before this is done, see the +apache::vhost class below for how this is done. + +VirtualHost files +----------------- + +vhosts can be added with the apache::vhost define. + +You can ship a flat file containing the configuration, or a template. That is +controlled by the 'vhost_mode' parameter, which can be either 'file', or +'template' (default). + +Unless specified, the source will be automatically pulled from +modules/site_apache/{templates,files}/vhosts.d, searched in this order: + + "puppet:///modules/site_apache/vhosts.d/${::fqdn}/${name}.conf", + "puppet:///modules/site_apache/vhosts.d/{$apache::cluster_node}/${name}.conf", + "puppet:///modules/site_apache/vhosts.d/${::operatingsystem}.${::operatingsystemmajrelease}/${name}.conf", + "puppet:///modules/site_apache/vhosts.d/${::operatingsystem}/${name}.conf", + "puppet:///modules/site_apache/vhosts.d/${name}.conf", + +otherwise you can pass a 'content' parameter to configure a template location that +it should be pulled from, or a 'vhost_source' parameter to specify the file source. + +For example: + +This would deploy a the vhost for $domain, pulled from a file from the sources +listed above: + + apache::vhost { "$domain": vhost_mode => 'file' } + + apache::vhost { "$domain": + vhost_mode => 'file', + vhost_source => 'modules/site_configs/vhosts.d/${name}.conf" + } + +There are multiple other additional configurables that you can pass to each +vhost definition: + +* logmode: + - default: Do normal logging to CustomLog and ErrorLog + - nologs: Send every logging to /dev/null + - anonym: Don't log ips for CustomLog, send ErrorLog to /dev/null + - semianonym: Don't log ips for CustomLog, log normal ErrorLog + +* run_mode: controls in which mode the vhost should be run, there are different setups + possible: + - normal: (*default*) run vhost with the current active worker (default: prefork) don't + setup anything special + - itk: run vhost with the mpm_itk module (Incompatibility: cannot be used in combination + with 'proxy-itk' & 'static-itk' mode) + - proxy-itk: run vhost with a dual prefork/itk setup, where prefork just proxies all the + requests for the itk setup, that listens only on the loobpack device. + (Incompatibility: cannot be used in combination with the itk setup.) + - static-itk: run vhost with a dual prefork/itk setup, where prefork serves all the static + content and proxies the dynamic calls to the itk setup, that listens only on + the loobpack device (Incompatibility: cannot be used in combination with + 'itk' mode) + +* mod_security: Whether we use mod_security or not (will include mod_security module) + - false: (*default*) don't activate mod_security + - true: activate mod_security + +For templates, you can pass various parameters that will automatically configure +the template accordingly (such as php_options and php_settings). Please see +manifests/vhost/template.pp for the full list. + +There are various pre-made vhost configurations that use good defaults that you can use: + +- apache::vhost::gitweb - sets up a gitweb vhost +- apache::vhost::modperl - uses modperl, with optional fastcgi +- apache::vhost::passenger - setup passenger +- apache::vhost::proxy - setup a proxy vhost +- apache::vhost::redirect - vhost to redirect hosts +- apache::vhost::static - a static vhost +- apache::vhost::webdav - for managing webdave accessible targets + +Additionally, for php sites, there are several handy pre-made vhost configurations: + +- apache::vhost::php::drupal +- apache::vhost::php::gallery2 +- apache::vhost::php::global_exec_bin_dir +- apache::vhost::php::joomla +- apache::vhost::php::mediawiki +- apache::vhost::php::safe_mode_bin +- apache::vhost::php::silverstripe +- apache::vhost::php::simplemachine +- apache::vhost::php::spip +- apache::vhost::php::standard +- apache::vhost::php::typo3 +- apache::vhost::php::webapp +- apache::vhost::php::wordpress diff --git a/puppet/modules/apache/Rakefile b/puppet/modules/apache/Rakefile new file mode 100644 index 00000000..ec1c52b3 --- /dev/null +++ b/puppet/modules/apache/Rakefile @@ -0,0 +1,26 @@ +require 'bundler' +Bundler.require(:rake) + +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' + +Rake::Task[:lint].clear +PuppetLint::RakeTask.new :lint do |config| + config.ignore_paths = ["spec/**/*.pp", "vendor/**/*.pp"] + config.log_format = '%{path}:%{linenumber}:%{KIND}: %{message}' + config.disable_checks = [ "class_inherits_from_params_class", "80chars" ] +end + +# use librarian-puppet to manage fixtures instead of .fixtures.yml +# offers more possibilities like explicit version management, forge downloads,... +task :librarian_spec_prep do + sh "librarian-puppet install --path=spec/fixtures/modules/" + pwd = `pwd`.strip + unless File.directory?("#{pwd}/spec/fixtures/modules/apache") + sh "ln -s #{pwd} #{pwd}/spec/fixtures/modules/apache" + end +end +task :spec_prep => :librarian_spec_prep + + +task :default => [:spec, :lint] diff --git a/puppet/modules/apache/files/conf.d/CentOS/ssl.conf b/puppet/modules/apache/files/conf.d/CentOS/ssl.conf new file mode 100644 index 00000000..7f9be957 --- /dev/null +++ b/puppet/modules/apache/files/conf.d/CentOS/ssl.conf @@ -0,0 +1,76 @@ +# +# This is the Apache server configuration file providing SSL support. +# It contains the configuration directives to instruct the server how to +# serve pages over an https connection. For detailing information about these +# directives see +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# + +LoadModule ssl_module modules/mod_ssl.so + +# +# When we also provide SSL we have to listen to the +# the HTTPS port in addition. +# +Listen 443 +NameVirtualHost *:443 + +## +## SSL Global Context +## +## All SSL configuration in this context applies both to +## the main server and all SSL-enabled virtual hosts. +## + +# +# Some MIME-types for downloading Certificates and CRLs +# +AddType application/x-x509-ca-cert .crt +AddType application/x-pkcs7-crl .crl + +# Pass Phrase Dialog: +# Configure the pass phrase gathering process. +# The filtering dialog program (`builtin' is a internal +# terminal dialog) has to provide the pass phrase on stdout. +SSLPassPhraseDialog builtin + +# Inter-Process Session Cache: +# Configure the SSL Session Cache: First the mechanism +# to use and second the expiring timeout (in seconds). +#SSLSessionCache dc:UNIX:/var/cache/mod_ssl/distcache +SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000) +SSLSessionCacheTimeout 300 + +# Semaphore: +# Configure the path to the mutual exclusion semaphore the +# SSL engine uses internally for inter-process synchronization. +SSLMutex default + +# Pseudo Random Number Generator (PRNG): +# Configure one or more sources to seed the PRNG of the +# SSL library. The seed data should be of good random quality. +# WARNING! On some platforms /dev/random blocks if not enough entropy +# is available. This means you then cannot use the /dev/random device +# because it would lead to very long connection times (as long as +# it requires to make more entropy available). But usually those +# platforms additionally provide a /dev/urandom device which doesn't +# block. So, if available, use this one instead. Read the mod_ssl User +# Manual for more details. +SSLRandomSeed startup file:/dev/urandom 256 +SSLRandomSeed connect builtin +#SSLRandomSeed startup file:/dev/random 512 +#SSLRandomSeed connect file:/dev/random 512 +#SSLRandomSeed connect file:/dev/urandom 512 + +# +# Use "SSLCryptoDevice" to enable any supported hardware +# accelerators. Use "openssl engine -v" to list supported +# engine names. NOTE: If you enable an accelerator and the +# server does not start, consult the error logs and ensure +# your accelerator is functioning properly. +# +SSLCryptoDevice builtin +#SSLCryptoDevice ubsec diff --git a/puppet/modules/apache/files/conf.d/CentOS/welcome.conf b/puppet/modules/apache/files/conf.d/CentOS/welcome.conf new file mode 100644 index 00000000..7d7b0cd6 --- /dev/null +++ b/puppet/modules/apache/files/conf.d/CentOS/welcome.conf @@ -0,0 +1,10 @@ +# +# This configuration file enables the default "Welcome" +# page if there is no default index page present for +# the root URL. To disable the Welcome page, comment +# out all the lines below. +# +# +# Options -Indexes +# ErrorDocument 403 /error/noindex.html +# diff --git a/puppet/modules/apache/files/conf.d/Debian/charset b/puppet/modules/apache/files/conf.d/Debian/charset new file mode 100644 index 00000000..40d7198b --- /dev/null +++ b/puppet/modules/apache/files/conf.d/Debian/charset @@ -0,0 +1,6 @@ +# Read the documentation before enabling AddDefaultCharset. +# In general, it is only a good idea if you know that all your files +# have this encoding. It will override any encoding given in the files +# in meta http-equiv or xml encoding tags. + +#AddDefaultCharset UTF-8 diff --git a/puppet/modules/apache/files/conf.d/Debian/security b/puppet/modules/apache/files/conf.d/Debian/security new file mode 100644 index 00000000..55b3e519 --- /dev/null +++ b/puppet/modules/apache/files/conf.d/Debian/security @@ -0,0 +1,50 @@ +# +# Disable access to the entire file system except for the directories that +# are explicitly allowed later. +# +# This currently breaks the configurations that come with some web application +# Debian packages. It will be made the default for the release after lenny. +# +# +# AllowOverride None +# Order Deny,Allow +# Deny from all +# + + +# Changing the following options will not really affect the security of the +# server, but might make attacks slightly more difficult in some cases. + +# +# ServerTokens +# This directive configures what you return as the Server HTTP response +# Header. The default is 'Full' which sends information about the OS-Type +# and compiled in modules. +# Set to one of: Full | OS | Minimal | Minor | Major | Prod +# where Full conveys the most information, and Prod the least. +# +#ServerTokens Minimal +ServerTokens Full + +# +# Optionally add a line containing the server version and virtual host +# name to server-generated pages (internal error documents, FTP directory +# listings, mod_status and mod_info output etc., but not CGI generated +# documents or custom error documents). +# Set to "EMail" to also include a mailto: link to the ServerAdmin. +# Set to one of: On | Off | EMail +# +#ServerSignature Off +ServerSignature On + +# +# Allow TRACE method +# +# Set to "extended" to also reflect the request body (only for testing and +# diagnostic purposes). +# +# Set to one of: On | Off | extended +# +#TraceEnable Off +TraceEnable On + diff --git a/puppet/modules/apache/files/conf.d/Debian/ssl.conf b/puppet/modules/apache/files/conf.d/Debian/ssl.conf new file mode 100644 index 00000000..bcfe8201 --- /dev/null +++ b/puppet/modules/apache/files/conf.d/Debian/ssl.conf @@ -0,0 +1 @@ +NameVirtualHost *:443 diff --git a/puppet/modules/apache/files/conf.d/do_includes.conf b/puppet/modules/apache/files/conf.d/do_includes.conf new file mode 100644 index 00000000..f44d9d4a --- /dev/null +++ b/puppet/modules/apache/files/conf.d/do_includes.conf @@ -0,0 +1,5 @@ +# +# Add index.shtml to the list of files that will be served as directory +# indexes. +# +DirectoryIndex index.shtml diff --git a/puppet/modules/apache/files/conf.d/git.conf b/puppet/modules/apache/files/conf.d/git.conf new file mode 100644 index 00000000..c03ee2b5 --- /dev/null +++ b/puppet/modules/apache/files/conf.d/git.conf @@ -0,0 +1,5 @@ +# deny access to git repository folders + + Order allow,deny + Deny From All + diff --git a/puppet/modules/apache/files/conf.d/mozilla_autoconfig.conf b/puppet/modules/apache/files/conf.d/mozilla_autoconfig.conf new file mode 100644 index 00000000..6e4f7db8 --- /dev/null +++ b/puppet/modules/apache/files/conf.d/mozilla_autoconfig.conf @@ -0,0 +1,6 @@ +Alias /.well-known/autoconfig/mail/config-v1.1.xml /var/www/autoconfig/config.shtml + + Options +Includes + AddType application/xml .shtml + AddOutputFilter INCLUDES .shtml + diff --git a/puppet/modules/apache/files/conf.d/status.conf b/puppet/modules/apache/files/conf.d/status.conf new file mode 100644 index 00000000..fb706cc1 --- /dev/null +++ b/puppet/modules/apache/files/conf.d/status.conf @@ -0,0 +1,24 @@ +########################################################### +### this file is managed by PUPPET #### +### only modify it in puppet repo or you will #### +### loose the changes ! #### +########################################################### + +# Allow server status reports generated by mod_status, +# with the URL of http://servername/server-status + + SetHandler server-status + Order deny,allow + Deny from all + Allow from 127.0.0.1 + + + SecRuleEngine Off + + + +# ExtendedStatus controls whether Apache will generate "full" status +# information (ExtendedStatus On) or just basic information (ExtendedStatus +# Off) when the "server-status" handler is called. +ExtendedStatus On + diff --git a/puppet/modules/apache/files/conf.d/vhosts.conf b/puppet/modules/apache/files/conf.d/vhosts.conf new file mode 100644 index 00000000..86485501 --- /dev/null +++ b/puppet/modules/apache/files/conf.d/vhosts.conf @@ -0,0 +1,8 @@ +########################################################### +### this file is managed by PUPPET #### +### only modify it in puppet repo or you will #### +### loose the changes ! #### +########################################################### + +NameVirtualHost *:80 +Include vhosts.d/*.conf diff --git a/puppet/modules/apache/files/config/Debian.jessie/apache2.conf b/puppet/modules/apache/files/config/Debian.jessie/apache2.conf new file mode 100644 index 00000000..7b1f96f5 --- /dev/null +++ b/puppet/modules/apache/files/config/Debian.jessie/apache2.conf @@ -0,0 +1,221 @@ +# This is the main Apache server configuration file. It contains the +# configuration directives that give the server its instructions. +# See http://httpd.apache.org/docs/2.4/ for detailed information about +# the directives and /usr/share/doc/apache2/README.Debian about Debian specific +# hints. +# +# +# Summary of how the Apache 2 configuration works in Debian: +# The Apache 2 web server configuration in Debian is quite different to +# upstream's suggested way to configure the web server. This is because Debian's +# default Apache2 installation attempts to make adding and removing modules, +# virtual hosts, and extra configuration directives as flexible as possible, in +# order to make automating the changes and administering the server as easy as +# possible. + +# It is split into several files forming the configuration hierarchy outlined +# below, all located in the /etc/apache2/ directory: +# +# /etc/apache2/ +# |-- apache2.conf +# | `-- ports.conf +# |-- mods-enabled +# | |-- *.load +# | `-- *.conf +# |-- conf-enabled +# | `-- *.conf +# `-- sites-enabled +# `-- *.conf +# +# +# * apache2.conf is the main configuration file (this file). It puts the pieces +# together by including all remaining configuration files when starting up the +# web server. +# +# * ports.conf is always included from the main configuration file. It is +# supposed to determine listening ports for incoming connections which can be +# customized anytime. +# +# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ +# directories contain particular configuration snippets which manage modules, +# global configuration fragments, or virtual host configurations, +# respectively. +# +# They are activated by symlinking available configuration files from their +# respective *-available/ counterparts. These should be managed by using our +# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See +# their respective man pages for detailed information. +# +# * The binary is called apache2. Due to the use of environment variables, in +# the default configuration, apache2 needs to be started/stopped with +# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not +# work with the default configuration. + + +# Global configuration +# + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# NOTE! If you intend to place this on an NFS (or otherwise network) +# mounted filesystem then please read the Mutex documentation (available +# at ); +# you will save yourself a lot of trouble. +# +# Do NOT add a slash at the end of the directory path. +# +#ServerRoot "/etc/apache2" + +# +# The accept serialization lock file MUST BE STORED ON A LOCAL DISK. +# +Mutex file:${APACHE_LOCK_DIR} default + +# +# PidFile: The file in which the server should record its process +# identification number when it starts. +# This needs to be set in /etc/apache2/envvars +# +PidFile ${APACHE_PID_FILE} + +# +# Timeout: The number of seconds before receives and sends time out. +# +Timeout 300 + +# +# KeepAlive: Whether or not to allow persistent connections (more than +# one request per connection). Set to "Off" to deactivate. +# +KeepAlive On + +# +# MaxKeepAliveRequests: The maximum number of requests to allow +# during a persistent connection. Set to 0 to allow an unlimited amount. +# We recommend you leave this number high, for maximum performance. +# +MaxKeepAliveRequests 100 + +# +# KeepAliveTimeout: Number of seconds to wait for the next request from the +# same client on the same connection. +# +KeepAliveTimeout 5 + + +# These need to be set in /etc/apache2/envvars +User ${APACHE_RUN_USER} +Group ${APACHE_RUN_GROUP} + +# +# HostnameLookups: Log the names of clients or just their IP addresses +# e.g., www.apache.org (on) or 204.62.129.132 (off). +# The default is off because it'd be overall better for the net if people +# had to knowingly turn this feature on, since enabling it means that +# each client request will result in AT LEAST one lookup request to the +# nameserver. +# +HostnameLookups Off + +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog ${APACHE_LOG_DIR}/error.log + +# +# LogLevel: Control the severity of messages logged to the error_log. +# Available values: trace8, ..., trace1, debug, info, notice, warn, +# error, crit, alert, emerg. +# It is also possible to configure the log level for particular modules, e.g. +# "LogLevel info ssl:warn" +# +LogLevel warn + +# Include module configuration: +IncludeOptional mods-enabled/*.load +IncludeOptional mods-enabled/*.conf + +# Include list of ports to listen on +Include ports.conf + + +# Sets the default security model of the Apache2 HTTPD server. It does +# not allow access to the root filesystem outside of /usr/share and /var/www. +# The former is used by web applications packaged in Debian, +# the latter may be used for local directories served by the web server. If +# your system is serving content from a sub-directory in /srv you must allow +# access here, or in any related virtual host. + + Options FollowSymLinks + AllowOverride None + Require all denied + + + + AllowOverride None + Require all granted + + + + Options Indexes FollowSymLinks + AllowOverride None + Require all granted + + +# +# Options Indexes FollowSymLinks +# AllowOverride None +# Require all granted +# + + + + +# AccessFileName: The name of the file to look for in each directory +# for additional configuration directives. See also the AllowOverride +# directive. +# +AccessFileName .htaccess + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Require all denied + + + +# +# The following directives define some format nicknames for use with +# a CustomLog directive. +# +# These deviate from the Common Log Format definitions in that they use %O +# (the actual bytes sent including headers) instead of %b (the size of the +# requested file), because the latter makes it impossible to detect partial +# requests. +# +# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. +# Use mod_remoteip instead. +# +LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined +LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %O" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +# Include of directories ignores editors' and dpkg's backup files, +# see README.Debian for details. + +# Include generic snippets of statements +IncludeOptional conf-enabled/*.conf + +# Include the virtual host configurations: +IncludeOptional sites-enabled/*.conf + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/puppet/modules/apache/files/config/Debian.wheezy/apache2.conf b/puppet/modules/apache/files/config/Debian.wheezy/apache2.conf new file mode 100644 index 00000000..50545671 --- /dev/null +++ b/puppet/modules/apache/files/config/Debian.wheezy/apache2.conf @@ -0,0 +1,268 @@ +# This is the main Apache server configuration file. It contains the +# configuration directives that give the server its instructions. +# See http://httpd.apache.org/docs/2.2/ for detailed information about +# the directives and /usr/share/doc/apache2-common/README.Debian.gz about +# Debian specific hints. +# +# +# Summary of how the Apache 2 configuration works in Debian: +# The Apache 2 web server configuration in Debian is quite different to +# upstream's suggested way to configure the web server. This is because Debian's +# default Apache2 installation attempts to make adding and removing modules, +# virtual hosts, and extra configuration directives as flexible as possible, in +# order to make automating the changes and administering the server as easy as +# possible. + +# It is split into several files forming the configuration hierarchy outlined +# below, all located in the /etc/apache2/ directory: +# +# /etc/apache2/ +# |-- apache2.conf +# | `-- ports.conf +# |-- mods-enabled +# | |-- *.load +# | `-- *.conf +# |-- conf.d +# | `-- * +# `-- sites-enabled +# `-- * +# +# +# * apache2.conf is the main configuration file (this file). It puts the pieces +# together by including all remaining configuration files when starting up the +# web server. +# +# In order to avoid conflicts with backup files, the Include directive is +# adapted to ignore files that: +# - do not begin with a letter or number +# - contain a character that is neither letter nor number nor _-:. +# - contain .dpkg +# +# Yet we strongly suggest that all configuration files either end with a +# .conf or .load suffix in the file name. The next Debian release will +# ignore files not ending with .conf (or .load for mods-enabled). +# +# * ports.conf is always included from the main configuration file. It is +# supposed to determine listening ports for incoming connections, and which +# of these ports are used for name based virtual hosts. +# +# * Configuration files in the mods-enabled/ and sites-enabled/ directories +# contain particular configuration snippets which manage modules or virtual +# host configurations, respectively. +# +# They are activated by symlinking available configuration files from their +# respective *-available/ counterparts. These should be managed by using our +# helpers a2enmod/a2dismod, a2ensite/a2dissite. See +# their respective man pages for detailed information. +# +# * Configuration files in the conf.d directory are either provided by other +# packages or may be added by the local administrator. Local additions +# should start with local- or end with .local.conf to avoid name clashes. All +# files in conf.d are considered (excluding the exceptions noted above) by +# the Apache 2 web server. +# +# * The binary is called apache2. Due to the use of environment variables, in +# the default configuration, apache2 needs to be started/stopped with +# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not +# work with the default configuration. + + +# Global configuration +# + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# NOTE! If you intend to place this on an NFS (or otherwise network) +# mounted filesystem then please read the LockFile documentation (available +# at ); +# you will save yourself a lot of trouble. +# +# Do NOT add a slash at the end of the directory path. +# +#ServerRoot "/etc/apache2" + +# +# The accept serialization lock file MUST BE STORED ON A LOCAL DISK. +# +LockFile ${APACHE_LOCK_DIR}/accept.lock + +# +# PidFile: The file in which the server should record its process +# identification number when it starts. +# This needs to be set in /etc/apache2/envvars +# +PidFile ${APACHE_PID_FILE} + +# +# Timeout: The number of seconds before receives and sends time out. +# +Timeout 300 + +# +# KeepAlive: Whether or not to allow persistent connections (more than +# one request per connection). Set to "Off" to deactivate. +# +KeepAlive On + +# +# MaxKeepAliveRequests: The maximum number of requests to allow +# during a persistent connection. Set to 0 to allow an unlimited amount. +# We recommend you leave this number high, for maximum performance. +# +MaxKeepAliveRequests 100 + +# +# KeepAliveTimeout: Number of seconds to wait for the next request from the +# same client on the same connection. +# +KeepAliveTimeout 5 + +## +## Server-Pool Size Regulation (MPM specific) +## + +# prefork MPM +# StartServers: number of server processes to start +# MinSpareServers: minimum number of server processes which are kept spare +# MaxSpareServers: maximum number of server processes which are kept spare +# MaxClients: maximum number of server processes allowed to start +# MaxRequestsPerChild: maximum number of requests a server process serves + + StartServers 5 + MinSpareServers 5 + MaxSpareServers 10 + MaxClients 150 + MaxRequestsPerChild 0 + + +# worker MPM +# StartServers: initial number of server processes to start +# MinSpareThreads: minimum number of worker threads which are kept spare +# MaxSpareThreads: maximum number of worker threads which are kept spare +# ThreadLimit: ThreadsPerChild can be changed to this maximum value during a +# graceful restart. ThreadLimit can only be changed by stopping +# and starting Apache. +# ThreadsPerChild: constant number of worker threads in each server process +# MaxClients: maximum number of simultaneous client connections +# MaxRequestsPerChild: maximum number of requests a server process serves + + StartServers 2 + MinSpareThreads 25 + MaxSpareThreads 75 + ThreadLimit 64 + ThreadsPerChild 25 + MaxClients 150 + MaxRequestsPerChild 0 + + +# event MPM +# StartServers: initial number of server processes to start +# MinSpareThreads: minimum number of worker threads which are kept spare +# MaxSpareThreads: maximum number of worker threads which are kept spare +# ThreadsPerChild: constant number of worker threads in each server process +# MaxClients: maximum number of simultaneous client connections +# MaxRequestsPerChild: maximum number of requests a server process serves + + StartServers 2 + MinSpareThreads 25 + MaxSpareThreads 75 + ThreadLimit 64 + ThreadsPerChild 25 + MaxClients 150 + MaxRequestsPerChild 0 + + +# These need to be set in /etc/apache2/envvars +User ${APACHE_RUN_USER} +Group ${APACHE_RUN_GROUP} + +# +# AccessFileName: The name of the file to look for in each directory +# for additional configuration directives. See also the AllowOverride +# directive. +# + +AccessFileName .htaccess + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Order allow,deny + Deny from all + Satisfy all + + +# +# DefaultType is the default MIME type the server will use for a document +# if it cannot otherwise determine one, such as from filename extensions. +# If your server contains mostly text or HTML documents, "text/plain" is +# a good value. If most of your content is binary, such as applications +# or images, you may want to use "application/octet-stream" instead to +# keep browsers from trying to display binary files as though they are +# text. +# +# It is also possible to omit any default MIME type and let the +# client's browser guess an appropriate action instead. Typically the +# browser will decide based on the file's extension then. In cases +# where no good assumption can be made, letting the default MIME type +# unset is suggested instead of forcing the browser to accept +# incorrect metadata. +# +DefaultType None + + +# +# HostnameLookups: Log the names of clients or just their IP addresses +# e.g., www.apache.org (on) or 204.62.129.132 (off). +# The default is off because it'd be overall better for the net if people +# had to knowingly turn this feature on, since enabling it means that +# each client request will result in AT LEAST one lookup request to the +# nameserver. +# +HostnameLookups Off + +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog ${APACHE_LOG_DIR}/error.log + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + +# Include module configuration: +Include mods-enabled/*.load +Include mods-enabled/*.conf + +# Include list of ports to listen on and which to use for name based vhosts +Include ports.conf + +# +# The following directives define some format nicknames for use with +# a CustomLog directive (see below). +# If you are behind a reverse proxy, you might want to change %h into %{X-Forwarded-For}i +# +LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined +LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %O" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +# Include of directories ignores editors' and dpkg's backup files, +# see the comments above for details. + +# Include generic snippets of statements +Include conf.d/ + +# Include the virtual host configurations: +Include sites-enabled/ diff --git a/puppet/modules/apache/files/config/Debian/apache2.conf b/puppet/modules/apache/files/config/Debian/apache2.conf new file mode 100644 index 00000000..1e97b4eb --- /dev/null +++ b/puppet/modules/apache/files/config/Debian/apache2.conf @@ -0,0 +1,230 @@ +# +# Based upon the NCSA server configuration files originally by Rob McCool. +# +# This is the main Apache server configuration file. It contains the +# configuration directives that give the server its instructions. +# See http://httpd.apache.org/docs/2.2/ for detailed information about +# the directives. +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# +# The configuration directives are grouped into three basic sections: +# 1. Directives that control the operation of the Apache server process as a +# whole (the 'global environment'). +# 2. Directives that define the parameters of the 'main' or 'default' server, +# which responds to requests that aren't handled by a virtual host. +# These directives also provide default values for the settings +# of all virtual hosts. +# 3. Settings for virtual hosts, which allow Web requests to be sent to +# different IP addresses or hostnames and have them handled by the +# same Apache server process. +# +# Configuration and logfile names: If the filenames you specify for many +# of the server's control files begin with "/" (or "drive:/" for Win32), the +# server will use that explicit path. If the filenames do *not* begin +# with "/", the value of ServerRoot is prepended -- so "foo.log" +# with ServerRoot set to "/etc/apache2" will be interpreted by the +# server as "/etc/apache2/foo.log". +# + +### Section 1: Global Environment +# +# The directives in this section affect the overall operation of Apache, +# such as the number of concurrent requests it can handle or where it +# can find its configuration files. +# + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# NOTE! If you intend to place this on an NFS (or otherwise network) +# mounted filesystem then please read the LockFile documentation (available +# at ); +# you will save yourself a lot of trouble. +# +# Do NOT add a slash at the end of the directory path. +# +#ServerRoot "/etc/apache2" + +# +# The accept serialization lock file MUST BE STORED ON A LOCAL DISK. +# +LockFile ${APACHE_LOCK_DIR}/accept.lock + +# +# PidFile: The file in which the server should record its process +# identification number when it starts. +# This needs to be set in /etc/apache2/envvars +# +PidFile ${APACHE_PID_FILE} + +# +# Timeout: The number of seconds before receives and sends time out. +# +Timeout 300 + +# +# KeepAlive: Whether or not to allow persistent connections (more than +# one request per connection). Set to "Off" to deactivate. +# +KeepAlive On + +# +# MaxKeepAliveRequests: The maximum number of requests to allow +# during a persistent connection. Set to 0 to allow an unlimited amount. +# We recommend you leave this number high, for maximum performance. +# +MaxKeepAliveRequests 100 + +# +# KeepAliveTimeout: Number of seconds to wait for the next request from the +# same client on the same connection. +# +KeepAliveTimeout 15 + +## +## Server-Pool Size Regulation (MPM specific) +## + +# prefork MPM +# StartServers: number of server processes to start +# MinSpareServers: minimum number of server processes which are kept spare +# MaxSpareServers: maximum number of server processes which are kept spare +# MaxClients: maximum number of server processes allowed to start +# MaxRequestsPerChild: maximum number of requests a server process serves + + StartServers 5 + MinSpareServers 5 + MaxSpareServers 10 + MaxClients 150 + MaxRequestsPerChild 0 + + +# worker MPM +# StartServers: initial number of server processes to start +# MaxClients: maximum number of simultaneous client connections +# MinSpareThreads: minimum number of worker threads which are kept spare +# MaxSpareThreads: maximum number of worker threads which are kept spare +# ThreadLimit: ThreadsPerChild can be changed to this maximum value during a +# graceful restart. ThreadLimit can only be changed by stopping +# and starting Apache. +# ThreadsPerChild: constant number of worker threads in each server process +# MaxRequestsPerChild: maximum number of requests a server process serves + + StartServers 2 + MinSpareThreads 25 + MaxSpareThreads 75 + ThreadLimit 64 + ThreadsPerChild 25 + MaxClients 150 + MaxRequestsPerChild 0 + + +# event MPM +# StartServers: initial number of server processes to start +# MaxClients: maximum number of simultaneous client connections +# MinSpareThreads: minimum number of worker threads which are kept spare +# MaxSpareThreads: maximum number of worker threads which are kept spare +# ThreadsPerChild: constant number of worker threads in each server process +# MaxRequestsPerChild: maximum number of requests a server process serves + + StartServers 2 + MaxClients 150 + MinSpareThreads 25 + MaxSpareThreads 75 + ThreadLimit 64 + ThreadsPerChild 25 + MaxRequestsPerChild 0 + + +# These need to be set in /etc/apache2/envvars +User ${APACHE_RUN_USER} +Group ${APACHE_RUN_GROUP} + +# +# AccessFileName: The name of the file to look for in each directory +# for additional configuration directives. See also the AllowOverride +# directive. +# + +AccessFileName .htaccess + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Order allow,deny + Deny from all + Satisfy all + + +# +# DefaultType is the default MIME type the server will use for a document +# if it cannot otherwise determine one, such as from filename extensions. +# If your server contains mostly text or HTML documents, "text/plain" is +# a good value. If most of your content is binary, such as applications +# or images, you may want to use "application/octet-stream" instead to +# keep browsers from trying to display binary files as though they are +# text. +# +DefaultType text/plain + + +# +# HostnameLookups: Log the names of clients or just their IP addresses +# e.g., www.apache.org (on) or 204.62.129.132 (off). +# The default is off because it'd be overall better for the net if people +# had to knowingly turn this feature on, since enabling it means that +# each client request will result in AT LEAST one lookup request to the +# nameserver. +# +HostnameLookups Off + +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog ${APACHE_LOG_DIR}/error.log + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + +# Include module configuration: +Include mods-enabled/*.load +Include mods-enabled/*.conf + +# Include all the user configurations: +Include httpd.conf + +# Include ports listing +Include ports.conf + +# +# The following directives define some format nicknames for use with +# a CustomLog directive (see below). +# If you are behind a reverse proxy, you might want to change %h into %{X-Forwarded-For}i +# +LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined +LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %O" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +# Include of directories ignores editors' and dpkg's backup files, +# see README.Debian for details. + +# Include generic snippets of statements +Include conf.d/ + +# Include the virtual host configurations: +Include sites-enabled/ diff --git a/puppet/modules/apache/files/config/OpenBSD/httpd.conf b/puppet/modules/apache/files/config/OpenBSD/httpd.conf new file mode 100644 index 00000000..09e452e6 --- /dev/null +++ b/puppet/modules/apache/files/config/OpenBSD/httpd.conf @@ -0,0 +1,1120 @@ +# $OpenBSD: httpd.conf,v 1.22 2008/01/25 09:59:57 sthen Exp $ +# +# Based upon the NCSA server configuration files originally by Rob McCool. +# +# This is the main Apache server configuration file. It contains the +# configuration directives that give the server its instructions. +# See for detailed information about +# the directives. +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# +# After this file is processed, the server will look for and process +# /var/www/conf/srm.conf and then /var/www/conf/access.conf +# unless you have overridden these with ResourceConfig and/or +# AccessConfig directives here. +# +# The configuration directives are grouped into three basic sections: +# 1. Directives that control the operation of the Apache server process as a +# whole (the 'global environment'). +# 2. Directives that define the parameters of the 'main' or 'default' server, +# which responds to requests that aren't handled by a virtual host. +# These directives also provide default values for the settings +# of all virtual hosts. +# 3. Settings for virtual hosts, which allow Web requests to be sent to +# different IP addresses or hostnames and have them handled by the +# same Apache server process. +# +# Configuration and logfile names: If the filenames you specify for many +# of the server's control files begin with "/" (or "drive:/" for Win32), the +# server will use that explicit path. If the filenames do *not* begin +# with "/", the value of ServerRoot is prepended -- so "logs/foo.log" +# with ServerRoot set to "/usr/local/apache" will be interpreted by the +# server as "/usr/local/apache/logs/foo.log". +# + +### Section 1: Global Environment +# +# The directives in this section affect the overall operation of Apache, +# such as the number of concurrent requests it can handle or where it +# can find its configuration files. +# + +# +# ServerType is either inetd, or standalone. Inetd mode is only supported on +# Unix platforms. +# +ServerType standalone + +# +# ServerTokens is either Full, OS, Minimal, or ProductOnly. +# The values define what version information is returned in the +# Server header in HTTP responses. +# +# ServerTokens ProductOnly + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# NOTE! If you intend to place this on an NFS (or otherwise network) +# mounted filesystem then please read the LockFile documentation +# (available at ); +# you will save yourself a lot of trouble. +# +# Do NOT add a slash at the end of the directory path. +# +ServerRoot "/var/www" + +# +# The LockFile directive sets the path to the lockfile used when Apache +# is compiled with either USE_FCNTL_SERIALIZED_ACCEPT or +# USE_FLOCK_SERIALIZED_ACCEPT. This directive should normally be left at +# its default value. The main reason for changing it is if the logs +# directory is NFS mounted, since the lockfile MUST BE STORED ON A LOCAL +# DISK. The PID of the main server process is automatically appended to +# the filename. +# +#LockFile logs/accept.lock + +# +# PidFile: The file in which the server should record its process +# identification number when it starts. +# +PidFile logs/httpd.pid +# +# ScoreBoardFile: File used to store internal server process information. +# Not all architectures require this. But if yours does (you'll know because +# this file will be created when you run Apache) then you *must* ensure that +# no two invocations of Apache share the same scoreboard file. +# +ScoreBoardFile logs/apache_runtime_status + +# +# In the standard configuration, the server will process httpd.conf, +# srm.conf, and access.conf in that order. The latter two files are +# now deprecated and not installed any more, as it is recommended that +# all directives be kept in a single file for simplicity. +# +#ResourceConfig conf/srm.conf +#AccessConfig conf/access.conf + +# +# Timeout: The number of seconds before receives and sends time out. +# +Timeout 300 + +# +# KeepAlive: Whether or not to allow persistent connections (more than +# one request per connection). Set to "Off" to deactivate. +# +KeepAlive On + +# +# MaxKeepAliveRequests: The maximum number of requests to allow +# during a persistent connection. Set to 0 to allow an unlimited amount. +# We recommend you leave this number high, for maximum performance. +# +MaxKeepAliveRequests 100 + +# +# KeepAliveTimeout: Number of seconds to wait for the next request from the +# same client on the same connection. +# +KeepAliveTimeout 15 + +# +# Server-pool size regulation. Rather than making you guess how many +# server processes you need, Apache dynamically adapts to the load it +# sees --- that is, it tries to maintain enough server processes to +# handle the current load, plus a few spare servers to handle transient +# load spikes (e.g., multiple simultaneous requests from a single +# Netscape browser). +# +# It does this by periodically checking how many servers are waiting +# for a request. If there are fewer than MinSpareServers, it creates +# a new spare. If there are more than MaxSpareServers, some of the +# spares die off. The default values in httpd.conf-dist are probably OK +# for most sites. +# +MinSpareServers 5 +MaxSpareServers 10 + +# +# Number of servers to start initially --- should be a reasonable ballpark +# figure. +# +StartServers 5 + +# +# Limit on total number of servers running, i.e., limit on the number +# of clients who can simultaneously connect --- if this limit is ever +# reached, clients will be LOCKED OUT, so it should NOT BE SET TOO LOW. +# It is intended mainly as a brake to keep a runaway server from taking +# the system with it as it spirals down... +# +MaxClients 150 + +# +# MaxRequestsPerChild: the number of requests each child process is +# allowed to process before the child dies. The child will exit so +# as to avoid problems after prolonged use when Apache (and maybe the +# libraries it uses) leak memory or other resources. On most systems, this +# isn't really needed, but a few (such as Solaris) do have notable leaks +# in the libraries. +# +MaxRequestsPerChild 0 + +# +# MaxFOOPerChild: these directives set the current and hard rlimits for +# the child processes. Attempts to exceed them will cause the the OS to +# take appropriate action. See the setrlimit(2) and signal(3). +# +MaxCPUPerChild 0 +MaxDATAPerChild 0 +MaxNOFILEPerChild 0 +MaxRSSPerChild 0 +MaxSTACKPerChild 0 + +# +# Listen: Allows you to bind Apache to specific IP addresses and/or +# ports, in addition to the default. See also the +# directive. +# +#Listen 3000 +#Listen 12.34.56.78:80 + +# +# BindAddress: You can support virtual hosts with this option. This directive +# is used to tell the server which IP address to listen to. It can either +# contain "*", an IP address, or a fully qualified Internet domain name. +# See also the and Listen directives. +# +#BindAddress * + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Please read the file README.DSO in the Apache 1.3 distribution for more +# details about the DSO mechanism and run `httpd -l' for the list of already +# built-in (statically linked and thus always available) modules in your httpd +# binary. +# +# Note: The order is which modules are loaded is important. Don't change +# the order below without expert advice. +# +# Example: +# LoadModule foo_module libexec/mod_foo.so + +# "anonymous" user access to authenticated areas +# LoadModule anon_auth_module /usr/lib/apache/modules/mod_auth_anon.so + +# user authentication using Berkeley DB files +# LoadModule db_auth_module /usr/lib/apache/modules/mod_auth_db.so + +# user authentication using DBM files +# LoadModule dbm_auth_module /usr/lib/apache/modules/mod_auth_dbm.so + +# authentication using new-style MD5 Digest Authentication (experimental) +# LoadModule digest_auth_module /usr/lib/apache/modules/mod_auth_digest.so + +# CERN httpd metafile semantics +# LoadModule cern_meta_module /usr/lib/apache/modules/mod_cern_meta.so + +# configuration defines ($xxx) +# LoadModule define_module /usr/lib/apache/modules/mod_define.so + +# user authentication using old-style MD5 Digest Authentication +# LoadModule digest_module /usr/lib/apache/modules/mod_digest.so + +# generation of Expires HTTP headers according to user-specified criteria +# LoadModule expires_module /usr/lib/apache/modules/mod_expires.so + +# customization of HTTP response headers +# LoadModule headers_module /usr/lib/apache/modules/mod_headers.so + +# comprehensive overview of the server configuration +# LoadModule info_module /usr/lib/apache/modules/mod_info.so + +# logging of the client user agents (deprecated in favor of mod_log_config) +# LoadModule agent_log_module /usr/lib/apache/modules/mod_log_agent.so + +# logging of referers (deprecated in favor of mod_log_config) +# LoadModule referer_log_module /usr/lib/apache/modules/mod_log_referer.so + +# determining the MIME type of a file by looking at a few bytes of its contents +# LoadModule mime_magic_module /usr/lib/apache/modules/mod_mime_magic.so + +# mmap()ing of a statically configured list of frequently requested but +# not changed files (experimental) +# LoadModule mmap_static_module /usr/lib/apache/modules/mod_mmap_static.so + +# rule-based rewriting engine to rewrite requested URLs on the fly +# LoadModule rewrite_module /usr/lib/apache/modules/mod_rewrite.so + +# attempt to correct misspellings of URLs that users might have entered +# LoadModule speling_module /usr/lib/apache/modules/mod_speling.so + +# provides an environment variable with a unique identifier for each request +# LoadModule unique_id_module /usr/lib/apache/modules/mod_unique_id.so + +# uses cookies to provide for a clickstream log of user activity on a site +# LoadModule usertrack_module /usr/lib/apache/modules/mod_usertrack.so + +# dynamically configured mass virtual hosting +# LoadModule vhost_alias_module /usr/lib/apache/modules/mod_vhost_alias.so + +# caching proxy +# LoadModule proxy_module /usr/lib/apache/modules/libproxy.so + +# +# Include extra module configuration files +# +Include /var/www/conf/modules/*.conf + +# +# ExtendedStatus controls whether Apache will generate "full" status +# information (ExtendedStatus On) or just basic information (ExtendedStatus +# Off) when the "server-status" handler is called. The default is Off. +# +#ExtendedStatus On + +### Section 2: 'Main' server configuration +# +# The directives in this section set up the values used by the 'main' +# server, which responds to any requests that aren't handled by a +# definition. These values also provide defaults for +# any containers you may define later in the file. +# +# All of these directives may appear inside containers, +# in which case these default settings will be overridden for the +# virtual host being defined. +# + +# +# If your ServerType directive (set earlier in the 'Global Environment' +# section) is set to "inetd", the next few directives don't have any +# effect since their settings are defined by the inetd configuration. +# Skip ahead to the ServerAdmin directive. +# + +# +# Port: The port to which the standalone server listens. For +# ports < 1023, you will need httpd to be run as root initially. +# +Port 80 + +## +## SSL Support +## +## When we also provide SSL we have to listen to the +## standard HTTP port (see above) and to the HTTPS port +## + +Listen 80 +Listen 443 + + +# +# If you wish httpd to run as a different user or group, you must run +# httpd as root initially and it will switch. +# +# User/Group: The name (or #number) of the user/group to run httpd as. +# . On SCO (ODT 3) use "User nouser" and "Group nogroup". +# . On HPUX you may not be able to use shared memory as nobody, and the +# suggested workaround is to create a user www and use that user. +# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET) +# when the value of (unsigned)Group is above 60000; +# don't use Group #-1 on these systems! +# On OpenBSD, use user www, group www. +# +User www +Group www + +# +# ServerAdmin: Your address, where problems with the server should be +# e-mailed. This address appears on some server-generated pages, such +# as error documents. +# +ServerAdmin you@your.address + +# +# ServerName allows you to set a host name which is sent back to clients for +# your server if it's different than the one the program would get (i.e., use +# "www" instead of the host's real name). +# +# Note: You cannot just invent host names and hope they work. The name you +# define here must be a valid DNS name for your host. If you don't understand +# this, ask your network administrator. +# If your host doesn't have a registered DNS name, enter its IP address here. +# You will have to access it by its address (e.g., http://123.45.67.89/) +# anyway, and this will make redirections work in a sensible way. +# +#ServerName new.host.name + +# +# DocumentRoot: The directory out of which you will serve your +# documents. By default, all requests are taken from this directory, but +# symbolic links and aliases may be used to point to other locations. +# +DocumentRoot "/var/www/htdocs" + +# +# Each directory to which Apache has access, can be configured with respect +# to which services and features are allowed and/or disabled in that +# directory (and its subdirectories). +# +# First, we configure the "default" to be a very restrictive set of +# permissions. +# + + Options FollowSymLinks + AllowOverride None + + +# +# Note that from this point forward you must specifically allow +# particular features to be enabled - so if something's not working as +# you might expect, make sure that you have specifically enabled it +# below. +# + +# +# This should be changed to whatever you set DocumentRoot to. +# + + +# +# This may also be "None", "All", or any combination of "Indexes", +# "Includes", "FollowSymLinks", "ExecCGI", or "MultiViews". +# +# Note that "MultiViews" must be named *explicitly* --- "Options All" +# doesn't give it to you. +# + Options Indexes FollowSymLinks + +# +# This controls which options the .htaccess files in directories can +# override. Can also be "All", or any combination of "Options", "FileInfo", +# "AuthConfig", and "Limit" +# + AllowOverride None + +# +# Controls who can get stuff from this server. +# + Order allow,deny + Allow from all + + +# +# UserDir: The directory which is prepended onto a users username, within +# which a users's web pages are looked for if a ~user request is received. +# Relative pathes are relative to the user's home directory. +# +# "disabled" turns this feature off. +# +# Since httpd will chroot(2) to the ServerRoot path by default, +# you should use +# UserDir /var/www/users +# and create per user directories in /var/www/users/ +# + +UserDir disabled + +# +# Control access to UserDir directories. The following is an example +# for a site where these directories are restricted to read-only and +# are located under /users/ +# You will need to change this to match your site's home directories. +# +# +# AllowOverride FileInfo AuthConfig Limit +# Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec +# +# Order allow,deny +# Allow from all +# +# +# Order deny,allow +# Deny from all +# +# + +# +# DirectoryIndex: Name of the file or files to use as a pre-written HTML +# directory index. Separate multiple entries with spaces. +# +DirectoryIndex index.html + +# +# AccessFileName: The name of the file to look for in each directory +# for access control information. +# +AccessFileName .htaccess + +# +# The following lines prevent .htaccess files from being viewed by +# Web clients. Since .htaccess files often contain authorization +# information, access is disallowed for security reasons. Comment +# these lines out if you want Web visitors to see the contents of +# .htaccess files. If you change the AccessFileName directive above, +# be sure to make the corresponding changes here. +# + + Order allow,deny + Deny from all + + +# +# CacheNegotiatedDocs: By default, Apache sends "Pragma: no-cache" with each +# document that was negotiated on the basis of content. This asks proxy +# servers not to cache the document. Uncommenting the following line disables +# this behavior, and proxies will be allowed to cache the documents. +# +#CacheNegotiatedDocs + +# +# UseCanonicalName: (new for 1.3) With this setting turned on, whenever +# Apache needs to construct a self-referencing URL (a URL that refers back +# to the server the response is coming from) it will use ServerName and +# Port to form a "canonical" name. With this setting off, Apache will +# use the hostname:port that the client supplied, when possible. This +# also affects SERVER_NAME and SERVER_PORT in CGI scripts. +# +UseCanonicalName On + +# +# TypesConfig describes where the mime.types file (or equivalent) is +# to be found. +# +TypesConfig conf/mime.types + +# +# DefaultType is the default MIME type the server will use for a document +# if it cannot otherwise determine one, such as from filename extensions. +# If your server contains mostly text or HTML documents, "text/plain" is +# a good value. If most of your content is binary, such as applications +# or images, you may want to use "application/octet-stream" instead to +# keep browsers from trying to display binary files as though they are +# text. +# +DefaultType text/plain + +# +# The mod_mime_magic module allows the server to use various hints from the +# contents of the file itself to determine its type. The MIMEMagicFile +# directive tells the module where the hint definitions are located. +# mod_mime_magic is not part of the default server (you have to add +# it yourself with a LoadModule [see the DSO paragraph in the 'Global +# Environment' section], or recompile the server and include mod_mime_magic +# as part of the configuration), so it's enclosed in an container. +# This means that the MIMEMagicFile directive will only be processed if the +# module is part of the server. +# + + MIMEMagicFile conf/magic + + +# +# HostnameLookups: Log the names of clients or just their IP addresses +# e.g., www.apache.org (on) or 204.62.129.132 (off). +# The default is off because it'd be overall better for the net if people +# had to knowingly turn this feature on, since enabling it means that +# each client request will result in AT LEAST one lookup request to the +# nameserver. +# +HostnameLookups Off + +# +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# Either a filename or the text "syslog:" followed by a facility +# name may be specified here. +# +#ErrorLog syslog:daemon +ErrorLog logs/error_log + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + +# +# The following directives define some format nicknames for use with +# a CustomLog directive (see below). +# +LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %b" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +# +# The location and format of the access logfile (Common Logfile Format). +# If you do not define any access logfiles within a +# container, they will be logged here. Contrariwise, if you *do* +# define per- access logfiles, transactions will be +# logged therein and *not* in this file. +# +CustomLog logs/access_log common + +# +# If you would like to have agent and referer logfiles, uncomment the +# following directives. +# +#CustomLog logs/referer_log referer +#CustomLog logs/agent_log agent + +# +# If you prefer a single logfile with access, agent, and referer information +# (Combined Logfile Format) you can use the following directive. +# +#CustomLog logs/access_log combined + +# +# Optionally add a line containing the server version and virtual host +# name to server-generated pages (error documents, FTP directory listings, +# mod_status and mod_info output etc., but not CGI generated documents). +# Set to "EMail" to also include a mailto: link to the ServerAdmin. +# Set to one of: On | Off | EMail +# +# ServerSignature Off + +# +# Aliases: Add here as many aliases as you need (with no limit). The format is +# Alias fakename realname +# +# Note that if you include a trailing / on fakename then the server will +# require it to be present in the URL. So "/icons" isn't aliased in this +# example, only "/icons/".. +# +Alias /icons/ "/var/www/icons/" + + + Options Indexes MultiViews + AllowOverride None + Order allow,deny + Allow from all + + + + Options MultiViews + AllowOverride None + Order allow,deny + Allow from all + + +# +# ScriptAlias: This controls which directories contain server scripts. +# ScriptAliases are essentially the same as Aliases, except that +# documents in the realname directory are treated as applications and +# run by the server when requested rather than as documents sent to the client. +# The same rules about trailing "/" apply to ScriptAlias directives as to +# Alias. +# +ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" + +# +# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased +# CGI directory exists, if you have that configured. +# + + AllowOverride None + Options None + Order allow,deny + Allow from all + + +# +# Redirect allows you to tell clients about documents which used to exist in +# your server's namespace, but do not anymore. This allows you to tell the +# clients where to look for the relocated document. +# Format: Redirect old-URI new-URL +# + +# +# Directives controlling the display of server-generated directory listings. +# + +# +# FancyIndexing is whether you want fancy directory indexing or standard +# +IndexOptions FancyIndexing + +# +# AddIcon* directives tell the server which icon to show for different +# files or filename extensions. These are only displayed for +# FancyIndexed directories. +# +AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip + +AddIconByType (TXT,/icons/text.gif) text/* +AddIconByType (IMG,/icons/image2.gif) image/* +AddIconByType (SND,/icons/sound2.gif) audio/* +AddIconByType (VID,/icons/movie.gif) video/* + +AddIcon /icons/binary.gif .bin .exe +AddIcon /icons/binhex.gif .hqx +AddIcon /icons/tar.gif .tar +AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv +AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip +AddIcon /icons/a.gif .ps .ai .eps +AddIcon /icons/layout.gif .html .shtml .htm .pdf +AddIcon /icons/text.gif .txt +AddIcon /icons/c.gif .c +AddIcon /icons/p.gif .pl .py +AddIcon /icons/f.gif .for +AddIcon /icons/dvi.gif .dvi +AddIcon /icons/uuencoded.gif .uu +AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl +AddIcon /icons/tex.gif .tex +AddIcon /icons/bomb.gif core + +AddIcon /icons/back.gif .. +AddIcon /icons/hand.right.gif README +AddIcon /icons/folder.gif ^^DIRECTORY^^ +AddIcon /icons/blank.gif ^^BLANKICON^^ + +# +# DefaultIcon is which icon to show for files which do not have an icon +# explicitly set. +# +DefaultIcon /icons/unknown.gif + +# +# AddDescription allows you to place a short description after a file in +# server-generated indexes. These are only displayed for FancyIndexed +# directories. +# Format: AddDescription "description" filename +# +#AddDescription "GZIP compressed document" .gz +#AddDescription "tar archive" .tar +#AddDescription "GZIP compressed tar archive" .tgz + +# +# ReadmeName is the name of the README file the server will look for by +# default, and append to directory listings. +# +# HeaderName is the name of a file which should be prepended to +# directory indexes. +# +# The server will first look for name.html and include it if found. +# If name.html doesn't exist, the server will then look for name.txt +# and include it as plaintext if found. +# +ReadmeName README +HeaderName HEADER + +# +# IndexIgnore is a set of filenames which directory indexing should ignore +# and not include in the listing. Shell-style wildcarding is permitted. +# +IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t + +# +# AddEncoding allows you to have certain browsers (Mosaic/X 2.1+) uncompress +# information on the fly. Note: Not all browsers support this. +# Despite the name similarity, the following Add* directives have nothing +# to do with the FancyIndexing customization directives above. +# +AddEncoding x-compress Z +AddEncoding x-gzip gz + +# +# AddLanguage allows you to specify the language of a document. You can +# then use content negotiation to give a browser a file in a language +# it can understand. Note that the suffix does not have to be the same +# as the language keyword --- those with documents in Polish (whose +# net-standard language code is pl) may wish to use "AddLanguage pl .po" +# to avoid the ambiguity with the common suffix for perl scripts. +# +AddLanguage en .en +AddLanguage fr .fr +AddLanguage de .de +AddLanguage da .da +AddLanguage el .el +AddLanguage it .it + +# +# LanguagePriority allows you to give precedence to some languages +# in case of a tie during content negotiation. +# Just list the languages in decreasing order of preference. +# +LanguagePriority en fr de + +# +# AddType allows you to tweak mime.types without actually editing it, or to +# make certain files to be certain types. +# +# For example, the PHP module (not part of the Apache distribution) +# will typically use: +# +#AddType application/x-httpd-php .php + +# +# AddHandler allows you to map certain file extensions to "handlers", +# actions unrelated to filetype. These can be either built into the server +# or added with the Action command (see below) +# +# If you want to use server side includes, or CGI outside +# ScriptAliased directories, uncomment the following lines. +# +# To use CGI scripts: +# +#AddHandler cgi-script .cgi + +# +# To use server-parsed HTML files +# +#AddType text/html .shtml +#AddHandler server-parsed .shtml + +# +# Uncomment the following line to enable Apache's send-asis HTTP file +# feature +# +#AddHandler send-as-is asis + +# +# If you wish to use server-parsed imagemap files, use +# +#AddHandler imap-file map + +# +# To enable type maps, you might want to use +# +#AddHandler type-map var + +# +# Action lets you define media types that will execute a script whenever +# a matching file is called. This eliminates the need for repeated URL +# pathnames for oft-used CGI file processors. +# Format: Action media/type /cgi-script/location +# Format: Action handler-name /cgi-script/location +# + +# +# MetaDir: specifies the name of the directory in which Apache can find +# meta information files. These files contain additional HTTP headers +# to include when sending the document +# +#MetaDir .web + +# +# MetaSuffix: specifies the file name suffix for the file containing the +# meta information. +# +#MetaSuffix .meta + +# +# Customizable error response (Apache style) +# these come in three flavors +# +# 1) plain text +#ErrorDocument 500 "The server made a boo boo. +# n.b. the (") marks it as text, it does not get output +# +# 2) local redirects +#ErrorDocument 404 /missing.html +# to redirect to local URL /missing.html +#ErrorDocument 404 /cgi-bin/missing_handler.pl +# N.B.: You can redirect to a script or a document using server-side-includes. +# +# 3) external redirects +#ErrorDocument 402 http://some.other_server.com/subscription_info.html +# N.B.: Many of the environment variables associated with the original +# request will *not* be available to such a script. + +# +# The following directives modify normal HTTP response behavior. +# The first directive disables keepalive for Netscape 2.x and browsers that +# spoof it. There are known problems with these browser implementations. +# The second directive is for Microsoft Internet Explorer 4.0b2 +# which has a broken HTTP/1.1 implementation and does not properly +# support keepalive when it is used on 301 or 302 (redirect) responses. +# +BrowserMatch "Mozilla/2" nokeepalive +BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 + +# +# The following directive disables HTTP/1.1 responses to browsers which +# are in violation of the HTTP/1.0 spec by not being able to grok a +# basic 1.1 response. +# +BrowserMatch "RealPlayer 4\.0" force-response-1.0 +BrowserMatch "Java/1\.0" force-response-1.0 +BrowserMatch "JDK/1\.0" force-response-1.0 + +# +# Allow server status reports, with the URL of http://servername/server-status +# Change the ".your_domain.com" to match your domain to enable. +# +# +# SetHandler server-status +# Order deny,allow +# Deny from all +# Allow from .your_domain.com +# + +# +# Allow remote server configuration reports, with the URL of +# http://servername/server-info (requires that mod_info.c be loaded). +# Change the ".your_domain.com" to match your domain to enable. +# +# +# SetHandler server-info +# Order deny,allow +# Deny from all +# Allow from .your_domain.com +# + +# +# There have been reports of people trying to abuse an old bug from pre-1.1 +# days. This bug involved a CGI script distributed as a part of Apache. +# By uncommenting these lines you can redirect these attacks to a logging +# script on phf.apache.org. Or, you can record them yourself, using the script +# support/phf_abuse_log.cgi. +# +# +# Deny from all +# ErrorDocument 403 http://phf.apache.org/phf_abuse_log.cgi +# + +# +# Proxy Server directives. Uncomment the following lines to +# enable the proxy server: +# +# +#ProxyRequests On +# +# +# Order deny,allow +# Deny from all +# Allow from .your_domain.com +# + +# +# Enable/disable the handling of HTTP/1.1 "Via:" headers. +# ("Full" adds the server version; "Block" removes all outgoing Via: headers) +# Set to one of: Off | On | Full | Block +# +#ProxyVia On + +# +# To enable the cache as well, edit and uncomment the following lines: +# (no cacheing without CacheRoot) +# +#CacheRoot "/var/www/proxy" +#CacheSize 5 +#CacheGcInterval 4 +#CacheMaxExpire 24 +#CacheLastModifiedFactor 0.1 +#CacheDefaultExpire 1 +#NoCache a_domain.com another_domain.edu joes.garage_sale.com + +# +# End of proxy directives. + +### Section 3: Virtual Hosts +# +# VirtualHost: If you want to maintain multiple domains/hostnames on your +# machine you can setup VirtualHost containers for them. +# Please see the documentation at +# for further details before you try to setup virtual hosts. +# You may use the command line option '-S' to verify your virtual host +# configuration. + +# +# If you want to use name-based virtual hosts you need to define at +# least one IP address (and port number) for them. +# +#NameVirtualHost 12.34.56.78:80 +#NameVirtualHost 12.34.56.78 + +# +# VirtualHost example: +# Almost any Apache directive may go into a VirtualHost container. +# +# +# ServerAdmin webmaster@host.some_domain.com +# DocumentRoot /www/docs/host.some_domain.com +# ServerName host.some_domain.com +# ErrorLog logs/host.some_domain.com-error_log +# CustomLog logs/host.some_domain.com-access_log common +# + +# +# + + +## +## SSL Global Context +## +## All SSL configuration in this context applies both to +## the main server and all SSL-enabled virtual hosts. +## + +# +# Some MIME-types for downloading Certificates and CRLs +# + +AddType application/x-x509-ca-cert .crt +AddType application/x-pkcs7-crl .crl + + + + +# Pass Phrase Dialog: +# Configure the pass phrase gathering process. +# The filtering dialog program (`builtin' is a internal +# terminal dialog) has to provide the pass phrase on stdout. +SSLPassPhraseDialog builtin + +# Inter-Process Session Cache: +# Configure the SSL Session Cache: First either `none' +# or `dbm:/path/to/file' for the mechanism to use and +# second the expiring timeout (in seconds). +SSLSessionCache dbm:logs/ssl_scache +SSLSessionCacheTimeout 300 + +# Semaphore: +# Configure the path to the mutual exclusion semaphore the +# SSL engine uses internally for inter-process synchronization. +SSLMutex sem + +# Pseudo Random Number Generator (PRNG): +# Configure one or more sources to seed the PRNG of the +# SSL library. The seed data should be of good random quality. +SSLRandomSeed startup builtin +SSLRandomSeed connect builtin +#SSLRandomSeed startup file:/dev/random 512 +#SSLRandomSeed startup file:/dev/urandom 512 +#SSLRandomSeed connect file:/dev/random 512 +#SSLRandomSeed connect file:/dev/urandom 512 +SSLRandomSeed startup file:/dev/arandom 512 + +# Logging: +# The home of the dedicated SSL protocol logfile. Errors are +# additionally duplicated in the general error log file. Put +# this somewhere where it cannot be used for symlink attacks on +# a real server (i.e. somewhere where only root can write). +# Log levels are (ascending order: higher ones include lower ones): +# none, error, warn, info, trace, debug. +SSLLog logs/ssl_engine_log +SSLLogLevel info + + + + + +## +## SSL Virtual Host Context +## + + + +# General setup for the virtual host +DocumentRoot /var/www/htdocs +ServerName new.host.name +ServerAdmin you@your.address +ErrorLog logs/error_log +TransferLog logs/access_log + +# SSL Engine Switch: +# Enable/Disable SSL for this virtual host. +SSLEngine on + +# SSL Cipher Suite: +# List the ciphers that the client is permitted to negotiate. +# See the mod_ssl documentation for a complete list. +#SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP + +# Server Certificate: +# Point SSLCertificateFile at a PEM encoded certificate. If +# the certificate is encrypted, then you will be prompted for a +# pass phrase. Note that a kill -HUP will prompt again. A test +# certificate can be generated with `make certificate' under +# built time. +SSLCertificateFile /etc/ssl/server.crt + +# Server Private Key: +# If the key is not combined with the certificate, use this +# directive to point at the key file. +SSLCertificateKeyFile /etc/ssl/private/server.key + +# Certificate Authority (CA): +# Set the CA certificate verification path where to find CA +# certificates for client authentication or alternatively one +# huge file containing all of them (file must be PEM encoded) +# Note: Inside SSLCACertificatePath you need hash symlinks +# to point to the certificate files. Use the provided +# Makefile to update the hash symlinks after changes. +#SSLCACertificatePath /var/www/conf/ssl.crt +#SSLCACertificateFile /var/www/conf/ssl.crt/ca-bundle.crt + +# Client Authentication (Type): +# Client certificate verification type and depth. Types are +# none, optional, require and optional_no_ca. Depth is a +# number which specifies how deeply to verify the certificate +# issuer chain before deciding the certificate is not valid. +#SSLVerifyClient require +#SSLVerifyDepth 10 + +# Access Control: +# With SSLRequire you can do per-directory access control based +# on arbitrary complex boolean expressions containing server +# variable checks and other lookup directives. The syntax is a +# mixture between C and Perl. See the mod_ssl documentation +# for more details. +# +#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \ +# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \ +# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \ +# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \ +# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \ +# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/ +# + +# SSL Engine Options: +# Set various options for the SSL engine. +# FakeBasicAuth: +# Translate the client X.509 into a Basic Authorisation. This means that +# the standard Auth/DBMAuth methods can be used for access control. The +# user name is the `one line' version of the client's X.509 certificate. +# Note that no password is obtained from the user. Every entry in the user +# file needs this password: `xxj31ZMTZzkVA'. +# ExportCertData: +# This exports two additional environment variables: SSL_CLIENT_CERT and +# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the +# server (always existing) and the client (only existing when client +# authentication is used). This can be used to import the certificates +# into CGI scripts. +# CompatEnvVars: +# This exports obsolete environment variables for backward compatibility +# to Apache-SSL 1.x, mod_ssl 2.0.x, Sioux 1.0 and Stronghold 2.x. Use this +# to provide compatibility to existing CGI scripts. +#SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars + +# Per-Server Logging: +# The home of a custom SSL log file. Use this when you want a +# compact non-error SSL logfile on a virtual host basis. +CustomLog logs/ssl_request_log \ + "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" + + + + + +# include additional things +Include conf.d/*.conf +Include vhosts.d/*.conf diff --git a/puppet/modules/apache/files/include.d/defaults.inc b/puppet/modules/apache/files/include.d/defaults.inc new file mode 100644 index 00000000..3e5e7d73 --- /dev/null +++ b/puppet/modules/apache/files/include.d/defaults.inc @@ -0,0 +1,5 @@ +RewriteEngine on +RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) +RewriteRule .* - [F] + +ServerSignature Off diff --git a/puppet/modules/apache/files/include.d/joomla.inc b/puppet/modules/apache/files/include.d/joomla.inc new file mode 100644 index 00000000..1535ce37 --- /dev/null +++ b/puppet/modules/apache/files/include.d/joomla.inc @@ -0,0 +1,30 @@ +########## Begin - Rewrite rules to block out some common exploits +# against joomla's +# +# Block out any script trying to set a mosConfig value through the URL +RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR] + +# Block out any script trying to base64_encode crap to send via URL +RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR] + +# Block out any script that includes a + + + diff --git a/puppet/modules/nagios/images/nagiosgraph.gif b/puppet/modules/nagios/images/nagiosgraph.gif new file mode 100644 index 00000000..068082af Binary files /dev/null and b/puppet/modules/nagios/images/nagiosgraph.gif differ diff --git a/puppet/modules/nagios/manifests/apache.pp b/puppet/modules/nagios/manifests/apache.pp new file mode 100644 index 00000000..87fe3d2f --- /dev/null +++ b/puppet/modules/nagios/manifests/apache.pp @@ -0,0 +1,15 @@ +# setup naguis together with apache +class nagios::apache( + $allow_external_cmd = false, + $manage_shorewall = false, + $manage_munin = false, + $storeconfigs = true +) { + class{'::nagios': + httpd => 'apache', + allow_external_cmd => $allow_external_cmd, + manage_munin => $manage_munin, + manage_shorewall => $manage_shorewall, + storeconfigs => $storeconfigs + } +} diff --git a/puppet/modules/nagios/manifests/base.pp b/puppet/modules/nagios/manifests/base.pp new file mode 100644 index 00000000..18d5c12f --- /dev/null +++ b/puppet/modules/nagios/manifests/base.pp @@ -0,0 +1,144 @@ +# basic stuff for nagios +class nagios::base { + # include the variables + include ::nagios::defaults::vars + + package { 'nagios': + ensure => present, + } + + service { 'nagios': + ensure => running, + enable => $nagios::service_at_boot, + require => Package['nagios'], + } + + $cfg_dir = $nagios::defaults::vars::int_cfgdir + # this file should contain all the nagios_puppet-paths: + file{ + 'nagios_cfgdir': + ensure => directory, + path => $cfg_dir, + alias => nagios_confd, + recurse => true, + purge => true, + force => true, + require => Package['nagios'], + notify => Service['nagios'], + owner => root, + group => root, + mode => '0755'; + 'nagios_main_cfg': + path => "${cfg_dir}/nagios.cfg", + source => [ "puppet:///modules/site_nagios/configs/${::fqdn}/nagios.cfg", + "puppet:///modules/site_nagios/configs/${::operatingsystem}/nagios.cfg", + 'puppet:///modules/site_nagios/configs/nagios.cfg', + "puppet:///modules/nagios/configs/${::operatingsystem}/nagios.cfg", + 'puppet:///modules/nagios/configs/nagios.cfg' ], + notify => Service['nagios'], + owner => root, + group => root, + mode => '0644'; + 'nagios_cgi_cfg': + path => "${cfg_dir}/cgi.cfg", + source => [ "puppet:///modules/site_nagios/configs/${::fqdn}/cgi.cfg", + "puppet:///modules/site_nagios/configs/${::operatingsystem}/cgi.cfg", + 'puppet:///modules/site_nagios/configs/cgi.cfg', + "puppet:///modules/nagios/configs/${::operatingsystem}/cgi.cfg", + 'puppet:///modules/nagios/configs/cgi.cfg' ], + notify => Service['apache'], + owner => 'root', + group => 0, + mode => '0644'; + 'nagios_htpasswd': + path => "${cfg_dir}/htpasswd.users", + source => [ 'puppet:///modules/site_nagios/htpasswd.users', + 'puppet:///modules/nagios/htpasswd.users' ], + owner => root, + group => apache, + mode => '0640'; + 'nagios_resource_cfg': + path => "${cfg_dir}/resource.cfg", + source => [ "puppet:///modules/site_nagios/configs/${::operatingsystem}/private/resource.cfg.${::architecture}", + "puppet:///modules/nagios/configs/${::operatingsystem}/private/resource.cfg.${::architecture}" ], + notify => Service['nagios'], + owner => root, + group => nagios, + mode => '0640'; + } + + if $cfg_dir == '/etc/nagios3' { + file{'/etc/nagios': + ensure => link, + target => $cfg_dir, + before => File['nagios_cfgdir'], + } + } + + file{ + [ "${cfg_dir}/nagios_command.cfg", + "${cfg_dir}/nagios_contact.cfg", + "${cfg_dir}/nagios_contactgroup.cfg", + "${cfg_dir}/nagios_host.cfg", + "${cfg_dir}/nagios_hostdependency.cfg", + "${cfg_dir}/nagios_hostescalation.cfg", + "${cfg_dir}/nagios_hostextinfo.cfg", + "${cfg_dir}/nagios_hostgroup.cfg", + "${cfg_dir}/nagios_hostgroupescalation.cfg", + "${cfg_dir}/nagios_service.cfg", + "${cfg_dir}/nagios_servicedependency.cfg", + "${cfg_dir}/nagios_serviceescalation.cfg", + "${cfg_dir}/nagios_serviceextinfo.cfg", + "${cfg_dir}/nagios_servicegroup.cfg", + "${cfg_dir}/nagios_timeperiod.cfg" ]: + ensure => file, + replace => false, + notify => Service['nagios'], + require => File['nagios_cfgdir'], + owner => root, + group => 0, + mode => '0644'; + } + + resources { + [ + 'nagios_command', + 'nagios_contactgroup', + 'nagios_contact', + 'nagios_hostdependency', + 'nagios_hostescalation', + 'nagios_hostextinfo', + 'nagios_hostgroup', + 'nagios_host', + 'nagios_servicedependency', + 'nagios_serviceescalation', + 'nagios_servicegroup', + 'nagios_serviceextinfo', + 'nagios_service', + 'nagios_timeperiod', + ]: + notify => Service['nagios'], + purge => $::nagios::purge_resources + } + + # make sure nagios resources are defined after nagios is + # installed and the nagios_cfgdir resource is present + File['nagios_cfgdir'] -> Nagios_command <||> + File['nagios_cfgdir'] -> Nagios_contactgroup <||> + File['nagios_cfgdir'] -> Nagios_contact <||> + File['nagios_cfgdir'] -> Nagios_hostdependency <||> + File['nagios_cfgdir'] -> Nagios_hostescalation <||> + File['nagios_cfgdir'] -> Nagios_hostextinfo <||> + File['nagios_cfgdir'] -> Nagios_hostgroup <||> + File['nagios_cfgdir'] -> Nagios_host <||> + File['nagios_cfgdir'] -> Nagios_servicedependency <||> + File['nagios_cfgdir'] -> Nagios_serviceescalation <||> + File['nagios_cfgdir'] -> Nagios_servicegroup <||> + File['nagios_cfgdir'] -> Nagios_serviceextinfo <||> + File['nagios_cfgdir'] -> Nagios_service <||> + File['nagios_cfgdir'] -> Nagios_timeperiod <||> + + if ( $nagios::storeconfigs == true ) { + include ::nagios::storeconfigs + } +} diff --git a/puppet/modules/nagios/manifests/centos.pp b/puppet/modules/nagios/manifests/centos.pp new file mode 100644 index 00000000..f41d46dc --- /dev/null +++ b/puppet/modules/nagios/manifests/centos.pp @@ -0,0 +1,42 @@ +# centos specific changes +class nagios::centos inherits nagios::base { + + package { [ 'nagios-plugins', 'nagios-plugins-smtp','nagios-plugins-http', + 'nagios-plugins-ssh', 'nagios-plugins-tcp', 'nagios-plugins-dig', + 'nagios-plugins-nrpe', 'nagios-plugins-load', 'nagios-plugins-dns', + 'nagios-plugins-ping', 'nagios-plugins-procs', 'nagios-plugins-users', + 'nagios-plugins-ldap', 'nagios-plugins-disk', 'nagios-plugins-swap', + 'nagios-plugins-nagios', 'nagios-plugins-perl', 'nagios-plugins-ntp', + 'nagios-plugins-snmp' ]: + ensure => 'present', + notify => Service['nagios'], + } + + Service['nagios']{ + hasstatus => true, + } + + file{ + 'nagios_private': + ensure => directory, + path => "${nagios::base::cfg_dir}/private", + purge => true, + recurse => true, + notify => Service['nagios'], + owner => root, + group => nagios, + mode => '0750'; + } + File['nagios_resource_cfg']{ + path => "${nagios::base::cfg_dir}/private/resource.cfg", + } + if $nagios::allow_external_cmd { + file{'/var/spool/nagios/cmd': + ensure => 'directory', + require => Package['nagios'], + owner => apache, + group => nagios, + mode => '2660', + } + } +} diff --git a/puppet/modules/nagios/manifests/command/imap_pop3.pp b/puppet/modules/nagios/manifests/command/imap_pop3.pp new file mode 100644 index 00000000..42e4092b --- /dev/null +++ b/puppet/modules/nagios/manifests/command/imap_pop3.pp @@ -0,0 +1,30 @@ +# manage mail checks +class nagios::command::imap_pop3 { + require ::nagios::plugins::mail_login + case $::operatingsystem { + 'Debian','Ubuntu': { } # Debian/Ubuntu already define those checks + default: { + nagios_command { + 'check_imap': + command_line => '$USER1$/check_imap -H $ARG1$ -p $ARG2$'; + } + } + } + + nagios_command { + 'check_imap_ssl': + command_line => '$USER1$/check_imap -H $ARG1$ -p $ARG2$ -S'; + 'check_pop3': + command_line => '$USER1$/check_pop -H $ARG1$ -p $ARG2$'; + 'check_pop3_ssl': + command_line => '$USER1$/check_pop -H $ARG1$ -p $ARG2$ -S'; + 'check_managesieve': + command_line => '$USER1$/check_tcp -H $ARG1$ -p 4190'; + 'check_managesieve_legacy': + command_line => '$USER1$/check_tcp -H $ARG1$ -p 2000'; + 'check_imap_login': + command_line => '$USER1$/check_imap_login -s -H $ARG1$ -u $ARG2$ -p $ARG3$ -w $ARG4$ -c $ARG5$'; + 'check_pop3_login': + command_line => '$USER1$/check_pop3_login -s -H $ARG1$ -u $ARG2$ -p $ARG3$ -w $ARG4$ -c $ARG5$'; + } +} diff --git a/puppet/modules/nagios/manifests/command/nrpe.pp b/puppet/modules/nagios/manifests/command/nrpe.pp new file mode 100644 index 00000000..7539a266 --- /dev/null +++ b/puppet/modules/nagios/manifests/command/nrpe.pp @@ -0,0 +1,14 @@ +class nagios::command::nrpe { + + # this command runs a program $ARG1$ with arguments $ARG2$ + nagios_command { + 'check_nrpe': + command_line => '/usr/lib/nagios/plugins/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ -a $ARG2$' + } + + # this command runs a program $ARG1$ with no arguments + nagios_command { + 'check_nrpe_1arg': + command_line => '/usr/lib/nagios/plugins/check_nrpe -H $HOSTADDRESS$ -c $ARG1$' + } +} diff --git a/puppet/modules/nagios/manifests/command/nrpe_timeout.pp b/puppet/modules/nagios/manifests/command/nrpe_timeout.pp new file mode 100644 index 00000000..799f2fc3 --- /dev/null +++ b/puppet/modules/nagios/manifests/command/nrpe_timeout.pp @@ -0,0 +1,11 @@ +class nagios::command::nrpe_timeout { + nagios_command { + 'check_nrpe_timeout': + command_line => '/usr/lib/nagios/plugins/check_nrpe -t $ARG1$ -H $HOSTADDRESS$ -c $ARG2$ -a $ARG3$', + require => Package['nagios-nrpe-server']; + + 'check_nrpe_1arg_timeout': + command_line => '/usr/lib/nagios/plugins/check_nrpe -t $ARG1$ -H $HOSTADDRESS$ -c $ARG2$', + require => Package['nagios-nrpe-server'] + } +} diff --git a/puppet/modules/nagios/manifests/command/smtp.pp b/puppet/modules/nagios/manifests/command/smtp.pp new file mode 100644 index 00000000..29d97f8b --- /dev/null +++ b/puppet/modules/nagios/manifests/command/smtp.pp @@ -0,0 +1,22 @@ +class nagios::command::smtp { + case $operatingsystem { + debian,ubuntu: { } # Debian/Ubuntu already define those checks + default: { + nagios_command { + 'check_smtp': + command_line => '$USER1$/check_smtp -H $ARG1$ -p $ARG2$'; + 'check_ssmtp': + command_line => '$USER1$/check_ssmtp -H $ARG1$ -p $ARG2$ -S'; + } + } + } + + nagios_command { + 'check_smtp_tls': + command_line => '$USER1$/check_smtp -H $ARG1$ -p $ARG2$ -S'; + 'check_smtp_cert': + command_line => '$USER1$/check_smtp -H $ARG1$ -p $ARG2$ -S -D $ARG3$'; + 'check_ssmtp_cert': + command_line => '$USER1$/check_ssmtp -H $ARG1$ -p $ARG2$ -S -D $ARG3$'; + } +} diff --git a/puppet/modules/nagios/manifests/debian.pp b/puppet/modules/nagios/manifests/debian.pp new file mode 100644 index 00000000..39af973e --- /dev/null +++ b/puppet/modules/nagios/manifests/debian.pp @@ -0,0 +1,54 @@ +# debian specific things +class nagios::debian inherits nagios::base { + + Package['nagios'] { name => 'nagios3' } + + package { [ 'nagios-plugins', 'nagios-snmp-plugins','nagios-nrpe-plugin' ]: + ensure => 'present', + notify => Service['nagios'], + } + + Service['nagios'] { + name => 'nagios3', + hasstatus => true, + } + + File['nagios_htpasswd', 'nagios_cgi_cfg'] { group => 'www-data' } + + file{ + 'nagios_commands_cfg': + path => "${nagios::defaults::vars::int_cfgdir}/commands.cfg", + notify => Service['nagios'], + owner => root, + group => root, + mode => '0644', + require => Package['nagios']; + "${nagios::defaults::vars::int_cfgdir}/stylesheets": + ensure => directory, + purge => false, + recurse => true, + require => Package['nagios']; + } + + if $nagios::allow_external_cmd { + exec { 'nagios_external_cmd_perms_overrides': + command => 'dpkg-statoverride --update --add nagios www-data 2710 /var/lib/nagios3/rw && dpkg-statoverride --update --add nagios nagios 751 /var/lib/nagios3', + unless => 'dpkg-statoverride --list nagios www-data 2710 /var/lib/nagios3/rw && dpkg-statoverride --list nagios nagios 751 /var/lib/nagios3', + logoutput => false, + notify => Service['nagios'], + require => Package['nagios'], + } + exec { 'nagios_external_cmd_perms_1': + command => 'chmod 0751 /var/lib/nagios3 && chown nagios:nagios /var/lib/nagios3', + unless => 'test "`stat -c "%a %U %G" /var/lib/nagios3`" = "751 nagios nagios"', + notify => Service['nagios'], + require => Package['nagios'], + } + exec { 'nagios_external_cmd_perms_2': + command => 'chmod 2751 /var/lib/nagios3/rw && chown nagios:www-data /var/lib/nagios3/rw', + unless => 'test "`stat -c "%a %U %G" /var/lib/nagios3/rw`" = "2751 nagios www-data"', + notify => Service['nagios'], + require => Package['nagios'], + } + } +} diff --git a/puppet/modules/nagios/manifests/debian/apache.pp b/puppet/modules/nagios/manifests/debian/apache.pp new file mode 100644 index 00000000..17b60c60 --- /dev/null +++ b/puppet/modules/nagios/manifests/debian/apache.pp @@ -0,0 +1,22 @@ +# Handle files that are specifically needed for nagios with apache on debian +# +# Do not include this class directly. It is included by the nagios class and +# needs variables from it. +# +class nagios::debian::apache { + + include ::nagios::defaults::vars + + file { "${nagios::defaults::vars::int_cfgdir}/apache2.conf": + source => [ "puppet:///modules/site_nagios/configs/${::fqdn}/apache2.conf", + 'puppet:///modules/site_nagios/configs/apache2.conf', + 'puppet:///modules/nagios/configs/apache2.conf'], + } + + apache::config::global { 'nagios3.conf': + ensure => link, + target => "${nagios::defaults::vars::int_cfgdir}/apache2.conf", + require => File["${nagios::defaults::vars::int_cfgdir}/apache2.conf"], + } + +} diff --git a/puppet/modules/nagios/manifests/defaults.pp b/puppet/modules/nagios/manifests/defaults.pp new file mode 100644 index 00000000..7c25ac94 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults.pp @@ -0,0 +1,12 @@ +class nagios::defaults { + + # include some default nagios objects + + include nagios::defaults::commands + include nagios::defaults::contactgroups + include nagios::defaults::contacts + include nagios::defaults::hostgroups + include nagios::defaults::templates + include nagios::defaults::timeperiods + include nagios::defaults::plugins +} diff --git a/puppet/modules/nagios/manifests/defaults/commands.pp b/puppet/modules/nagios/manifests/defaults/commands.pp new file mode 100644 index 00000000..0f24411f --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/commands.pp @@ -0,0 +1,145 @@ +# defaults commands we wanna have available +class nagios::defaults::commands { + + include ::nagios::command::smtp + include ::nagios::command::imap_pop3 + include ::nagios::plugins::horde_login + + # common service commands + case $::operatingsystem { + 'Debian','Ubuntu': { + nagios_command { + 'check_dummy': + command_line => '$USER1$/check_dummy $ARG1$'; + 'check_https_cert': + command_line => '$USER1$/check_http --ssl -C 20 -H $HOSTADDRESS$ -I $HOSTADDRESS$'; + 'check_http_url': + command_line => '$USER1$/check_http -H $ARG1$ -u $ARG2$'; + 'check_http_url_regex': + command_line => '$USER1$/check_http -H $ARG1$ -p $ARG2$ -u $ARG3$ -e $ARG4$'; + 'check_https_url': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -u $ARG2$'; + 'check_https_url_regex': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -u $ARG2$ -e $ARG3$'; + 'check_mysql_db': + command_line => '$USER1$/check_mysql -H $ARG1$ -P $ARG2$ -u $ARG3$ -p $ARG4$ -d $ARG5$'; + 'check_ntp_time': + command_line => '$USER1$/check_ntp_time -H $HOSTADDRESS$ -w 0.5 -c 1'; + 'check_silc': + command_line => '$USER1$/check_tcp -p 706 -H $ARG1$'; + 'check_sobby': + command_line => '$USER1$/check_tcp -H $ARG1$ -p $ARG2$'; + 'check_jabber': + command_line => '$USER1$/check_jabber -H $ARG1$'; + 'check_git': + command_line => '$USER1$/check_tcp -H $ARG1$ -p 9418'; + } + } + default: { + nagios_command { + 'check_dummy': + command_line => '$USER1$/check_dummy $ARG1$'; + 'check_ping': + command_line => '$USER1$/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$'; + 'check-host-alive': + command_line => '$USER1$/check_ping -H $HOSTADDRESS$ -w 5000,100% -c 5000,100% -p 1'; + 'check_tcp': + command_line => '$USER1$/check_tcp -H $HOSTADDRESS$ -p $ARG1$'; + 'check_udp': + command_line => '$USER1$/check_udp -H $HOSTADDRESS$ -p $ARG1$'; + 'check_load': + command_line => '$USER1$/check_load --warning=$ARG1$,$ARG2$,$ARG3$ --critical=$ARG4$,$ARG5$,$ARG6$'; + 'check_disk': + command_line => '$USER1$/check_disk -w $ARG1$ -c $ARG2$ -e -p $ARG3$'; + 'check_all_disks': + command_line => '$USER1$/check_disk -w $ARG1$ -c $ARG2$ -e'; + 'check_ssh': + command_line => '$USER1$/check_ssh $HOSTADDRESS$'; + 'check_ssh_port': + command_line => '$USER1$/check_ssh -p $ARG1$ $HOSTADDRESS$'; + 'check_ssh_port_host': + command_line => '$USER1$/check_ssh -p $ARG1$ $ARG2$'; + 'check_http': + command_line => '$USER1$/check_http -H $HOSTADDRESS$ -I $HOSTADDRESS$'; + 'check_https': + command_line => '$USER1$/check_http --ssl -H $HOSTADDRESS$ -I $HOSTADDRESS$'; + 'check_https_cert': + command_line => '$USER1$/check_http --ssl -C 20 -H $HOSTADDRESS$ -I $HOSTADDRESS$'; + 'check_http_url': + command_line => '$USER1$/check_http -H $ARG1$ -u $ARG2$'; + 'check_http_url_regex': + command_line => '$USER1$/check_http -H $ARG1$ -p $ARG2$ -u $ARG3$ -e $ARG4$'; + 'check_https_url': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -u $ARG2$'; + 'check_https_url_regex': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -u $ARG2$ -e $ARG3$'; + 'check_mysql': + command_line => '$USER1$/check_mysql -H $ARG1$ -P $ARG2$ -u $ARG3$ -p $ARG4$'; + 'check_mysql_db': + command_line => '$USER1$/check_mysql -H $ARG1$ -P $ARG2$ -u $ARG3$ -p $ARG4$ -d $ARG5$'; + 'check_ntp_time': + command_line => '$USER1$/check_ntp_time -H $HOSTADDRESS$ -w 0.5 -c 1'; + 'check_silc': + command_line => '$USER1$/check_tcp -p 706 -H $ARG1$'; + 'check_sobby': + command_line => '$USER1$/check_tcp -H $ARG1$ -p $ARG2$'; + 'check_jabber': + command_line => '$USER1$/check_jabber -H $ARG1$'; + 'check_git': + command_line => '$USER1$/check_tcp -H $ARG1$ -p 9418'; + } + } + } + + # commands for services defined by other modules + + nagios_command { + # from apache module + 'http_port': + command_line => '$USER1$/check_http -p $ARG1$ -H $HOSTADDRESS$ -I $HOSTADDRESS$'; + + 'check_http_port_url_content': + command_line => '$USER1$/check_http -H $ARG1$ -p $ARG2$ -u $ARG3$ -s $ARG4$'; + 'check_https_port_url_content': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -p $ARG2$ -u $ARG3$ -s $ARG4$'; + 'check_http_url_content': + command_line => '$USER1$/check_http -H $ARG1$ -u $ARG2$ -s $ARG3$'; + 'check_https_url_content': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -u $ARG2$ -s $ARG3$'; + + # from bind module + 'check_dig2': + command_line => '$USER1$/check_dig -H $HOSTADDRESS$ -l $ARG1$ --record_type=$ARG2$'; + + # from mysql module + 'check_mysql_health': + command_line => '$USER1$/check_mysql_health --hostname $ARG1$ --port $ARG2$ --username $ARG3$ --password $ARG4$ --mode $ARG5$ --database $ARG6$ $ARG7$ $ARG8$'; + + # better check_dns + 'check_dns2': + command_line => '$USER1$/check_dns2 -c $ARG1$ A $ARG2$'; + + # dnsbl checking + 'check_dnsbl': + command_line => '$USER1$/check_dnsbl -H $ARG1$'; + } + + # notification commands + + $mail_cmd_location = $::operatingsystem ? { + 'CentOS' => '/bin/mail', + default => '/usr/bin/mail' + } + + case $::lsbdistcodename { + 'wheezy': { } + default: { + nagios_command { + 'notify-host-by-email': + command_line => "/usr/bin/printf \"%b\" \"***** Nagios *****\\n\\nNotification Type: \$NOTIFICATIONTYPE\$\\n\\nHost: \$HOSTNAME\$ (\$HOSTALIAS\$)\\nAddress: \$HOSTADDRESS\$\\nState: \$HOSTSTATE\$\\nDuration: \$HOSTDURATION\$\\n\\nDate/Time: \$LONGDATETIME\$\\n\\nOutput: \$HOSTOUTPUT\$\" | ${mail_cmd_location} -s \"\$NOTIFICATIONTYPE\$: \$HOSTSTATE\$ - \$HOSTNAME\$\" \$CONTACTEMAIL\$"; + 'notify-service-by-email': + command_line => "/usr/bin/printf \"%b\" \"***** Nagios *****\\n\\nNotification Type: \$NOTIFICATIONTYPE\$\\n\\nHost: \$HOSTNAME\$ (\$HOSTALIAS\$)\\nAddress: \$HOSTADDRESS\$\\n\\nService: \$SERVICEDESC\$\\nState: \$SERVICESTATE\$\\nDuration: \$SERVICEDURATION\$\\n\\nDate/Time: \$LONGDATETIME\$\\n\\nOutput: \$SERVICEOUTPUT\$\" | ${mail_cmd_location} -s \"\$NOTIFICATIONTYPE\$: \$SERVICESTATE\$ - \$HOSTALIAS\$/\$SERVICEDESC\$\" \$CONTACTEMAIL\$"; + } + } + } +} diff --git a/puppet/modules/nagios/manifests/defaults/contactgroups.pp b/puppet/modules/nagios/manifests/defaults/contactgroups.pp new file mode 100644 index 00000000..f5affc60 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/contactgroups.pp @@ -0,0 +1,9 @@ +class nagios::defaults::contactgroups { + + nagios_contactgroup { + 'admins': + alias => 'Nagios Administrators', + members => 'root', + } + +} diff --git a/puppet/modules/nagios/manifests/defaults/contacts.pp b/puppet/modules/nagios/manifests/defaults/contacts.pp new file mode 100644 index 00000000..0252b5a8 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/contacts.pp @@ -0,0 +1,15 @@ +class nagios::defaults::contacts { + + nagios_contact { + 'root': + alias => 'Root', + service_notification_period => '24x7', + host_notification_period => '24x7', + service_notification_options => 'w,u,c,r', + host_notification_options => 'd,r', + service_notification_commands => 'notify-service-by-email', + host_notification_commands => 'notify-host-by-email', + email => 'root@localhost', + } + +} diff --git a/puppet/modules/nagios/manifests/defaults/host_templates.pp b/puppet/modules/nagios/manifests/defaults/host_templates.pp new file mode 100644 index 00000000..0f47324a --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/host_templates.pp @@ -0,0 +1,24 @@ +class nagios::defaults::host_templates { + + # this inoperative for the moment, see : + # http://projects.reductivelabs.com/issues/1180 + + nagios_host { + 'generic-host': + notifications_enabled => '1', + event_handler_enabled => '1', + flap_detection_enabled => '1', + failure_prediction_enabled => '1', + process_perf_data => '1', + retain_status_information => '1', + retain_nonstatus_information => '1', + check_command => 'check-host-alive', + max_check_attempts => '10', + notification_interval => '0', + notification_period => '24x7', + notification_options => 'd,u,r', + contact_groups => 'admins', + register => '0', + } + +} diff --git a/puppet/modules/nagios/manifests/defaults/hostgroups.pp b/puppet/modules/nagios/manifests/defaults/hostgroups.pp new file mode 100644 index 00000000..8715adee --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/hostgroups.pp @@ -0,0 +1,11 @@ +class nagios::defaults::hostgroups { + nagios_hostgroup { + 'all': + alias => 'All Servers', + members => '*'; + 'debian-servers': + alias => 'Debian GNU/Linux Servers'; + 'centos-servers': + alias => 'CentOS GNU/Linux Servers'; + } +} diff --git a/puppet/modules/nagios/manifests/defaults/plugins.pp b/puppet/modules/nagios/manifests/defaults/plugins.pp new file mode 100644 index 00000000..abd8b528 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/plugins.pp @@ -0,0 +1,10 @@ +class nagios::defaults::plugins { + nagios::plugin { + 'check_mysql_health': + source => 'nagios/plugins/check_mysql_health'; + 'check_dns2': + source => 'nagios/plugins/check_dns2'; + 'check_dnsbl': + source => 'nagios/plugins/check_dnsbl'; + } +} diff --git a/puppet/modules/nagios/manifests/defaults/pnp4nagios.pp b/puppet/modules/nagios/manifests/defaults/pnp4nagios.pp new file mode 100644 index 00000000..58676c5a --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/pnp4nagios.pp @@ -0,0 +1,14 @@ +# configure default cmds for pnp4nagios +class nagios::defaults::pnp4nagios { + + # performance data cmds + # http://docs.pnp4nagios.org/de/pnp-0.6/config#bulk_mode_mit_npcd + nagios_command { + 'process-service-perfdata-file-pnp4nagios-bulk-npcd': + command_line => '/bin/mv /var/lib/nagios3/service-perfdata /var/spool/pnp4nagios/npcd/service-perfdata.$TIMET$', + require => Package['nagios']; + 'process-host-perfdata-file-pnp4nagios-bulk-npcd': + command_line => '/bin/mv /var/lib/nagios3/host-perfdata /var/spool/pnp4nagios/npcd/host-perfdata.$TIMET$', + require => Package['nagios']; + } +} diff --git a/puppet/modules/nagios/manifests/defaults/service_templates.pp b/puppet/modules/nagios/manifests/defaults/service_templates.pp new file mode 100644 index 00000000..e39441a1 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/service_templates.pp @@ -0,0 +1,32 @@ +# define the generic service template +class nagios::defaults::service_templates { + + # this inoperative for the moment, see : + # http://projects.reductivelabs.com/issues/1180 + + nagios_service { + 'generic-service': + active_checks_enabled => '1', + passive_checks_enabled => '1', + parallelize_check => '1', + obsess_over_service => '1', + check_freshness => '0', + notifications_enabled => '1', + event_handler_enabled => '1', + flap_detection_enabled => '1', + failure_prediction_enabled => '1', + process_perf_data => '1', + retain_status_information => '1', + retain_nonstatus_information => '1', + notification_interval => '0', + is_volatile => '0', + check_period => '24x7', + check_interval => '5', + retry_check_interval => '1', + max_check_attempts => '4', + notification_period => '24x7', + notification_options => 'w,u,c,r', + contact_groups => 'admins', + register => '0', + } +} diff --git a/puppet/modules/nagios/manifests/defaults/templates.pp b/puppet/modules/nagios/manifests/defaults/templates.pp new file mode 100644 index 00000000..5158189c --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/templates.pp @@ -0,0 +1,17 @@ +# manage nagios_templates +class nagios::defaults::templates { + include nagios::defaults::vars + + file { 'nagios_templates': + path => "${nagios::defaults::vars::int_cfgdir}/nagios_templates.cfg", + source => [ "puppet:///modules/site_nagios/configs/${::fqdn}/nagios_templates.cfg", + "puppet:///modules/site_nagios/configs/${::operatingsystem}/nagios_templates.cfg", + 'puppet:///modules/site_nagios/configs/nagios_templates.cfg', + "puppet:///modules/nagios/configs/${::operatingsystem}/nagios_templates.cfg", + 'puppet:///modules/nagios/configs/nagios_templates.cfg' ], + notify => Service['nagios'], + owner => root, + group => root, + mode => '0644'; + } +} diff --git a/puppet/modules/nagios/manifests/defaults/timeperiods.pp b/puppet/modules/nagios/manifests/defaults/timeperiods.pp new file mode 100644 index 00000000..0d05118a --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/timeperiods.pp @@ -0,0 +1,33 @@ +class nagios::defaults::timeperiods { + + nagios_timeperiod { + '24x7': + alias => '24 Hours A Day, 7 Days A Week', + sunday => '00:00-24:00', + monday => '00:00-24:00', + tuesday => '00:00-24:00', + wednesday => '00:00-24:00', + thursday => '00:00-24:00', + friday => '00:00-24:00', + saturday => '00:00-24:00'; + 'workhours': + alias => 'Standard Work Hours', + monday => '09:00-17:00', + tuesday => '09:00-17:00', + wednesday => '09:00-17:00', + thursday => '09:00-17:00', + friday => '09:00-17:00'; + 'nonworkhours': + alias => 'Non-Work Hours', + sunday => '00:00-24:00', + monday => '00:00-09:00,17:00-24:00', + tuesday => '00:00-09:00,17:00-24:00', + wednesday => '00:00-09:00,17:00-24:00', + thursday => '00:00-09:00,17:00-24:00', + friday => '00:00-09:00,17:00-24:00', + saturday => '00:00-24:00'; + 'never': + alias => 'Never'; + } + +} diff --git a/puppet/modules/nagios/manifests/defaults/vars.pp b/puppet/modules/nagios/manifests/defaults/vars.pp new file mode 100644 index 00000000..e1a62245 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/vars.pp @@ -0,0 +1,11 @@ +# some default vars +class nagios::defaults::vars { + case $nagios::cfgdir { + '': { $int_cfgdir = $::operatingsystem ? { + centos => '/etc/nagios', + default => '/etc/nagios3' + } + } + default: { $int_cfgdir = $nagios::cfgdir } + } +} diff --git a/puppet/modules/nagios/manifests/headless.pp b/puppet/modules/nagios/manifests/headless.pp new file mode 100644 index 00000000..ba8af8f4 --- /dev/null +++ b/puppet/modules/nagios/manifests/headless.pp @@ -0,0 +1,5 @@ +class nagios::headless { + class { 'nagios': + httpd => 'absent', + } +} diff --git a/puppet/modules/nagios/manifests/init.pp b/puppet/modules/nagios/manifests/init.pp new file mode 100644 index 00000000..e3421a0a --- /dev/null +++ b/puppet/modules/nagios/manifests/init.pp @@ -0,0 +1,56 @@ +# +# nagios module +# nagios.pp - everything nagios related +# +# Copyright (C) 2007 David Schmitt +# Copyright 2008, admin(at)immerda.ch +# Copyright 2008, Puzzle ITC GmbH +# Marcel Haerry haerry+puppet(at)puzzle.ch +# Simon Josi josi+puppet(at)puzzle.ch +# +# This program is free software; you can redistribute +# it and/or modify it under the terms of the GNU +# General Public License version 3 as published by +# the Free Software Foundation. +# + +# manage nagios +class nagios( + $httpd = 'apache', + $allow_external_cmd = false, + $manage_shorewall = false, + $manage_munin = false, + $service_atboot = true, + $purge_resources = true, + $gpgkey_checks = {}, + $storeconfigs = true +) { + case $nagios::httpd { + 'absent': { } + 'lighttpd': { include ::lighttpd } + 'apache': { + include ::apache + if $::operatingsystem == 'Debian' { + include ::nagios::debian::apache + } + } + default: { include ::apache } + } + case $::operatingsystem { + 'centos': { + $cfgdir = '/etc/nagios' + include ::nagios::centos + } + 'debian': { + $cfgdir = '/etc/nagios3' + include ::nagios::debian + } + default: { + fail("No such operatingsystem: ${::operatingsystem} yet defined") + } + } + if $manage_munin { + include ::nagios::munin + } + create_resources('nagios::service::gpgkey',$gpgkey_checks) +} diff --git a/puppet/modules/nagios/manifests/irc_bot.pp b/puppet/modules/nagios/manifests/irc_bot.pp new file mode 100644 index 00000000..7e934ef1 --- /dev/null +++ b/puppet/modules/nagios/manifests/irc_bot.pp @@ -0,0 +1,50 @@ +class nagios::irc_bot( + $nsa_socket = 'absent', + $nsa_server, + $nsa_port = 6667, + $nsa_nickname, + $nsa_password = '', + $nsa_channel, + $nsa_pidfile = 'absent', + $nsa_realname = 'Nagios', + $nsa_usenotices = false, + $nsa_commandfile = 'absent' +) { + $real_nsa_socket = $nsa_socket ? { + 'absent' => $::operatingsystem ? { + centos => '/var/run/nagios-nsa/nsa.socket', + default => '/var/run/nagios3/nsa.socket' + }, + default => $nsa_socket, + } + $real_nsa_pidfile = $nsa_pidfile ? { + 'absent' => $::operatingsystem ? { + centos => '/var/run/nagios-nsa/nsa.pid', + default => '/var/run/nagios3/nsa.pid' + }, + default => $nsa_pidfile, + } + $real_nsa_commandfile = $nsa_commandfile ? { + 'absent' => $::operatingsystem ? { + centos => '/var/spool/nagios/cmd/nagios.cmd', + default => '/var/lib/nagios3/rw/nagios.cmd' + }, + default => $nsa_commandfile, + } + + case $::operatingsystem { + centos: { + include nagios::irc_bot::centos + } + debian,ubuntu: { + include nagios::irc_bot::debian + } + default: { + include nagios::irc_bot::base + } + } + + if $nagios::manage_shorewall { + include shorewall::rules::out::irc + } +} diff --git a/puppet/modules/nagios/manifests/irc_bot/base.pp b/puppet/modules/nagios/manifests/irc_bot/base.pp new file mode 100644 index 00000000..fff9da4f --- /dev/null +++ b/puppet/modules/nagios/manifests/irc_bot/base.pp @@ -0,0 +1,41 @@ +class nagios::irc_bot::base { + file { + '/usr/local/bin/riseup-nagios-client.pl': + source => 'puppet:///modules/nagios/irc_bot/riseup-nagios-client.pl', + owner => root, group => 0, mode => '0755'; + + '/usr/local/bin/riseup-nagios-server.pl': + source => 'puppet:///modules/nagios/irc_bot/riseup-nagios-server.pl', + owner => root, group => 0, mode => '0755'; + + '/etc/init.d/nagios-nsa': + content => template("nagios/irc_bot/${::operatingsystem}/nagios-nsa.sh.erb"), + require => File['/usr/local/bin/riseup-nagios-server.pl'], + owner => root, group => 0, mode => '0755'; + + '/etc/nagios_nsa.cfg': + ensure => present, + content => template('nagios/irc_bot/nsa.cfg.erb'), + owner => nagios, group => 0, mode => '0400', + notify => Service['nagios-nsa']; + } + + package { 'libnet-irc-perl': + ensure => present, + } + + service { 'nagios-nsa': + ensure => 'running', + hasstatus => true, + require => [ File['/etc/nagios_nsa.cfg'], + Package['libnet-irc-perl'], + Service['nagios'] ], + } + + nagios_command { + 'notify-by-irc': + command_line => '/usr/local/bin/riseup-nagios-client.pl "$HOSTNAME$ ($SERVICEDESC$) $NOTIFICATIONTYPE$ n.$SERVICEATTEMPT$ $SERVICESTATETYPE$ $SERVICEEXECUTIONTIME$s $SERVICELATENCY$s $SERVICEOUTPUT$ $SERVICEPERFDATA$"'; + 'host-notify-by-irc': + command_line => '/usr/local/bin/riseup-nagios-client.pl "$HOSTNAME$ ($HOSTALIAS$) $NOTIFICATIONTYPE$ n.$HOSTATTEMPT$ $HOSTSTATETYPE$ took $HOSTEXECUTIONTIME$s $HOSTOUTPUT$ $HOSTPERFDATA$ $HOSTLATENCY$s"'; + } +} diff --git a/puppet/modules/nagios/manifests/irc_bot/centos.pp b/puppet/modules/nagios/manifests/irc_bot/centos.pp new file mode 100644 index 00000000..d7b19063 --- /dev/null +++ b/puppet/modules/nagios/manifests/irc_bot/centos.pp @@ -0,0 +1,9 @@ +class nagios::irc_bot::centos inherits nagios::irc_bot::base { + Package['libnet-irc-perl']{ + name => 'perl-Net-IRC', + } + + Service['nagios-nsa']{ + enable => true, + } +} diff --git a/puppet/modules/nagios/manifests/irc_bot/debian.pp b/puppet/modules/nagios/manifests/irc_bot/debian.pp new file mode 100644 index 00000000..93ea64b8 --- /dev/null +++ b/puppet/modules/nagios/manifests/irc_bot/debian.pp @@ -0,0 +1,8 @@ +class nagios::irc_bot::debian inherits nagios::irc_bot::base { + exec { "nagios_nsa_init_script": + command => "/usr/sbin/update-rc.d nagios-nsa defaults", + unless => "/bin/ls /etc/rc3.d/ | /bin/grep nagios-nsa", + require => File["/etc/init.d/nagios-nsa"], + before => Service['nagios-nsa'], + } +} diff --git a/puppet/modules/nagios/manifests/irc_bot/disable.pp b/puppet/modules/nagios/manifests/irc_bot/disable.pp new file mode 100644 index 00000000..d6b7c551 --- /dev/null +++ b/puppet/modules/nagios/manifests/irc_bot/disable.pp @@ -0,0 +1,8 @@ +class nagios::irc_bot::disable inherits nagios::irc_bot::base { + + Service['nagios-nsa'] { + ensure => stopped, + enable => false, + } + +} diff --git a/puppet/modules/nagios/manifests/lighttpd.pp b/puppet/modules/nagios/manifests/lighttpd.pp new file mode 100644 index 00000000..0f298964 --- /dev/null +++ b/puppet/modules/nagios/manifests/lighttpd.pp @@ -0,0 +1,12 @@ +class nagios::lighttpd( + $allow_external_cmd = false, + $manage_shorewall = false, + $manage_munin = false +) { + class{'nagios': + httpd => 'lighttpd', + allow_external_cmd => $allow_external_cmd, + manage_munin => $manage_munin, + manage_shorewall => $manage_shorewall, + } +} diff --git a/puppet/modules/nagios/manifests/munin.pp b/puppet/modules/nagios/manifests/munin.pp new file mode 100644 index 00000000..dc5cc4c3 --- /dev/null +++ b/puppet/modules/nagios/manifests/munin.pp @@ -0,0 +1,19 @@ +class nagios::munin { + include munin::plugins::base + + munin::plugin::deploy { + 'nagios_hosts': + source => 'nagios/munin/nagios_hosts', + config => 'user nagios'; + 'nagios_svc': + source => 'nagios/munin/nagios_svc', + config => 'user nagios'; + 'nagios_perf_hosts': + source => 'nagios/munin/nagios_perf', + config => 'user nagios'; + 'nagios_perf_svc': + source => 'nagios/munin/nagios_perf', + config => 'user nagios'; + } + +} diff --git a/puppet/modules/nagios/manifests/nrpe.pp b/puppet/modules/nagios/manifests/nrpe.pp new file mode 100644 index 00000000..b7984b6e --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe.pp @@ -0,0 +1,41 @@ +# setup nrpe stuff +class nagios::nrpe ( + $cfg_dir = '', + $pid_file = '', + $plugin_dir = '', + $server_address = '', + $allowed_hosts = '', + $dont_blame = '0', +) { + + if !($dont_blame in ['0', '1']) { + fail('Unrecognized value for $dont_blame, must be one of "0", or "1".') + } + + case $::operatingsystem { + 'FreeBSD': { + if $cfg_dir == '' { $real_cfg_dir = '/usr/local/etc' } + if $pid_file == '' { $real_pid_file = '/var/spool/nagios/nrpe2.pid' } + if $plugin_dir == '' { $real_plugin_dir = '/usr/local/libexec/nagios' } + + include ::nagios::nrpe::freebsd + } + 'Debian': { + if $cfg_dir == '' { $real_cfg_dir = '/etc/nagios' } + if $pid_file == '' { $real_pid_file = '/var/run/nagios/nrpe.pid' } + if $plugin_dir == '' { $real_plugin_dir = '/usr/lib/nagios/plugins' } + include ::nagios::nrpe::linux + } + default: { + if $cfg_dir == '' { $real_cfg_dir = '/etc/nagios' } + if $pid_file == '' { $real_pid_file = '/var/run/nrpe.pid' } + if $plugin_dir == '' { $real_plugin_dir = '/usr/lib/nagios/plugins' } + + case $::kernel { + 'Linux': { include ::nagios::nrpe::linux } + default: { include ::nagios::nrpe::base } + } + } + } + +} diff --git a/puppet/modules/nagios/manifests/nrpe/base.pp b/puppet/modules/nagios/manifests/nrpe/base.pp new file mode 100644 index 00000000..e48e87b4 --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/base.pp @@ -0,0 +1,58 @@ +# basic nrpe stuff +class nagios::nrpe::base { + + # Import all variables from entry point + $cfg_dir = $::nagios::nrpe::real_cfg_dir + $pid_file = $::nagios::nrpe::real_pid_file + $plugin_dir = $::nagios::nrpe::real_plugin_dir + $server_address = $::nagios::nrpe::server_address + $allowed_hosts = $::nagios::nrpe::allowed_hosts + $dont_blame = $::nagios::nrpe::dont_blame + + package{['nagios-nrpe-server', 'nagios-plugins-basic', 'libwww-perl']: + ensure => installed; + } + + # Special-case lenny. the package doesn't exist + if $::lsbdistcodename != 'lenny' { + package{'libnagios-plugin-perl': ensure => installed; } + } + + file{ + [ $cfg_dir, "${cfg_dir}/nrpe.d" ]: + ensure => directory; + } + + file { "${cfg_dir}/nrpe.cfg": + content => template('nagios/nrpe/nrpe.cfg'), + owner => root, + group => 0, + mode => '0644'; + } + + # default commands + nagios::nrpe::command{'basic_nrpe': + source => [ "puppet:///modules/site_nagios/configs/nrpe/nrpe_commands.${::fqdn}.cfg", + 'puppet:///modules/site_nagios/configs/nrpe/nrpe_commands.cfg', + 'puppet:///modules/nagios/nrpe/nrpe_commands.cfg' ], + } + # the check for load should be customized for each server based on number + # of CPUs and the type of activity. + $warning_1_threshold = 7 * $::processorcount + $warning_5_threshold = 6 * $::processorcount + $warning_15_threshold = 5 * $::processorcount + $critical_1_threshold = 10 * $::processorcount + $critical_5_threshold = 9 * $::processorcount + $critical_15_threshold = 8 * $::processorcount + nagios::nrpe::command {'check_load': + command_line => "${plugin_dir}/check_load -w ${warning_1_threshold},${warning_5_threshold},${warning_15_threshold} -c ${critical_1_threshold},${critical_5_threshold},${critical_15_threshold}", + } + + service{'nagios-nrpe-server': + ensure => running, + enable => true, + pattern => 'nrpe', + subscribe => File["${cfg_dir}/nrpe.cfg"], + require => Package['nagios-nrpe-server'], + } +} diff --git a/puppet/modules/nagios/manifests/nrpe/command.pp b/puppet/modules/nagios/manifests/nrpe/command.pp new file mode 100644 index 00000000..c66ab986 --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/command.pp @@ -0,0 +1,34 @@ +# manage an nrpe command +define nagios::nrpe::command ( + $ensure = present, + $command_line = '', + $source = '', +){ + if ($command_line == '' and $source == '') { + fail('Either one of $command_line or $source must be given to nagios::nrpe::command.' ) + } + + $cfg_dir = $nagios::nrpe::real_cfg_dir + + file{"${cfg_dir}/nrpe.d/${name}_command.cfg": + ensure => $ensure, + notify => Service['nagios-nrpe-server'], + require => File["${cfg_dir}/nrpe.d" ], + owner => 'root', + group => 0, + mode => '0644'; + } + + case $source { + '': { + File["${cfg_dir}/nrpe.d/${name}_command.cfg"] { + content => template('nagios/nrpe/nrpe_command.erb'), + } + } + default: { + File["${cfg_dir}/nrpe.d/${name}_command.cfg"] { + source => $source, + } + } + } +} diff --git a/puppet/modules/nagios/manifests/nrpe/debian.pp b/puppet/modules/nagios/manifests/nrpe/debian.pp new file mode 100644 index 00000000..fcaf8514 --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/debian.pp @@ -0,0 +1,6 @@ +class nagios::nrpe::debian inherits nagios::nrpe::base { + include nagios::nrpe::linux + Service['nagios-nrpe-server'] { + hasstatus => false, + } +} diff --git a/puppet/modules/nagios/manifests/nrpe/freebsd.pp b/puppet/modules/nagios/manifests/nrpe/freebsd.pp new file mode 100644 index 00000000..063b79bc --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/freebsd.pp @@ -0,0 +1,16 @@ +class nagios::nrpe::freebsd inherits nagios::nrpe::base { + + Package["nagios-nrpe-server"] { name => "nrpe" } + Package["nagios-plugins-basic"] { name => "nagios-plugins" } + Package["libnagios-plugin-perl"] { name => "p5-Nagios-Plugin" } + Package["libwww-perl"] { name => "p5-libwww" } + + # TODO check_cpustats.sh is probably not working as of now. the package 'sysstat' is not available under FreeBSD + + Service["nagios-nrpe-server"] { + pattern => "^/usr/local/sbin/nrpe2", + path => "/usr/local/etc/rc.d", + name => "nrpe2", + hasstatus => "false", + } +} diff --git a/puppet/modules/nagios/manifests/nrpe/linux.pp b/puppet/modules/nagios/manifests/nrpe/linux.pp new file mode 100644 index 00000000..14e007f3 --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/linux.pp @@ -0,0 +1,9 @@ +class nagios::nrpe::linux inherits nagios::nrpe::base { + + package { + "nagios-plugins-standard": ensure => present; + "ksh": ensure => present; # for check_cpustats.sh + "sysstat": ensure => present; # for check_cpustats.sh + } + +} diff --git a/puppet/modules/nagios/manifests/nrpe/xinetd.pp b/puppet/modules/nagios/manifests/nrpe/xinetd.pp new file mode 100644 index 00000000..4de0bac6 --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/xinetd.pp @@ -0,0 +1,11 @@ +# This is created only to cope with cases where we're not the only ones +# administering a machine and NRPE is running in xinetd. +class nagios::nrpe::xinetd inherits base { + + Service["nagios-nrpe-server"] { + ensure => stopped, + } + + # TODO manage the xinetd config file that glues with NRPE + +} diff --git a/puppet/modules/nagios/manifests/nsca.pp b/puppet/modules/nagios/manifests/nsca.pp new file mode 100644 index 00000000..d5be298c --- /dev/null +++ b/puppet/modules/nagios/manifests/nsca.pp @@ -0,0 +1,3 @@ +class nagios::nsca { + include nagios::nsca::server +} diff --git a/puppet/modules/nagios/manifests/nsca/client.pp b/puppet/modules/nagios/manifests/nsca/client.pp new file mode 100644 index 00000000..6aa8c0b1 --- /dev/null +++ b/puppet/modules/nagios/manifests/nsca/client.pp @@ -0,0 +1,18 @@ +# manage nsca client +class nagios::nsca::client { + + package{'nsca': + ensure => installed + } + + file{'/etc/send_nsca.cfg': + source => [ "puppet:///modules/site_nagios/nsca/${::fqdn}/send_nsca.cfg", + 'puppet:///modules/site_nagios/nsca/send_nsca.cfg', + 'puppet:///modules/nagios/nsca/send_nsca.cfg' ], + owner => 'nagios', + group => 'nogroup', + mode => '0400', + require => Package['nsca']; + } + +} diff --git a/puppet/modules/nagios/manifests/nsca/server.pp b/puppet/modules/nagios/manifests/nsca/server.pp new file mode 100644 index 00000000..8163eec1 --- /dev/null +++ b/puppet/modules/nagios/manifests/nsca/server.pp @@ -0,0 +1,24 @@ +# an nsca server +class nagios::nsca::server { + package{'nsca': + ensure => installed + } + + service { 'nsca': + ensure => running, + hasstatus => false, + hasrestart => true, + require => Package['nsca'], + } + + file { '/etc/nsca.cfg': + source => [ "puppet:///modules/site_nagios/nsca/${::fqdn}/nsca.cfg", + 'puppet:///modules/site_nagios/nsca/nsca.cfg', + 'puppet:///modules/nagios/nsca/nsca.cfg' ], + owner => 'nagios', + group => 'nogroup', + mode => '0400', + notify => Service['nsca'], + } + +} diff --git a/puppet/modules/nagios/manifests/plugin.pp b/puppet/modules/nagios/manifests/plugin.pp new file mode 100644 index 00000000..07938cd2 --- /dev/null +++ b/puppet/modules/nagios/manifests/plugin.pp @@ -0,0 +1,28 @@ +# a wrapper for syncing a plugin +define nagios::plugin( + $source = 'absent', + $ensure = present, +){ + if $::hardwaremodel == 'x86_64' and $::operatingsystem != 'Debian' { + $real_path = "/usr/lib64/nagios/plugins/${name}" + } + else { + $real_path = "/usr/lib/nagios/plugins/${name}" + } + + $real_source = $source ? { + 'absent' => "puppet:///modules/nagios/plugins/${name}", + default => "puppet:///modules/${source}" + } + + file{$name: + ensure => $ensure, + path => $real_path, + source => $real_source, + tag => 'nagios_plugin', + require => Package['nagios-plugins'], + owner => 'root', + group => 0, + mode => '0755'; + } +} diff --git a/puppet/modules/nagios/manifests/plugin/deploy.pp b/puppet/modules/nagios/manifests/plugin/deploy.pp new file mode 100644 index 00000000..76815909 --- /dev/null +++ b/puppet/modules/nagios/manifests/plugin/deploy.pp @@ -0,0 +1,41 @@ +# deploy a specific plugin +define nagios::plugin::deploy( + $source = '', + $ensure = 'present', + $config = '', + $require_package = 'nagios-plugins' +) { + $plugin_src = $ensure ? { + 'present' => $name, + 'absent' => $name, + default => $ensure + } + $real_source = $source ? { + '' => "nagios/plugins/${plugin_src}", + default => $source + } + + if !defined(Package[$require_package]) { + package { $require_package: + ensure => installed, + tag => 'nagios::plugin::deploy::package'; + } + } + + include ::nagios::plugin::scriptpaths + file{"nagios_plugin_${name}": + path => "${nagios::plugin::scriptpaths::script_path}/${name}", + source => "puppet:///modules/${real_source}", + require => Package[$require_package], + tag => 'nagios::plugin::deploy::file', + owner => root, + group => 0, + mode => '0755'; + } + + # register the plugin + nagios::plugin{$name: + ensure => $ensure, + require => Package['nagios-plugins'] + } +} diff --git a/puppet/modules/nagios/manifests/plugin/scriptpaths.pp b/puppet/modules/nagios/manifests/plugin/scriptpaths.pp new file mode 100644 index 00000000..9cd4b5d6 --- /dev/null +++ b/puppet/modules/nagios/manifests/plugin/scriptpaths.pp @@ -0,0 +1,6 @@ +class nagios::plugin::scriptpaths { + case $::hardwaremodel { + x86_64: { $script_path = "/usr/lib64/nagios/plugins/" } + default: { $script_path = "/usr/lib/nagios/plugins" } + } +} diff --git a/puppet/modules/nagios/manifests/plugins/gpg.pp b/puppet/modules/nagios/manifests/plugins/gpg.pp new file mode 100644 index 00000000..a09736a8 --- /dev/null +++ b/puppet/modules/nagios/manifests/plugins/gpg.pp @@ -0,0 +1,30 @@ +# check_gpg from +# https://github.com/lelutin/nagios-plugins/blob/master/check_gpg +class nagios::plugins::gpg { + require ::gpg + nagios::plugin{'check_gpg': + source => 'nagios/plugins/check_gpg', + } + + $gpg_home = '/var/local/nagios_gpg_homedir' + file{ + $gpg_home: + ensure => 'directory', + owner => nagios, + group => nagios, + mode => '0600', + require => Nagios::Plugin['check_gpg']; + "${gpg_home}/sks-keyservers.netCA.pem": + source => 'puppet:///modules/nagios/plugin_data/sks-keyservers.netCA.pem', + owner => nagios, + group => 0, + mode => '0400', + before => Nagios_command['check_gpg']; + } + nagios_command { + 'check_gpg': + command_line => "\$USER1\$/check_gpg --gnupg-homedir ${gpg_home} -w \$ARG1\$ \$ARG2\$", + require => Nagios::Plugin['check_gpg'], + } +} + diff --git a/puppet/modules/nagios/manifests/plugins/horde_login.pp b/puppet/modules/nagios/manifests/plugins/horde_login.pp new file mode 100644 index 00000000..4274b4cf --- /dev/null +++ b/puppet/modules/nagios/manifests/plugins/horde_login.pp @@ -0,0 +1,11 @@ +# check_horde_login +class nagios::plugins::horde_login { + ensure_packages(['python-requests']) + nagios::plugin { 'check_horde_login': + source => 'nagios/plugins/check_horde_login', + require => Package['python-requests'], + } -> nagios_command { + 'check_horde_login': + command_line => "\$USER1\$/check_horde_login -s \$ARG1\$ -u \$ARG2\$ -p \$ARG3\$", + } +} diff --git a/puppet/modules/nagios/manifests/plugins/jabber.pp b/puppet/modules/nagios/manifests/plugins/jabber.pp new file mode 100644 index 00000000..380a5c0a --- /dev/null +++ b/puppet/modules/nagios/manifests/plugins/jabber.pp @@ -0,0 +1,10 @@ +class nagios::plugins::jabber { + + # for check_jabber_login + require rubygems::xmpp4r + + nagios::plugin { 'check_jabber_login': + source => 'nagios/plugins/check_jabber_login' + } +} + diff --git a/puppet/modules/nagios/manifests/plugins/mail_login.pp b/puppet/modules/nagios/manifests/plugins/mail_login.pp new file mode 100644 index 00000000..a86cdc24 --- /dev/null +++ b/puppet/modules/nagios/manifests/plugins/mail_login.pp @@ -0,0 +1,10 @@ +# simple mail login check +class nagios::plugins::mail_login { + nagios::plugin { + 'check_imap_login': + source => 'nagios/plugins/check_imap_login'; + 'check_pop3_login': + source => 'nagios/plugins/check_pop3_login'; + } +} + diff --git a/puppet/modules/nagios/manifests/pnp4nagios.pp b/puppet/modules/nagios/manifests/pnp4nagios.pp new file mode 100644 index 00000000..bd7ab0ca --- /dev/null +++ b/puppet/modules/nagios/manifests/pnp4nagios.pp @@ -0,0 +1,68 @@ +# manage pnp4nagios +class nagios::pnp4nagios { + include nagios::defaults::pnp4nagios + + package { [ 'pnp4nagios', 'pnp4nagios-web-config-nagios3']: + ensure => installed, + require => Package['nagios'] + } + + # unfortunatly we can't use the nagios_host and nagios_service + # definition to define templates, so we need to copy a file here. + # see http://projects.reductivelabs.com/issues/1180 for this limitation + + file { 'pnp4nagios-templates.cfg': + path => "${nagios::defaults::vars::int_cfgdir}/pnp4nagios-templates.cfg", + source => [ 'puppet:///modules/site_nagios/pnp4nagios/pnp4nagios-templates.cfg', + 'puppet:///modules/nagios/pnp4nagios/pnp4nagios-templates.cfg' ], + mode => '0644', + owner => root, + group => root, + notify => Service['nagios'], + require => Package['nagios']; + } + + file { 'apache.conf': + path => '/etc/pnp4nagios/apache.conf', + source => ['puppet:///modules/site_nagios/pnp4nagios/apache.conf', + 'puppet:///modules/nagios/pnp4nagios/apache.conf' ], + mode => '0644', + owner => root, + group => root, + notify => Service['apache'], + require => [ Package['apache2'], Package['pnp4nagios'] ], + } + + # run npcd as daemon + + file { '/etc/default/npcd': + path => '/etc/default/npcd', + source => [ 'puppet:///modules/site_nagios/pnp4nagios/npcd', + 'puppet:///modules/nagios/pnp4nagios/npcd' ], + mode => '0644', + owner => root, + group => root, + notify => Service['npcd'], + require => [ Package['nagios'], Package['pnp4nagios'] ]; + } + + service { 'npcd': + ensure => running, + enable => true, + hasstatus => true, + require => Package['pnp4nagios'], + } + + # modify action.gif + + file { '/usr/share/nagios3/htdocs/images/action.gif': + path => '/usr/share/nagios3/htdocs/images/action.gif', + source => [ 'puppet:///modules/site_nagios/pnp4nagios/action.gif', + 'puppet:///modules/nagios/pnp4nagios/action.gif' ], + mode => '0644', + owner => root, + group => root, + notify => Service['nagios'], + require => Package['nagios']; + } +} diff --git a/puppet/modules/nagios/manifests/pnp4nagios/popup.pp b/puppet/modules/nagios/manifests/pnp4nagios/popup.pp new file mode 100644 index 00000000..91136ccb --- /dev/null +++ b/puppet/modules/nagios/manifests/pnp4nagios/popup.pp @@ -0,0 +1,24 @@ +class nagios::pnp4nagios::popup inherits nagios::pnp4nagios { + File['pnp4nagios-templates.cfg']{ + source => [ + 'puppet:///modules/site-nagios/pnp4nagios/pnp4nagios-popup-templates.cfg', + 'puppet:///modules/nagios/pnp4nagios/pnp4nagios-popup-templates.cfg' ], + } + + file { '/usr/share/nagios3/htdocs/ssi': + ensure => directory, + require => Package['nagios'], + } + + file { 'status-header.ssi': + path => '/usr/share/nagios3/htdocs/ssi/status-header.ssi', + source => [ + 'puppet:///modules/site-nagios/pnp4nagios/status-header.ssi', + 'puppet:///modules/nagios/pnp4nagios/status-header.ssi'], + mode => '0644', + owner => root, + group => root, + notify => Service['nagios'], + require => Package['nagios'], + } +} diff --git a/puppet/modules/nagios/manifests/service.pp b/puppet/modules/nagios/manifests/service.pp new file mode 100644 index 00000000..e2c08e99 --- /dev/null +++ b/puppet/modules/nagios/manifests/service.pp @@ -0,0 +1,91 @@ +# a wrapper around nagios_service to make it more convenient and +# also automatically an exported resource. +define nagios::service ( + $ensure = present, + $host_name = $::fqdn, + $check_command = 'absent', + $check_period = undef, + $check_interval = undef, + $retry_check_interval = undef, + $max_check_attempts = undef, + $notification_interval = undef, + $notification_period = undef, + $notification_options = undef, + $contact_groups = undef, + $use = 'generic-service', + $service_description = 'absent', + $use_nrpe = undef, + $nrpe_args = undef, + $nrpe_timeout = 10, +) { + + # TODO: this resource should normally accept all nagios_host parameters + + $real_name = "${::hostname}_${name}" + + @@nagios_service {$real_name: + ensure => $ensure, + notify => Service['nagios']; + } + + if $ensure != 'absent' { + if $check_command == 'absent' { + fail("Must pass a check_command to ${name} if it should be present") + } + if str2bool($use_nrpe) { + include ::nagios::command::nrpe_timeout + + if $nrpe_args { + $real_check_command = "check_nrpe_timeout!${nrpe_timeout}!${check_command}!\"${nrpe_args}\"" + } else { + $real_check_command = "check_nrpe_1arg_timeout!${nrpe_timeout}!${check_command}" + } + } else { + $real_check_command = $check_command + } + + $real_service_description = $service_description ? { + 'absent' => $name, + default => $service_description + } + Nagios_service[$real_name] { + check_command => $check_command, + host_name => $host_name, + use => $use, + service_description => $real_service_description, + } + + if $check_period { + Nagios_service[$real_name] { check_period => $check_period } + } + + if $check_interval { + Nagios_service[$real_name] { check_interval => $check_interval } + } + + if $retry_check_interval { + Nagios_service[$real_name] { retry_check_interval => $retry_check_interval } + } + + if $max_check_attempts { + Nagios_service[$real_name] { max_check_attempts => $max_check_attempts } + } + + if $notification_interval { + Nagios_service[$real_name] { notification_interval => $notification_interval } + } + + if $notification_period { + Nagios_service[$real_name] { notification_period => $notification_period } + } + + if $notification_options { + Nagios_service[$real_name] { notification_options => $notification_options } + } + + if $contact_groups { + Nagios_service[$real_name] { contact_groups => $contact_groups } + } + } +} + diff --git a/puppet/modules/nagios/manifests/service/dns.pp b/puppet/modules/nagios/manifests/service/dns.pp new file mode 100644 index 00000000..5ef6e3e8 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/dns.pp @@ -0,0 +1,19 @@ +define nagios::service::dns( + $host_name = $::fqdn, + $comment = $name, + $check_domain = $name, + $ip +){ + if $name != $comment { + $check_name = "${comment}_${name}_${::hostname}" + } else { + $check_name = "${name}_${::hostname}" + } + + nagios::service{ + $check_name: + check_command => "check_dns2!${check_domain}!${ip}", + host_name => $host_name, + service_description => "check if ${::host_name} is resolving ${check_domain}"; + } +} diff --git a/puppet/modules/nagios/manifests/service/dns_host.pp b/puppet/modules/nagios/manifests/service/dns_host.pp new file mode 100644 index 00000000..d88f3735 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/dns_host.pp @@ -0,0 +1,22 @@ +# add a special host and monitor +# it's dns service +define nagios::service::dns_host( + $check_domain, + $host_alias, + $parent, + $ip +){ + @@nagios_host{$name: + address => $ip, + alias => $host_alias, + use => 'generic-host', + parents => $parent, + } + + nagios::service::dns{$name: + host_name => $name, + comment => 'public_ns', + check_domain => $check_domain, + ip => $ip, + } +} diff --git a/puppet/modules/nagios/manifests/service/gpgkey.pp b/puppet/modules/nagios/manifests/service/gpgkey.pp new file mode 100644 index 00000000..df13ca88 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/gpgkey.pp @@ -0,0 +1,49 @@ +# define a gpgkey to be watched +define nagios::service::gpgkey( + $ensure = 'present', + $warning = '14', + $key_info = undef, + $check_interval = 60, +){ + validate_slength($name,40,40) + require ::nagios::plugins::gpg + $gpg_home = $nagios::plugins::gpg::gpg_home + $gpg_cmd = "gpg --homedir ${gpg_home}" + + exec{"manage_key_${name}": + user => nagios, + group => nagios, + } + nagios::service{ + "check_gpg_${name}": + ensure => $ensure; + } + + if $ensure == 'present' { + Exec["manage_key_${name}"]{ + command => "${gpg_cmd} --keyserver hkps://hkps.pool.sks-keyservers.net --keyserver-options ca-cert-file=${gpg_home}/sks-keyservers.netCA.pem --recv-keys ${name}", + unless => "${gpg_cmd} --list-keys ${name}", + before => Nagios::Service["check_gpg_${name}"], + } + + Nagios::Service["check_gpg_${name}"]{ + check_command => "check_gpg!${warning}!${name}", + check_interval => $check_interval, + } + if $key_info { + Nagios::Service["check_gpg_${name}"]{ + service_description => "Keyfingerprint: ${name} - Info: ${key_info}", + } + } else { + Nagios::Service["check_gpg_${name}"]{ + service_description => "Keyfingerprint: ${name}", + } + } + } else { + Exec["manage_key_${name}"]{ + command => "${gpg_cmd} --batch --delete-key ${name}", + onlyif => "${gpg_cmd} --list-keys ${name}", + require => Nagios::Service["check_gpg_${name}"], + } + } +} diff --git a/puppet/modules/nagios/manifests/service/horde_login.pp b/puppet/modules/nagios/manifests/service/horde_login.pp new file mode 100644 index 00000000..6cab59e9 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/horde_login.pp @@ -0,0 +1,18 @@ +# a horde login check +define nagios::service::horde_login( + $password, + $url, + $username = $name, + $ensure = 'present', +){ + nagios::service{ + "horde_${name}": + ensure => $ensure; + } + + if $ensure != 'absent' { + Nagios::Service["horde_${name}"]{ + check_command => "check_horde_login!${url}!${username}!${password}", + } + } +} diff --git a/puppet/modules/nagios/manifests/service/http.pp b/puppet/modules/nagios/manifests/service/http.pp new file mode 100644 index 00000000..b80c140e --- /dev/null +++ b/puppet/modules/nagios/manifests/service/http.pp @@ -0,0 +1,54 @@ +# ssl_mode: +# - false: only check http +# - true: check http and https +# - force: http is permanent redirect to https +# - only: check only https +define nagios::service::http( + $ensure = present, + $check_domain = 'absent', + $port = '80', + $check_url = '/', + $check_code = '200,301,302', + $use = 'generic-service', + $ssl_mode = false +){ + $real_check_domain = $check_domain ? { + 'absent' => $name, + default => $check_domain + } + if is_hash($check_code) { + $check_code_hash = $check_code + } else { + $check_code_hash = { + http => $check_code, + https => $check_code, + } + } + case $ssl_mode { + 'force',true,'only': { + nagios::service{"https_${name}": + ensure => $ensure, + use => $use, + check_command => "check_https_url_regex!${real_check_domain}!${check_url}!'${check_code_hash[https]}'", + } + case $ssl_mode { + 'force': { + nagios::service{"http_${name}": + ensure => $ensure, + use => $use, + check_command => "check_http_url_regex!${real_check_domain}!${port}!${check_url}!'301'", + } + } + } + } + } + case $ssl_mode { + false,true: { + nagios::service{"http_${name}": + ensure => $ensure, + use => $use, + check_command => "check_http_url_regex!${real_check_domain}!${port}!${check_url}!'${check_code_hash[http]}'", + } + } + } +} diff --git a/puppet/modules/nagios/manifests/service/imap.pp b/puppet/modules/nagios/manifests/service/imap.pp new file mode 100644 index 00000000..45b667ab --- /dev/null +++ b/puppet/modules/nagios/manifests/service/imap.pp @@ -0,0 +1,34 @@ +# check an imap service +define nagios::service::imap( + $ensure = 'present', + $host = 'absent', + $port = '143', + $tls = true, + $tls_port = '993' +){ + + $real_host = $host ? { + 'absent' => $name, + default => $host + } + + $tls_ensure = $tls ? { + true => $ensure, + default => 'absent' + } + nagios::service{ + "imap_${name}_${port}": + ensure => $ensure; + "imaps_${name}_${tls_port}": + ensure => $tls_ensure; + } + + if $ensure != 'absent' { + Nagios::Service["imap_${name}_${port}"]{ + check_command => "check_imap!${real_host}!${port}", + } + Nagios::Service["imaps_${name}_${tls_port}"]{ + check_command => "check_imap_ssl!${real_host}!${tls_port}", + } + } +} diff --git a/puppet/modules/nagios/manifests/service/imap_login.pp b/puppet/modules/nagios/manifests/service/imap_login.pp new file mode 100644 index 00000000..25303a3f --- /dev/null +++ b/puppet/modules/nagios/manifests/service/imap_login.pp @@ -0,0 +1,22 @@ +# a imap login check +define nagios::service::imap_login( + $username, + $password, + $warning = 5, + $critical = 10, + $host = $::fqdn, + $host_name = $::fqdn, + $ensure = 'present', +){ + nagios::service{ + "imap_login_${name}": + ensure => $ensure; + } + + if $ensure != 'absent' { + Nagios::Service["imap_login_${name}"]{ + check_command => "check_imap_login!${host}!${username}!${password}!${warning}!${critical}", + host_name => $host_name, + } + } +} diff --git a/puppet/modules/nagios/manifests/service/mysql.pp b/puppet/modules/nagios/manifests/service/mysql.pp new file mode 100644 index 00000000..9559b17c --- /dev/null +++ b/puppet/modules/nagios/manifests/service/mysql.pp @@ -0,0 +1,58 @@ +# Checks a mysql instance via tcp or socket +define nagios::service::mysql( + $ensure = present, + $check_host = 'absent', + $check_port = '3306', + $check_username = 'nagios', + $check_password, + $check_database = 'information_schema', + $check_warning = undef, + $check_critical = undef, + $check_health_mode = $name, + $check_name = undef, + $check_name2 = undef, + $check_regexp = undef, + $check_units = undef, + $check_mode = 'tcp' ) +{ + + if ($check_host == 'absent') { + fail("Please specify a hostname, ip address or socket to check a mysql instance.") + } + + if $check_name != undef { + $real_check_name = "!--name $check_name" + } + + if $check_warning != undef { + $real_check_warning = "!--warning $check_warning" + } + + if $check_critical != undef { + $real_check_critical = "!--critical $check_critical" + } + + case $check_mode { + 'tcp': { + if ($check_host == 'localhost') { + $real_check_host = '127.0.0.1' + } + else { + $real_check_host = $check_host + } + } + default: { + if ($check_host == '127.0.0.1') { + $real_check_host = 'localhost' + } + else { + $real_check_host = $check_host + } + } + } + + nagios::service { "mysql_health_${name}": + ensure => $ensure, + check_command => "check_mysql_health!${real_check_host}!${check_port}!${check_username}!'${check_password}'!${check_health_mode}!${check_database}${real_check_name}${real_check_warning}${real_check_critical}", + } +} diff --git a/puppet/modules/nagios/manifests/service/ntp.pp b/puppet/modules/nagios/manifests/service/ntp.pp new file mode 100644 index 00000000..b3cde2ab --- /dev/null +++ b/puppet/modules/nagios/manifests/service/ntp.pp @@ -0,0 +1,9 @@ +# manifests/service/ntp.pp + +class nagios::service::ntp { + nagios::service{ "check_ntp": + check_command => "check_ntp_time", + host_name => $::fqdn, + } +} + diff --git a/puppet/modules/nagios/manifests/service/passive.pp b/puppet/modules/nagios/manifests/service/passive.pp new file mode 100644 index 00000000..f3df1e8b --- /dev/null +++ b/puppet/modules/nagios/manifests/service/passive.pp @@ -0,0 +1,18 @@ +define nagios::service::passive( + $ensure = present, + $notification_interval = '', + $notification_period = '', + $notification_options = '', + $contact_groups = '' +) { + + nagios::service { $name: + use => 'passive-service', + check_command => 'check_dummy!0', + notification_interval => $notification_interval, + notification_period => $notification_period, + notification_options => $notification_options, + contact_groups => $contact_groups, + } + +} diff --git a/puppet/modules/nagios/manifests/service/ping.pp b/puppet/modules/nagios/manifests/service/ping.pp new file mode 100644 index 00000000..f1c8d878 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/ping.pp @@ -0,0 +1,9 @@ +define nagios::service::ping( + $ensure = present, + $ping_rate = '!100.0,20%!500.0,60%' +){ + nagios::service{ "check_ping": + ensure => $ensure, + check_command => "check_ping${ping_rate}", + } +} diff --git a/puppet/modules/nagios/manifests/service/pop.pp b/puppet/modules/nagios/manifests/service/pop.pp new file mode 100644 index 00000000..9ec4aec1 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/pop.pp @@ -0,0 +1,32 @@ +define nagios::service::pop( + $ensure = 'present', + $host = 'absent', + $port = '110', + $tls = true, + $tls_port = '995' +){ + + $real_host = $host ? { + 'absent' => $name, + default => $host + } + + nagios::service{ + "pop_${name}_${port}": + ensure => $ensure; + "pops_${name}_${tls_port}": + ensure => $tls ? { + true => $ensure, + default => 'absent' + }; + } + + if $ensure != 'absent' { + Nagios::Service["pop_${name}_${port}"]{ + check_command => "check_pop3!${real_host}!${port}", + } + Nagios::Service["pops_${name}_${tls_port}"]{ + check_command => "check_pop3_ssl!${real_host}!${tls_port}", + } + } +} diff --git a/puppet/modules/nagios/manifests/service/pop3_login.pp b/puppet/modules/nagios/manifests/service/pop3_login.pp new file mode 100644 index 00000000..74535289 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/pop3_login.pp @@ -0,0 +1,22 @@ +# a pop3 login check +define nagios::service::pop3_login( + $username, + $password, + $warning = 5, + $critical = 10, + $host = $::fqdn, + $host_name = $::fqdn, + $ensure = 'present', +){ + nagios::service{ + "pop3_login_${name}": + ensure => $ensure; + } + + if $ensure != 'absent' { + Nagios::Service["pop3_login_${name}"]{ + check_command => "check_pop3_login!${host}!${username}!${password}!${warning}!${critical}", + host_name => $host_name, + } + } +} diff --git a/puppet/modules/nagios/manifests/service/smtp.pp b/puppet/modules/nagios/manifests/service/smtp.pp new file mode 100644 index 00000000..14237a9e --- /dev/null +++ b/puppet/modules/nagios/manifests/service/smtp.pp @@ -0,0 +1,50 @@ +# true: +# - true : check tls and plain connect *defualt* +# - false : check plain connection only +# cert_days: +# If tls is used add an additionl check +# to check for validity for cert. +# - 'absent' : do not execute that check +# - INTEGER : Minimum number of days a certificate +# has to be valid. Default: 10 +define nagios::service::smtp( + $ensure = 'present', + $host = 'absent', + $port = '25', + $tls = true, + $cert_days = 10 +){ + $real_host = $host ? { + 'absent' => $name, + default => $host + } + + nagios::service{ + "smtp_${name}_${port}": + ensure => $ensure; + "smtp_tls_${name}_${port}": + ensure => $tls ? { + true => $ensure, + default => 'absent' + }; + "smtp_tls_cert_${name}_${port}": + ensure => $cert_days ? { + 'absent' => 'absent', + default => $ensure + }; + } + + if $ensure != 'absent' { + Nagios::Service["smtp_${name}_${port}"]{ + check_command => "check_smtp!${real_host}!${port}", + } + Nagios::Service["smtp_tls_${name}_${port}"]{ + check_command => "check_smtp_tls!${real_host}!${port}", + } + if $cert_days != 'absent' { + Nagios::Service["smtp_tls_cert_${name}_${port}"]{ + check_command => "check_smtp_cert!${real_host}!${port}!${cert_days}", + } + } + } +} diff --git a/puppet/modules/nagios/manifests/service/ssmtp.pp b/puppet/modules/nagios/manifests/service/ssmtp.pp new file mode 100644 index 00000000..b05678a6 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/ssmtp.pp @@ -0,0 +1,32 @@ +define nagios::service::ssmtp( + $ensure = 'present', + $host = 'absent', + $port = '465', + $cert_days = 10 +){ + $real_host = $host ? { + 'absent' => $name, + default => $host + } + + nagios::service{ + "ssmtp_${name}_${port}": + ensure => $ensure; + "ssmtp_cert_${name}_${port}": + ensure => $cert_days ? { + 'absent' => 'absent', + default => $ensure + }; + } + + if $ensure != 'absent' { + Nagios::Service["ssmtp_${name}_${port}"]{ + check_command => "check_ssmtp!${real_host}!${port}", + } + if $cert_days != 'absent' { + Nagios::Service["ssmtp_cert_${name}_${port}"]{ + check_command => "check_ssmtp_cert!${real_host}!${port}!${cert_days}", + } + } + } +} diff --git a/puppet/modules/nagios/manifests/storeconfigs.pp b/puppet/modules/nagios/manifests/storeconfigs.pp new file mode 100644 index 00000000..96c30dd5 --- /dev/null +++ b/puppet/modules/nagios/manifests/storeconfigs.pp @@ -0,0 +1,61 @@ +# collect exported resources when using 'storeconfigs => true' +class nagios::storeconfigs { + + Nagios_command <<||>> + Nagios_contactgroup <<||>> + Nagios_contact <<||>> + Nagios_hostdependency <<||>> + Nagios_hostescalation <<||>> + Nagios_hostextinfo <<||>> + Nagios_hostgroup <<||>> + Nagios_host <<||>> + Nagios_servicedependency <<||>> + Nagios_serviceescalation <<||>> + Nagios_servicegroup <<||>> + Nagios_serviceextinfo <<||>> + Nagios_service <<||>> + Nagios_timeperiod <<||>> + + Nagios_command <||> { + notify => Service['nagios'], + } + Nagios_contact <||> { + notify => Service['nagios'], + } + Nagios_contactgroup <||> { + notify => Service['nagios'], + } + Nagios_host <||> { + notify => Service['nagios'], + } + Nagios_hostdependency <||> { + notify => Service['nagios'], + } + Nagios_hostescalation <||> { + notify => Service['nagios'], + } + Nagios_hostextinfo <||> { + notify => Service['nagios'], + } + Nagios_hostgroup <||> { + notify => Service['nagios'], + } + Nagios_service <||> { + notify => Service['nagios'], + } + Nagios_servicegroup <||> { + notify => Service['nagios'], + } + Nagios_servicedependency <||> { + notify => Service['nagios'], + } + Nagios_serviceescalation <||> { + notify => Service['nagios'], + } + Nagios_serviceextinfo <||> { + notify => Service['nagios'], + } + Nagios_timeperiod <||> { + notify => Service['nagios'], + } +} diff --git a/puppet/modules/nagios/manifests/stored_config.pp b/puppet/modules/nagios/manifests/stored_config.pp new file mode 100644 index 00000000..5afda04f --- /dev/null +++ b/puppet/modules/nagios/manifests/stored_config.pp @@ -0,0 +1,19 @@ +class nagios::stored_config { + # collect exported resources + + Nagios_command <<||>> + Nagios_contactgroup <<||>> + Nagios_contact <<||>> + Nagios_hostdependency <<||>> + Nagios_hostescalation <<||>> + Nagios_hostextinfo <<||>> + Nagios_hostgroup <<||>> + Nagios_host <<||>> + Nagios_servicedependency <<||>> + Nagios_serviceescalation <<||>> + Nagios_servicegroup <<||>> + Nagios_serviceextinfo <<||>> + Nagios_service <<||>> + Nagios_timeperiod <<||>> + +} diff --git a/puppet/modules/nagios/manifests/target.pp b/puppet/modules/nagios/manifests/target.pp new file mode 100644 index 00000000..760d7d47 --- /dev/null +++ b/puppet/modules/nagios/manifests/target.pp @@ -0,0 +1,32 @@ +# a simple nagios target to monitor +class nagios::target( + $parents = 'absent', + $address = $::ipaddress, + $nagios_alias = false, + $hostgroups = 'absent', + $use = 'generic-host', +){ + @@nagios_host { $::fqdn: + address => $address, + use => $use, + } + # Watch out with using aliases: they need to be unique throughout *all* + # resources in a given host's catalogue. + if $nagios_alias { + Nagios_host[$::fqdn]{ + alias => $nagios_alias + } + } + + if ($parents != 'absent') { + Nagios_host[$::fqdn]{ + parents => $parents + } + } + + if ($hostgroups != 'absent') { + Nagios_host[$::fqdn]{ + hostgroups => $hostgroups + } + } +} diff --git a/puppet/modules/nagios/manifests/target/fqdn.pp b/puppet/modules/nagios/manifests/target/fqdn.pp new file mode 100644 index 00000000..31fc4b71 --- /dev/null +++ b/puppet/modules/nagios/manifests/target/fqdn.pp @@ -0,0 +1,12 @@ +# monitor a host by fqdn +class nagios::target::fqdn( + $address = $::fqdn, + $hostgroups = 'absent', + $parents = 'absent' +) { + class{'nagios::target': + address => $address, + hostgroups => $hostgroups, + parents => $parents + } +} diff --git a/puppet/modules/nagios/templates/irc_bot/CentOS/nagios-nsa.sh.erb b/puppet/modules/nagios/templates/irc_bot/CentOS/nagios-nsa.sh.erb new file mode 100644 index 00000000..0f9f87b4 --- /dev/null +++ b/puppet/modules/nagios/templates/irc_bot/CentOS/nagios-nsa.sh.erb @@ -0,0 +1,104 @@ +#!/bin/sh +# +# nagios-nsa - manage nagios irc bot +# +# chkconfig: - 99 01 +# description: Nagios Simple IRC Agent + +### BEGIN INIT INFO +# Provides: nagios-nsa +# Required-Start: $nagios +# Required-Stop: $nagios +# Default-Start: 2 3 4 5 +# Default-Stop: 1 6 0 +# Short-Description: Nagios Simple IRC Agent +### END INIT INFO + +# Source function library. +. /etc/rc.d/init.d/functions + +exec="/usr/local/bin/riseup-nagios-server.pl" +prog="nsa" +PIDFILE=<%= scope.lookupvar('nagios::irc_bot::real_nsa_pidfile') %> +SOCKFILE=<%= scope.lookupvar('nagios::irc_bot::real_nsa_socket') %> + +[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog + +lockfile=/var/lock/subsys/$prog +mkdir -p /var/run/nagios-nsa 2>/dev/null +chown nagios /var/run/nagios-nsa + +start() { + [ -x $exec ] || exit 5 + [ -f $config ] || exit 6 + echo -n $"Starting $prog: " + daemon --pidfile $PIDFILE --user nagios /usr/local/bin/riseup-nagios-server.pl + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile + return $retval +} + +stop() { + echo -n $"Stopping $prog: " + killproc -p $PIDFILE $prog + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile + return $retval +} + +restart() { + stop + start +} + +reload() { + restart +} + +force_reload() { + restart +} + +rh_status() { + # run checks to determine if the service is running or use generic status + status -p $PIDFILE $prog +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + + +case "$1" in + start) + rh_status_q && exit 0 + $1 + ;; + stop) + rh_status_q || exit 0 + $1 + ;; + restart) + $1 + ;; + reload) + rh_status_q || exit 7 + $1 + ;; + force-reload) + force_reload + ;; + status) + rh_status + ;; + condrestart|try-restart) + rh_status_q || exit 0 + restart + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" + exit 2 +esac +exit $? diff --git a/puppet/modules/nagios/templates/irc_bot/Debian/nagios-nsa.sh.erb b/puppet/modules/nagios/templates/irc_bot/Debian/nagios-nsa.sh.erb new file mode 100644 index 00000000..43c0e794 --- /dev/null +++ b/puppet/modules/nagios/templates/irc_bot/Debian/nagios-nsa.sh.erb @@ -0,0 +1,72 @@ +#! /bin/sh + +### BEGIN INIT INFO +# Provides: nagios-nsa +# Required-Start: $remote_fs $syslog nagios3 +# Required-Stop: $remote_fs $syslog nagios3 +# Default-Start: 2 3 4 5 +# Default-Stop: 1 6 0 +# Short-Description: Nagios Simple IRC Agent +### END INIT INFO + +PIDFILE=<%= scope.lookupvar('nagios::irc_bot::real_nsa_pidfile') %> +SOCKFILE=<%= scope.lookupvar('nagios::irc_bot::real_nsa_socket') %> + +. /lib/lsb/init-functions + +start() { + log_daemon_msg "Starting nagios IRC bot" "nagios-nsa" + if start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --user nagios --chuid nagios --exec /usr/local/bin/riseup-nagios-server.pl; then + log_end_msg 0 + else + log_end_msg 1 + fi +} + +stop () { + log_daemon_msg "Stopping nagios IRC bot" "nagios-nsa" + if start-stop-daemon --stop --quiet --pidfile $PIDFILE; then + log_end_msg 0 + else + log_end_msg 1 + fi +} + +remove_socket() { + [ -e $SOCKFILE ] && rm $SOCKFILE +} + +cleanup() { + if [ -r $PIDFILE ]; then + ps -p `cat $PIDFILE` | grep -v 'PID' || { + echo "not running" + remove_socket + } + else + echo "no pid file" + remove_socket + fi +} + +case $1 +in + start) + cleanup + start + ;; + stop) + stop + ;; + restart) + stop + cleanup + start + ;; + status) + status_of_proc -p $PIDFILE /usr/local/bin/riseup-nagios-server.pl && exit 0 || exit $? + ;; + *) + log_action_msg "Usage: /etc/init.d/nagios-nsa {start|stop|restart|status}" + exit 1 +esac + diff --git a/puppet/modules/nagios/templates/irc_bot/nsa.cfg.erb b/puppet/modules/nagios/templates/irc_bot/nsa.cfg.erb new file mode 100644 index 00000000..c4091e8a --- /dev/null +++ b/puppet/modules/nagios/templates/irc_bot/nsa.cfg.erb @@ -0,0 +1,15 @@ +%Nsa = ( + 'socket' => '<%= scope.lookupvar('nagios::irc_bot::real_nsa_socket') %>', + 'server' => '<%= scope.lookupvar('nagios::irc_bot::nsa_server') %>', + 'port' => '<%= scope.lookupvar('nagios::irc_bot::nsa_port') %>', + 'nickname' => '<%= scope.lookupvar('nagios::irc_bot::nsa_nickname') %>', + 'password' => '<%= scope.lookupvar('nagios::irc_bot::nsa_password') %>', + # this needs libio-socket-ssl-perl + # doesn't actually works because Net::IRC is braindead and tries to use IO::Socket::SSL->read/write instead of the builtin print, see http://search.cpan.org/dist/IO-Socket-SSL/SSL.pm + #'SSL' => 0, + 'channel' => '<%= scope.lookupvar('nagios::irc_bot::nsa_channel') %>', + 'pidfile' => '<%= scope.lookupvar('nagios::irc_bot::real_nsa_pidfile') %>', # set to undef to disable + 'realname' => '<%= scope.lookupvar('nagios::irc_bot::nsa_realname') %>', + 'usenotices' => '<%= scope.lookupvar('nagios::irc_bot::nsa_usenotices') %>', + 'commandfile' => '<%= scope.lookupvar('nagios::irc_bot::real_nsa_commandfile') %>', +); diff --git a/puppet/modules/nagios/templates/nrpe/nrpe.cfg b/puppet/modules/nagios/templates/nrpe/nrpe.cfg new file mode 100644 index 00000000..d4ad9a4d --- /dev/null +++ b/puppet/modules/nagios/templates/nrpe/nrpe.cfg @@ -0,0 +1,203 @@ +############################################################################# +# Sample NRPE Config File +# Written by: Ethan Galstad (nagios@nagios.org) +# +# Last Modified: 02-23-2006 +# +# NOTES: +# This is a sample configuration file for the NRPE daemon. It needs to be +# located on the remote host that is running the NRPE daemon, not the host +# from which the check_nrpe client is being executed. +############################################################################# + + +# PID FILE +# The name of the file in which the NRPE daemon should write it's process ID +# number. The file is only written if the NRPE daemon is started by the root +# user and is running in standalone mode. + +pid_file=<%= @pid_file %> + + + +# PORT NUMBER +# Port number we should wait for connections on. +# NOTE: This must be a non-priviledged port (i.e. > 1024). +# NOTE: This option is ignored if NRPE is running under either inetd or xinetd + +server_port=5666 + + + +# SERVER ADDRESS +# Address that nrpe should bind to in case there are more than one interface +# and you do not want nrpe to bind on all interfaces. +# NOTE: This option is ignored if NRPE is running under either inetd or xinetd + +<%- if not @server_address.to_s.empty? then %> +server_address=<%= @server_address %> +<%- end %> + + +# NRPE USER +# This determines the effective user that the NRPE daemon should run as. +# You can either supply a username or a UID. +# +# NOTE: This option is ignored if NRPE is running under either inetd or xinetd + +nrpe_user=nagios + + + +# NRPE GROUP +# This determines the effective group that the NRPE daemon should run as. +# You can either supply a group name or a GID. +# +# NOTE: This option is ignored if NRPE is running under either inetd or xinetd + +nrpe_group=nagios + + + +# ALLOWED HOST ADDRESSES +# This is an optional comma-delimited list of IP address or hostnames +# that are allowed to talk to the NRPE daemon. +# +# Note: The daemon only does rudimentary checking of the client's IP +# address. I would highly recommend adding entries in your /etc/hosts.allow +# file to allow only the specified host to connect to the port +# you are running this daemon on. +# +# NOTE: This option is ignored if NRPE is running under either inetd or xinetd + +<%- if @allowed_hosts.to_s.empty? then %> +allowed_hosts=127.0.0.1 +<%- else %> +allowed_hosts=127.0.0.1,<%= @allowed_hosts %> +<%- end %> + +# COMMAND ARGUMENT PROCESSING +# This option determines whether or not the NRPE daemon will allow clients +# to specify arguments to commands that are executed. This option only works +# if the daemon was configured with the --enable-command-args configure script +# option. +# +# *** ENABLING THIS OPTION IS A SECURITY RISK! *** +# Read the SECURITY file for information on some of the security implications +# of enabling this variable. +# +# Values: 0=do not allow arguments, 1=allow command arguments + +dont_blame_nrpe=<%= @dont_blame %> + + +# COMMAND PREFIX +# This option allows you to prefix all commands with a user-defined string. +# A space is automatically added between the specified prefix string and the +# command line from the command definition. +# +# *** THIS EXAMPLE MAY POSE A POTENTIAL SECURITY RISK, SO USE WITH CAUTION! *** +# Usage scenario: +# Execute restricted commmands using sudo. For this to work, you need to add +# the nagios user to your /etc/sudoers. An example entry for alllowing +# execution of the plugins from might be: +# +# nagios ALL=(ALL) NOPASSWD: /usr/lib/nagios/plugins/ +# +# This lets the nagios user run all commands in that directory (and only them) +# without asking for a password. If you do this, make sure you don't give +# random users write access to that directory or its contents! + +# command_prefix=/usr/bin/sudo + + + +# DEBUGGING OPTION +# This option determines whether or not debugging messages are logged to the +# syslog facility. +# Values: 0=debugging off, 1=debugging on + +debug=0 + + + +# COMMAND TIMEOUT +# This specifies the maximum number of seconds that the NRPE daemon will +# allow plugins to finish executing before killing them off. + +command_timeout=60 + + + +# WEEK RANDOM SEED OPTION +# This directive allows you to use SSL even if your system does not have +# a /dev/random or /dev/urandom (on purpose or because the necessary patches +# were not applied). The random number generator will be seeded from a file +# which is either a file pointed to by the environment valiable $RANDFILE +# or $HOME/.rnd. If neither exists, the pseudo random number generator will +# be initialized and a warning will be issued. +# Values: 0=only seed from /dev/[u]random, 1=also seed from weak randomness + +#allow_weak_random_seed=1 + + + +# INCLUDE CONFIG FILE +# This directive allows you to include definitions from an external config file. + +#include= + + + +# INCLUDE CONFIG DIRECTORY +# This directive allows you to include definitions from config files (with a +# .cfg extension) in one or more directories (with recursion). + +#include_dir= +#include_dir= +include_dir=<%= @cfg_dir %>/nrpe.d + + + +# COMMAND DEFINITIONS +# Command definitions that this daemon will run. Definitions +# are in the following format: +# +# command[]= +# +# When the daemon receives a request to return the results of +# it will execute the command specified by the argument. +# +# Unlike Nagios, the command line cannot contain macros - it must be +# typed exactly as it should be executed. +# +# Note: Any plugins that are used in the command lines must reside +# on the machine that this daemon is running on! The examples below +# assume that you have plugins installed in a /usr/local/nagios/libexec +# directory. Also note that you will have to modify the definitions below +# to match the argument format the plugins expect. Remember, these are +# examples only! + +# The following examples use hardcoded command arguments... + +#command[check_users]=/usr/lib/nagios/plugins/check_users -w 5 -c 10 +#command[check_load]=/usr/lib/nagios/plugins/check_load -w 15,10,5 -c 30,25,20 +#command[check_disk1]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /dev/hda1 +#command[check_disk2]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /dev/hdb1 +#command[check_zombie_procs]=/usr/lib/nagios/plugins/check_procs -w 5 -c 10 -s Z +#command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 150 -c 200 + +# The following examples allow user-supplied arguments and can +# only be used if the NRPE daemon was compiled with support for +# command arguments *AND* the dont_blame_nrpe directive in this +# config file is set to '1'... + +#command[check_users]=/usr/lib/nagios/plugins/check_users -w $ARG1$ -c $ARG2$ +#command[check_load]=/usr/lib/nagios/plugins/check_load -w $ARG1$ -c $ARG2$ +#command[check_disk]=/usr/lib/nagios/plugins/check_disk -w $ARG1$ -c $ARG2$ -p $ARG3$ +#command[check_procs]=/usr/lib/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -s $ARG3$ + +# +# local configuration: +# if you'd prefer, you can instead place directives here + diff --git a/puppet/modules/nagios/templates/nrpe/nrpe_command.erb b/puppet/modules/nagios/templates/nrpe/nrpe_command.erb new file mode 100644 index 00000000..99f4601b --- /dev/null +++ b/puppet/modules/nagios/templates/nrpe/nrpe_command.erb @@ -0,0 +1,2 @@ +# generated by puppet, do not edit +command[<%= name -%>]=<%= command_line %> -- cgit v1.2.3 From 297fadc8e6ad4729589d4ec21683f05a1e50bdf9 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:46:13 -0400 Subject: git subrepo clone https://leap.se/git/puppet_tor puppet/modules/tor subrepo: subdir: "puppet/modules/tor" merged: "9981a70" upstream: origin: "https://leap.se/git/puppet_tor" branch: "master" commit: "9981a70" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I0a876a52bd83914cfd1e06abe9af208dd62e5683 --- puppet/modules/tor/.gitignore | 1 + puppet/modules/tor/.gitrepo | 11 + puppet/modules/tor/LICENSE | 661 ++++ puppet/modules/tor/README | 214 ++ puppet/modules/tor/files/munin/tor_connections | 162 + puppet/modules/tor/files/munin/tor_routers | 151 + puppet/modules/tor/files/munin/tor_traffic | 154 + puppet/modules/tor/files/polipo/polipo.conf | 164 + puppet/modules/tor/files/tor-exit-notice.html | 144 + puppet/modules/tor/files/tor.html | 3157 ++++++++++++++++++++ puppet/modules/tor/manifests/arm.pp | 9 + puppet/modules/tor/manifests/base.pp | 14 + puppet/modules/tor/manifests/compact.pp | 7 + puppet/modules/tor/manifests/daemon.pp | 22 + puppet/modules/tor/manifests/daemon/base.pp | 77 + puppet/modules/tor/manifests/daemon/bridge.pp | 18 + puppet/modules/tor/manifests/daemon/control.pp | 27 + puppet/modules/tor/manifests/daemon/directory.pp | 27 + puppet/modules/tor/manifests/daemon/dns.pp | 17 + puppet/modules/tor/manifests/daemon/exit_policy.pp | 18 + .../modules/tor/manifests/daemon/hidden_service.pp | 17 + puppet/modules/tor/manifests/daemon/map_address.pp | 17 + puppet/modules/tor/manifests/daemon/relay.pp | 42 + puppet/modules/tor/manifests/daemon/snippet.pp | 16 + puppet/modules/tor/manifests/daemon/socks.pp | 15 + puppet/modules/tor/manifests/daemon/transparent.pp | 17 + puppet/modules/tor/manifests/init.pp | 6 + puppet/modules/tor/manifests/munin.pp | 21 + puppet/modules/tor/manifests/polipo.pp | 9 + puppet/modules/tor/manifests/polipo/base.pp | 22 + puppet/modules/tor/manifests/polipo/debian.pp | 7 + puppet/modules/tor/manifests/repo.pp | 16 + puppet/modules/tor/manifests/repo/debian.pp | 9 + puppet/modules/tor/manifests/torsocks.pp | 9 + puppet/modules/tor/templates/torrc.bridge.erb | 3 + puppet/modules/tor/templates/torrc.control.erb | 16 + puppet/modules/tor/templates/torrc.directory.erb | 11 + puppet/modules/tor/templates/torrc.dns.erb | 5 + puppet/modules/tor/templates/torrc.exit_policy.erb | 11 + puppet/modules/tor/templates/torrc.global.erb | 24 + puppet/modules/tor/templates/torrc.header.erb | 2 + .../modules/tor/templates/torrc.hidden_service.erb | 6 + puppet/modules/tor/templates/torrc.map_address.erb | 3 + puppet/modules/tor/templates/torrc.relay.erb | 46 + puppet/modules/tor/templates/torrc.socks.erb | 9 + puppet/modules/tor/templates/torrc.transparent.erb | 5 + 46 files changed, 5419 insertions(+) create mode 100644 puppet/modules/tor/.gitignore create mode 100644 puppet/modules/tor/.gitrepo create mode 100644 puppet/modules/tor/LICENSE create mode 100644 puppet/modules/tor/README create mode 100755 puppet/modules/tor/files/munin/tor_connections create mode 100755 puppet/modules/tor/files/munin/tor_routers create mode 100755 puppet/modules/tor/files/munin/tor_traffic create mode 100644 puppet/modules/tor/files/polipo/polipo.conf create mode 100644 puppet/modules/tor/files/tor-exit-notice.html create mode 100644 puppet/modules/tor/files/tor.html create mode 100644 puppet/modules/tor/manifests/arm.pp create mode 100644 puppet/modules/tor/manifests/base.pp create mode 100644 puppet/modules/tor/manifests/compact.pp create mode 100644 puppet/modules/tor/manifests/daemon.pp create mode 100644 puppet/modules/tor/manifests/daemon/base.pp create mode 100644 puppet/modules/tor/manifests/daemon/bridge.pp create mode 100644 puppet/modules/tor/manifests/daemon/control.pp create mode 100644 puppet/modules/tor/manifests/daemon/directory.pp create mode 100644 puppet/modules/tor/manifests/daemon/dns.pp create mode 100644 puppet/modules/tor/manifests/daemon/exit_policy.pp create mode 100644 puppet/modules/tor/manifests/daemon/hidden_service.pp create mode 100644 puppet/modules/tor/manifests/daemon/map_address.pp create mode 100644 puppet/modules/tor/manifests/daemon/relay.pp create mode 100644 puppet/modules/tor/manifests/daemon/snippet.pp create mode 100644 puppet/modules/tor/manifests/daemon/socks.pp create mode 100644 puppet/modules/tor/manifests/daemon/transparent.pp create mode 100644 puppet/modules/tor/manifests/init.pp create mode 100644 puppet/modules/tor/manifests/munin.pp create mode 100644 puppet/modules/tor/manifests/polipo.pp create mode 100644 puppet/modules/tor/manifests/polipo/base.pp create mode 100644 puppet/modules/tor/manifests/polipo/debian.pp create mode 100644 puppet/modules/tor/manifests/repo.pp create mode 100644 puppet/modules/tor/manifests/repo/debian.pp create mode 100644 puppet/modules/tor/manifests/torsocks.pp create mode 100644 puppet/modules/tor/templates/torrc.bridge.erb create mode 100644 puppet/modules/tor/templates/torrc.control.erb create mode 100644 puppet/modules/tor/templates/torrc.directory.erb create mode 100644 puppet/modules/tor/templates/torrc.dns.erb create mode 100644 puppet/modules/tor/templates/torrc.exit_policy.erb create mode 100644 puppet/modules/tor/templates/torrc.global.erb create mode 100644 puppet/modules/tor/templates/torrc.header.erb create mode 100644 puppet/modules/tor/templates/torrc.hidden_service.erb create mode 100644 puppet/modules/tor/templates/torrc.map_address.erb create mode 100644 puppet/modules/tor/templates/torrc.relay.erb create mode 100644 puppet/modules/tor/templates/torrc.socks.erb create mode 100644 puppet/modules/tor/templates/torrc.transparent.erb (limited to 'puppet/modules') diff --git a/puppet/modules/tor/.gitignore b/puppet/modules/tor/.gitignore new file mode 100644 index 00000000..1377554e --- /dev/null +++ b/puppet/modules/tor/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/puppet/modules/tor/.gitrepo b/puppet/modules/tor/.gitrepo new file mode 100644 index 00000000..dfc1b3d9 --- /dev/null +++ b/puppet/modules/tor/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_tor + branch = master + commit = 9981a70f7ba1f9e4fe33e4eb46654295287c1fc1 + parent = 26aac7ccf240b06d65616bdd00ae472d980aaea9 + cmdver = 0.3.0 diff --git a/puppet/modules/tor/LICENSE b/puppet/modules/tor/LICENSE new file mode 100644 index 00000000..dba13ed2 --- /dev/null +++ b/puppet/modules/tor/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/puppet/modules/tor/README b/puppet/modules/tor/README new file mode 100644 index 00000000..7777438a --- /dev/null +++ b/puppet/modules/tor/README @@ -0,0 +1,214 @@ +puppet module for managing tor +============================== + +This module tries to manage tor, making sure it is installed, running, has munin +graphs if desired and allows for configuration of relays, hidden services, exit +policies, etc. + +! Upgrade Notice ! + + previously, if you did not set the $outbound_bindaddress variable, it was being + automatically set to the $listen_address variable. Now this is not being done + and instead you will need to set the $outbound_bindaddress explicitly for it to + be set. + + the tor::relay{} variables $bandwidth_rate and $bandwidth_burst were previously + used for the tor configuration variables RelayBandwidthRate and + RelayBandwidthBurst, these have been renamed to $relay_bandwidth_rate and + $relay_bandwidth_burst. If you were using these, please rename your variables in + your configuration. + + The variables $bandwidth_rate and $bandwidth_burst are now used for the tor + configuration variables BandwidthRate and BandwidthBurst. If you used + $bandwidth_rate or $bandwidth_burst please be aware that these values have + changed and adjust your configuration as necessary. + + The $tor_ensure_version was converted to a parameter for the tor and + tor::daemon classes. + + The $torsocks_ensure_version was converted to a parameter for the + tor::torsocks class. + + The options that used to be settable with the + tor::daemon::global_opts define now are parameters for the + tor::daemon class, and tor::daemon::global_opts was + removed accordingly. + + +Dependencies +============ + +This module needs: + +- the concat module: git://labs.riseup.net/shared-concat + +Usage +===== + +Installing tor +-------------- + +To install tor, simply include the 'tor' class in your manifests: + + class { 'tor': } + +You can specify the $ensure_version class parameter to get a specific +version installed. + +However, if you want to make configuration changes to your tor daemon, you will +want to instead include the 'tor::daemon' class in your manifests, which will +inherit the 'tor' class from above: + + class { '::tor::daemon': } + +You have the following class parameters that you can specify: + +data_dir (default: '/var/lib/tor') +config_file (default: '/etc/tor/torrc') +use_bridges (default: 0) +automap_hosts_on_resolve (default: 0) +log_rules (default: ['notice file /var/log/tor/notices.log']) + +The data_dir will be used for the tor user's $HOME, and the tor DataDirectory +value. + +The config_file will be managed and the daemon restarted when +it changed. + +use_bridges and automap_hosts_on_resolve are used to set the +UseBridges and AutomapHostsOnResolve torrc settings. + +The log_rules can be an array of different Log lines, each will be added to the +config, for example the following will use syslog: + + class { '::tor::daemon': + log_rules => [ 'notice syslog' ], + } + +If you want to set specific options for the tor class, +you may pass them directly to the tor::daemon in your manifests, +e.g.: + + class { '::tor::daemon': + use_munin => true, + automap_hosts_on_resolve => 1, + } + +Configuring socks +----------------- + +To configure tor socks support, you can do the following: + + tor::daemon::socks { "listen_locally": listen_addresses => [ '127.0.0.1' ]; } + +this will setup the SocksListenAddress to be 127.0.0.1. You also can pass the +following options to tor::daemon::socks: + +$port = 0 - SocksPort +$listen_address - can pass multiple values to configure SocksListenAddress lines +$policies - can pass multiple values to configure SocksPolicy lines + +Installing torsocks +------------------- + +To install torsocks, simply include the 'torsocks' class in your manifests: + + class { 'torsocks': } + +You can specify the $ensure_version class parameter to get a specific +version installed. + +Configuring relays +================== + +An example relay configuration: + + tor::daemon::relay { "foobar": + port => 9001, listen_addresses => '192.168.0.1', address => '192.168.0.1', + bandwidth_rate => '256', bandwidth_burst => '256', contact_info => "Foo ", + my_family => '' + } + +You have the following options that can be passed to a relay, with the defaults shown: + +$port = 0, +$listen_addresses = [], +$portforwarding = 0, # PortForwarding 0|1, set for opening ports at the router via UPnP. + # Requires 'tor-fw-helper' binary present. +$bandwidth_rate = '', # KB/s, defaulting to using tor's default: 5120KB/s +$bandwidth_burst = '', # KB/s, defaulting to using tor's default: 10240KB/s +$relay_bandwidth_rate = 0, # KB/s, 0 for no limit. +$relay_bandwidth_burst = 0, # KB/s, 0 for no limit. +$accounting_max = 0, # GB, 0 for no limit. +$accounting_start = [], +$contact_info = '', +$my_family = '', # TODO: autofill with other relays +$address = "tor.${domain}", +$bridge_relay = 0, +$ensure = present +$nickname = $name + +Configuring the control +----------------------- + +To pass parameters to configure the ControlPort and the HashedControlPassword, +you would do something like this: + + tor::daemon::control { "foo-control": + port => '80', hashed_control_password => '', + ensure => present +} + +Note: you must pass a hashed password to the control port, if you are going to +use it. + + +Configuring hidden services +--------------------------- + +To configure a tor hidden service you can do something like the following: + + tor::daemon::hidden_service { "hidden_ssh": ports => 22 } + +The HiddenServiceDir is set to the ${data_dir}/${name}. + +Configuring directories +----------------------- + +An example directory configuration: + + tor::daemon::directory { 'ssh_directory': + port => 80, listen_address => '192.168.0.1', + port_front_page => '/etc/tor/tor.html' + } + +Configuring exit policies +-------------------------- + +To configure exit policies, you can do the following: + +tor::daemon::exit_policy { "ssh_exit_policy": + accept => "192.168.0.1:22", + reject => "*:*"; + } + } + + +Polipo +====== + +Polipo support can be enabled by doing: + + include tor::polipo + +this will inherit the tor class by default, remove privoxy if its installed, and +install polipo, making sure it is running. + + +Munin +===== + +If you are using munin, and have the puppet munin module installed, you can set +the use_munin parameter to true when defining the tor::daemon class to have +graphs setup for you. + diff --git a/puppet/modules/tor/files/munin/tor_connections b/puppet/modules/tor/files/munin/tor_connections new file mode 100755 index 00000000..c1d0a928 --- /dev/null +++ b/puppet/modules/tor/files/munin/tor_connections @@ -0,0 +1,162 @@ +#!/usr/bin/perl -w +# +# Munin plugin to monitor Tor +# +# Author: Ge van Geldorp +# +# Parameters understood: +# +# host - Change which host to graph (default localhost) +# port - Change which port to connect to (default 9051) +# password - Plain-text control channel password (see torrc +# HashedControlPassword parameter) +# cookiefile - Name of the file containing the control channel cookie +# (see torrc CookieAuthentication parameter) +# +# Using HashedControlPassword authentication has the problem that you must +# include the plain-text password in the munin config file. To have any +# effect, that file shouldn't be world-readable. +# If you're using CookieAuthentication, you should run this plugin as a user +# which has read access to the tor datafiles. Also note that bugs in versions +# upto and including 0.1.1.20 prevent CookieAuthentication from working. +# +# Usage: place in /etc/munin/node.d/ (or link it there using ln -s) +# +# Parameters understood: +# config (required) +# autoconf (optional - used by munin-config) +# +# +# Magic markers - optional - used by installation scripts and +# munin-config: +# +#%# family=contrib +#%# capabilities=autoconf + +use strict; +use IO::Socket::INET; + +# Config +our $address = $ENV{host} || "localhost"; # Default: localhost +our $port = $ENV{port} || 9051; # Default: 9051 + +# Don't edit below this line + +sub Authenticate +{ + my ($socket) = @_; + my $authline = "AUTHENTICATE"; + if (defined($ENV{cookiefile})) { + if (open(COOKIE, "<$ENV{cookiefile}")) { + binmode COOKIE; + my $cookie; + $authline .= " "; + while (read(COOKIE, $cookie, 32)) { + foreach my $byte (unpack "C*", $cookie) { + $authline .= sprintf "%02x", $byte; + } + } + close COOKIE; + } + } elsif (defined($ENV{password})) { + $authline .= ' "' . $ENV{password} . '"'; + } + print $socket "$authline\r\n"; + my $replyline = <$socket>; + if (substr($replyline, 0, 1) != '2') { + $replyline =~ s/\s*$//; + return "Failed to authenticate: $replyline"; + } + + return; +} + +if ($ARGV[0] and $ARGV[0] eq "autoconf") { + # Try to connect to the daemon + my $socket = IO::Socket::INET->new("$address:$port") + or my $failed = 1; + + if ($failed) { + print "no (failed to connect to $address port $port)\n"; + exit 1; + } + + my $msg = Authenticate($socket); + if (defined($msg)) { + print $socket "QUIT\r\n"; + close($socket); + print "no ($msg)\n"; + exit 1; + } + + print $socket "QUIT\r\n"; + close($socket); + print "yes\n"; + exit 0; +} + +my %connections = ("new", 0, + "launched", 0, + "connected", 0, + "failed", 0, + "closed", 0); + +if ($ARGV[0] and $ARGV[0] eq "config") { + print "graph_title Connections\n"; + print "graph_args -l 0 --base 1000\n"; + print "graph_vlabel connections\n"; + print "graph_category Tor\n"; + print "graph_period second\n"; + print "graph_info This graph shows the number of Tor OR connections.\n"; + + foreach my $status (keys %connections) { + print "$status.label $status\n"; + print "$status.type GAUGE\n"; + print "$status.max 50000\n"; + print "$status.min 0\n"; + } + + exit 0; +} + +my $socket = IO::Socket::INET->new("$address:$port") + or die("Couldn't connect to $address port $port: $!"); + +my $msg = Authenticate($socket); +if (defined($msg)) { + print $socket "QUIT\r\n"; + close($socket); + die "$msg\n"; +} + +print $socket "GETINFO orconn-status\r\n"; +my $replyline = <$socket>; +if (substr($replyline, 0, 1) != '2') { + print $socket "QUIT\r\n"; + close($socket); + $replyline =~ s/\s*$//; + die "Failed to get orconn-status info: $replyline\n"; +} + +while (! (($replyline = <$socket>) =~ /^\.\s*$/)) { + my @reply = split(/\s+/, $replyline); + $connections{lc($reply[1])}++; +} +$replyline = <$socket>; +if (substr($replyline, 0, 1) != '2') { + print $socket "QUIT\r\n"; + close($socket); + $replyline =~ s/\s*$//; + die "Failed to authenticate: $replyline\n"; +} + +print $socket "QUIT\r\n"; +close($socket); + +while (my ($status, $count) = each(%connections)) { + print "$status.value $count\n"; +} + +exit 0; + +# vim:syntax=perl diff --git a/puppet/modules/tor/files/munin/tor_routers b/puppet/modules/tor/files/munin/tor_routers new file mode 100755 index 00000000..b977f9aa --- /dev/null +++ b/puppet/modules/tor/files/munin/tor_routers @@ -0,0 +1,151 @@ +#!/usr/bin/perl -w +# +# Munin plugin to monitor Tor routers +# +# Author: Ævar Arnfjörð Bjarmason , based on a plugin by Ge van Geldorp +# +# Parameters understood: +# +# host - Change which host to graph (default localhost) +# port - Change which port to connect to (default 9051) +# password - Plain-text control channel password (see torrc +# HashedControlPassword parameter) +# cookiefile - Name of the file containing the control channel cookie +# (see torrc CookieAuthentication parameter) +# +# Using HashedControlPassword authentication has the problem that you must +# include the plain-text password in the munin config file. To have any +# effect, that file shouldn't be world-readable. +# If you're using CookieAuthentication, you should run this plugin as a user +# which has read access to the tor datafiles. Also note that bugs in versions +# upto and including 0.1.1.20 prevent CookieAuthentication from working. +# +# Usage: place in /etc/munin/node.d/ (or link it there using ln -s) +# +# Parameters understood: +# config (required) +# autoconf (optional - used by munin-config) +# +# +# Magic markers - optional - used by installation scripts and +# munin-config: +# +#%# family=contrib +#%# capabilities=autoconf + +use strict; +use IO::Socket::INET; + +# Config +our $address = $ENV{host} || "localhost"; # Default: localhost +our $port = $ENV{port} || 9051; # Default: 9051 + +# Don't edit below this line + +sub Authenticate +{ + my ($socket) = @_; + my $authline = "AUTHENTICATE"; + if (defined($ENV{cookiefile})) { + if (open(COOKIE, "<$ENV{cookiefile}")) { + binmode COOKIE; + my $cookie; + $authline .= " "; + while (read(COOKIE, $cookie, 32)) { + foreach my $byte (unpack "C*", $cookie) { + $authline .= sprintf "%02x", $byte; + } + } + close COOKIE; + } + } elsif (defined($ENV{password})) { + $authline .= ' "' . $ENV{password} . '"'; + } + print $socket "$authline\r\n"; + my $replyline = <$socket>; + if (substr($replyline, 0, 1) != '2') { + $replyline =~ s/\s*$//; + return "Failed to authenticate: $replyline"; + } + + return; +} + +if ($ARGV[0] and $ARGV[0] eq "autoconf") { + # Try to connect to the daemon + my $socket = IO::Socket::INET->new("$address:$port") + or my $failed = 1; + + if ($failed) { + print "no (failed to connect to $address port $port)\n"; + exit 1; + } + + my $msg = Authenticate($socket); + if (defined($msg)) { + print $socket "QUIT\r\n"; + close($socket); + print "no ($msg)\n"; + exit 1; + } + + print $socket "QUIT\r\n"; + close($socket); + print "yes\n"; + exit 0; +} + +if ($ARGV[0] and $ARGV[0] eq "config") { + print "graph_title Routers\n"; + print "graph_args -l 0\n"; + print "graph_vlabel routers\n"; + print "graph_category Tor\n"; + print "graph_info This graph shows the number of known Tor ORs.\n"; + + print "ors.label routers\n"; + print "ors.type GAUGE\n"; + print "ors.info The number of known Tor ORs (onion routers)\n"; + + exit 0; +} + +my $socket = IO::Socket::INET->new("$address:$port") + or die("Couldn't connect to $address port $port: $!"); + +my $msg = Authenticate($socket); +if (defined($msg)) { + print $socket "QUIT\r\n"; + close($socket); + die "$msg\n"; +} + +print $socket "GETINFO ns/all\r\n"; +my $replyline = <$socket>; +if (substr($replyline, 0, 1) != '2') { + print $socket "QUIT\r\n"; + close($socket); + $replyline =~ s/\s*$//; + die "Failed to get orconn-status info: $replyline\n"; +} + +my $count; +while (! (($replyline = <$socket>) =~ /^\.\s*$/)) { + my @reply = split(/\s+/, $replyline); + $count++ if $reply[0] eq 'r'; +} +$replyline = <$socket>; +if (substr($replyline, 0, 1) != '2') { + print $socket "QUIT\r\n"; + close($socket); + $replyline =~ s/\s*$//; + die "Failed to authenticate: $replyline\n"; +} + +print $socket "QUIT\r\n"; +close($socket); + +print "ors.value $count\n"; + +exit 0; + +# vim:syntax=perl diff --git a/puppet/modules/tor/files/munin/tor_traffic b/puppet/modules/tor/files/munin/tor_traffic new file mode 100755 index 00000000..a72e7d7f --- /dev/null +++ b/puppet/modules/tor/files/munin/tor_traffic @@ -0,0 +1,154 @@ +#!/usr/bin/perl -w +# +# Munin plugin to monitor Tor traffic +# +# Author: Ge van Geldorp +# +# Parameters understood: +# +# host - Change which host to graph (default localhost) +# port - Change which port to connect to (default 9051) +# password - Plain-text control channel password (see torrc +# HashedControlPassword parameter) +# cookiefile - Name of the file containing the control channel cookie +# (see torrc CookieAuthentication parameter) +# +# Using HashedControlPassword authentication has the problem that you must +# include the plain-text password in the munin config file. To have any +# effect, that file shouldn't be world-readable. +# If you're using CookieAuthentication, you should run this plugin as a user +# which has read access to the tor datafiles. Also note that bugs in versions +# upto and including 0.1.1.20 prevent CookieAuthentication from working. +# +# Usage: place in /etc/munin/node.d/ (or link it there using ln -s) +# +# Parameters understood: +# config (required) +# autoconf (optional - used by munin-config) +# +# +# Magic markers - optional - used by installation scripts and +# munin-config: +# +#%# family=contrib +#%# capabilities=autoconf + +use strict; +use IO::Socket::INET; + +# Config +our $address = $ENV{host} || "localhost"; # Default: localhost +our $port = $ENV{port} || 9051; # Default: 9051 + +# Don't edit below this line + +sub Authenticate +{ + my ($socket) = @_; + my $authline = "AUTHENTICATE"; + if (defined($ENV{cookiefile})) { + if (open(COOKIE, "<$ENV{cookiefile}")) { + binmode COOKIE; + my $cookie; + $authline .= " "; + while (read(COOKIE, $cookie, 32)) { + foreach my $byte (unpack "C*", $cookie) { + $authline .= sprintf "%02x", $byte; + } + } + close COOKIE; + } + } elsif (defined($ENV{password})) { + $authline .= ' "' . $ENV{password} . '"'; + } + print $socket "$authline\r\n"; + my $replyline = <$socket>; + if (substr($replyline, 0, 1) != '2') { + $replyline =~ s/\s*$//; + return "Failed to authenticate: $replyline"; + } + + return; +} + +if ($ARGV[0] and $ARGV[0] eq "autoconf") { + # Try to connect to the daemon + my $socket = IO::Socket::INET->new("$address:$port") + or my $failed = 1; + + if ($failed) { + print "no (failed to connect to $address port $port)\n"; + exit 1; + } + + my $msg = Authenticate($socket); + if (defined($msg)) { + print $socket "QUIT\r\n"; + close($socket); + print "no ($msg)\n"; + exit 1; + } + + print $socket "QUIT\r\n"; + close($socket); + print "yes\n"; + exit 0; +} + +if ($ARGV[0] and $ARGV[0] eq "config") { + print "graph_title Traffic\n"; + print "graph_vlabel bytes per \${graph_period} read (-) / written (+)\n"; + print "graph_category Tor\n"; + print "graph_info This graph shows the bandwidth used by Tor.\n"; + + print "read.label byte/s\n"; + print "read.type GAUGE\n"; + print "read.graph no\n"; + print "read.max 10000000\n"; + print "write.label byte/s\n"; + print "write.type GAUGE\n"; + print "write.negative read\n"; + print "write.max 10000000\n"; + + exit 0; +} + +my $socket = IO::Socket::INET->new("$address:$port") + or die("Couldn't connect to $address port $port: $!"); + +my $msg = Authenticate($socket); +if (defined($msg)) { + print $socket "QUIT\r\n"; + close($socket); + die "$msg\n"; +} + +print $socket "SETEVENTS bw\r\n"; +my $replyline = <$socket>; +if (substr($replyline, 0, 1) != '2') { + print $socket "QUIT\r\n"; + close($socket); + $replyline =~ s/\s*$//; + die "Failed to get orconn-status info: $replyline\n"; +} + +$replyline = <$socket>; +if (substr($replyline, 0, 1) != '6') { + print $socket "QUIT\r\n"; + close($socket); + $replyline =~ s/\s*$//; + die "Failed to get bw: $replyline\n"; +} +my @reply = split(/\s+/, $replyline); + +print $socket "SETEVENTS\r\n"; +$replyline = <$socket>; +print $socket "QUIT\r\n"; +close($socket); + +print "read.value $reply[2]\n"; +print "write.value $reply[3]\n"; + +exit 0; + +# vim:syntax=perl diff --git a/puppet/modules/tor/files/polipo/polipo.conf b/puppet/modules/tor/files/polipo/polipo.conf new file mode 100644 index 00000000..12b10c41 --- /dev/null +++ b/puppet/modules/tor/files/polipo/polipo.conf @@ -0,0 +1,164 @@ +# Polipo Configuration from https://svn.torproject.org/svn/torbrowser/trunk/build-scripts/config/polipo.conf +# Managed by puppet. + +### Basic configuration +### ******************* + +# Uncomment one of these if you want to allow remote clients to +# connect: + +# proxyAddress = "::0" # both IPv4 and IPv6 +# proxyAddress = "0.0.0.0" # IPv4 only + +proxyAddress = "127.0.0.1" +proxyPort = 8118 + +# If you do that, you'll want to restrict the set of hosts allowed to +# connect: + +# allowedClients = "127.0.0.1, 134.157.168.57" +# allowedClients = "127.0.0.1, 134.157.168.0/24" + +allowedClients = 127.0.0.1 +allowedPorts = 1-65535 + +# Uncomment this if you want your Polipo to identify itself by +# something else than the host name: + +proxyName = "localhost" + +# Uncomment this if there's only one user using this instance of Polipo: + +cacheIsShared = false + +# Uncomment this if you want to use a parent proxy: + +# parentProxy = "squid.example.org:3128" + +# Uncomment this if you want to use a parent SOCKS proxy: + +socksParentProxy = "localhost:9050" +socksProxyType = socks5 + + +### Memory +### ****** + +# Uncomment this if you want Polipo to use a ridiculously small amount +# of memory (a hundred C-64 worth or so): + +# chunkHighMark = 819200 +# objectHighMark = 128 + +# Uncomment this if you've got plenty of memory: + +# chunkHighMark = 50331648 +# objectHighMark = 16384 + +chunkHighMark = 67108864 + +### On-disk data +### ************ + +# Uncomment this if you want to disable the on-disk cache: + +diskCacheRoot = "" + +# Uncomment this if you want to put the on-disk cache in a +# non-standard location: + +# diskCacheRoot = "~/.polipo-cache/" + +# Uncomment this if you want to disable the local web server: + +localDocumentRoot = "" + +# Uncomment this if you want to enable the pages under /polipo/index? +# and /polipo/servers?. This is a serious privacy leak if your proxy +# is shared. + +# disableIndexing = false +# disableServersList = false + +disableLocalInterface = true +disableConfiguration = true + +### Domain Name System +### ****************** + +# Uncomment this if you want to contact IPv4 hosts only (and make DNS +# queries somewhat faster): +# +# dnsQueryIPv6 = no + +# Uncomment this if you want Polipo to prefer IPv4 to IPv6 for +# double-stack hosts: +# +# dnsQueryIPv6 = reluctantly + +# Uncomment this to disable Polipo's DNS resolver and use the system's +# default resolver instead. If you do that, Polipo will freeze during +# every DNS query: + +dnsUseGethostbyname = yes + + +### HTTP +### **** + +# Uncomment this if you want to enable detection of proxy loops. +# This will cause your hostname (or whatever you put into proxyName +# above) to be included in every request: + +disableVia = true + +# Uncomment this if you want to slightly reduce the amount of +# information that you leak about yourself: + +# censoredHeaders = from, accept-language +# censorReferer = maybe + +censoredHeaders = from,accept-language,x-pad,link +censorReferer = maybe + +# Uncomment this if you're paranoid. This will break a lot of sites, +# though: + +# censoredHeaders = set-cookie, cookie, cookie2, from, accept-language +# censorReferer = true + +# Uncomment this if you want to use Poor Man's Multiplexing; increase +# the sizes if you're on a fast line. They should each amount to a few +# seconds' worth of transfer; if pmmSize is small, you'll want +# pmmFirstSize to be larger. + +# Note that PMM is somewhat unreliable. + +# pmmFirstSize = 16384 +# pmmSize = 8192 + +# Uncomment this if your user-agent does something reasonable with +# Warning headers (most don't): + +# relaxTransparency = maybe + +# Uncomment this if you never want to revalidate instances for which +# data is available (this is not a good idea): + +# relaxTransparency = yes + +# Uncomment this if you have no network: + +# proxyOffline = yes + +# Uncomment this if you want to avoid revalidating instances with a +# Vary header (this is not a good idea): + +# mindlesslyCacheVary = true + +# Suggestions from Incognito configuration +maxConnectionAge = 5m +maxConnectionRequests = 120 +serverMaxSlots = 8 +serverSlots = 2 +tunnelAllowedPorts = 1-65535 diff --git a/puppet/modules/tor/files/tor-exit-notice.html b/puppet/modules/tor/files/tor-exit-notice.html new file mode 100644 index 00000000..de3be174 --- /dev/null +++ b/puppet/modules/tor/files/tor-exit-notice.html @@ -0,0 +1,144 @@ + + + + + +This is a Tor Exit Router + + + + + + +

This is a +Tor Exit Router

+ +

+Most likely you are accessing this website because you had some issue with +the traffic coming from this IP. This router is part of the Tor Anonymity Network, which is +dedicated to providing +privacy to people who need it most: average computer users. This +router IP should be generating no other traffic, unless it has been +compromised.

+ + + + +

+ +How Tor works +

+ +

+Tor sees use by many +important segments of the population, including whistle blowers, +journalists, Chinese dissidents skirting the Great Firewall and oppressive +censorship, abuse victims, stalker targets, the US military, and law +enforcement, just to name a few. While Tor is not designed for malicious +computer users, it is true that they can use the network for malicious ends. +In reality however, the actual amount of abuse is quite low. This +is largely because criminals and hackers have significantly better access to +privacy and anonymity than do the regular users whom they prey upon. Criminals +can and do build, +sell, and trade far larger and more +powerful networks than Tor on a daily basis. Thus, in the mind of this +operator, the social need for easily accessible censorship-resistant private, +anonymous communication trumps the risk of unskilled bad actors, who are +almost always more easily uncovered by traditional police work than by +extensive monitoring and surveillance anyway.

+ +

+In terms of applicable law, the best way to understand Tor is to consider it a +network of routers operating as common carriers, much like the Internet +backbone. However, unlike the Internet backbone routers, Tor routers +explicitly do not contain identifiable routing information about the source of +a packet, and no single Tor node can determine both the origin and destination +of a given transmission.

+ +

+As such, there is little the operator of this router can do to help you track +the connection further. This router maintains no logs of any of the Tor +traffic, so there is little that can be done to trace either legitimate or +illegitimate traffic (or to filter one from the other). Attempts to +seize this router will accomplish nothing.

+ + + +

+Furthermore, this machine also serves as a carrier of email, which means that +its contents are further protected under the ECPA. 18 +USC 2707 explicitly allows for civil remedies ($1000/account +plus legal fees) +in the event of a seizure executed without good faith or probable cause (it +should be clear at this point that traffic with an originating IP address of +FIXME_DNS_NAME should not constitute probable cause to seize the +machine). Similar considerations exist for 1st amendment content on this +machine.

+ + + +

+If you are a representative of a company who feels that this router is being +used to violate the DMCA, please be aware that this machine does not host or +contain any illegal content. Also be aware that network infrastructure +maintainers are not liable for the type of content that passes over their +equipment, in accordance with DMCA +"safe harbor" provisions. In other words, you will have just as much luck +sending a takedown notice to the Internet backbone providers. Please consult +EFF's prepared +response for more information on this matter.

+ +

For more information, please consult the following documentation:

+ +
    +
  1. Tor Overview
  2. +
  3. Tor Abuse FAQ
  4. +
  5. Tor Legal FAQ
  6. +
+ +

+That being said, if you still have a complaint about the router, you may +email the maintainer. If +complaints are related to a particular service that is being abused, I will +consider removing that service from my exit policy, which would prevent my +router from allowing that traffic to exit through it. I can only do this on an +IP+destination port basis, however. Common P2P ports are +already blocked.

+ +

+You also have the option of blocking this IP address and others on +the Tor network if you so desire. The Tor project provides a web service +to fetch a list of all IP addresses of Tor exit nodes that allow exiting to a +specified IP:port combination, and an official DNSRBL is also available to +determine if a given IP address is actually a Tor exit server. Please +be considerate +when using these options. It would be unfortunate to deny all Tor users access +to your site indefinitely simply because of a few bad apples.

+ + + diff --git a/puppet/modules/tor/files/tor.html b/puppet/modules/tor/files/tor.html new file mode 100644 index 00000000..484545b8 --- /dev/null +++ b/puppet/modules/tor/files/tor.html @@ -0,0 +1,3157 @@ + + + + + +TOR(1) + + + + +

SYNOPSIS

+
+

tor [OPTION value]…

+
+

DESCRIPTION

+
+

tor is a connection-oriented anonymizing communication +service. Users choose a source-routed path through a set of nodes, and +negotiate a "virtual circuit" through the network, in which each node +knows its predecessor and successor, but no others. Traffic flowing down +the circuit is unwrapped by a symmetric key at each node, which reveals +the downstream node.

+

Basically tor provides a distributed network of servers ("onion routers"). +Users bounce their TCP streams — web traffic, ftp, ssh, etc — around the +routers, and recipients, observers, and even the routers themselves have +difficulty tracking the source of the stream.

+
+

OPTIONS

+
+
+
+-h, -help +
+
+

+ Display a short help message and exit. +

+
+
+-f FILE +
+
+

+ FILE contains further "option value" pairs. (Default: /etc/tor/torrc) +

+
+
+--hash-password +
+
+

+ Generates a hashed password for control port access. +

+
+
+--list-fingerprint +
+
+

+ Generate your keys and output your nickname and fingerprint. +

+
+
+--verify-config +
+
+

+ Verify the configuration file is valid. +

+
+
+--nt-service +
+
+

+ --service [install|remove|start|stop] Manage the Tor Windows + NT/2000/XP service. Current instructions can be found at + https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#WinNTService +

+
+
+--list-torrc-options +
+
+

+ List all valid options. +

+
+
+--version +
+
+

+ Display Tor version and exit. +

+
+
+--quiet +
+
+

+ Do not start Tor with a console log unless explicitly requested to do so. + (By default, Tor starts out logging messages at level "notice" or higher to + the console, until it has parsed its configuration.) +

+
+
+

Other options can be specified either on the command-line (--option + value), or in the configuration file (option value or option "value"). + Options are case-insensitive. C-style escaped characters are allowed inside + quoted values. Options on the command line take precedence over + options found in the configuration file, except indicated otherwise. To + split one configuration entry into multiple lines, use a single \ before + the end of the line. Comments can be used in such multiline entries, but + they must start at the beginning of a line.

+
+
+BandwidthRate N bytes|KB|MB|GB +
+
+

+ A token bucket limits the average incoming bandwidth usage on this node to + the specified number of bytes per second, and the average outgoing + bandwidth usage to that same value. If you want to run a relay in the + public network, this needs to be at the very least 20 KB (that is, + 20480 bytes). (Default: 5 MB) +

+
+
+BandwidthBurst N bytes|KB|MB|GB +
+
+

+ Limit the maximum token bucket size (also known as the burst) to the given + number of bytes in each direction. (Default: 10 MB) +

+
+
+MaxAdvertisedBandwidth N bytes|KB|MB|GB +
+
+

+ If set, we will not advertise more than this amount of bandwidth for our + BandwidthRate. Server operators who want to reduce the number of clients + who ask to build circuits through them (since this is proportional to + advertised bandwidth rate) can thus reduce the CPU demands on their server + without impacting network performance. +

+
+
+RelayBandwidthRate N bytes|KB|MB|GB +
+
+

+ If not 0, a separate token bucket limits the average incoming bandwidth + usage for _relayed traffic_ on this node to the specified number of bytes + per second, and the average outgoing bandwidth usage to that same value. + Relayed traffic currently is calculated to include answers to directory + requests, but that may change in future versions. (Default: 0) +

+
+
+RelayBandwidthBurst N bytes|KB|MB|GB +
+
+

+ If not 0, limit the maximum token bucket size (also known as the burst) for + _relayed traffic_ to the given number of bytes in each direction. + (Default: 0) +

+
+
+PerConnBWRate N bytes|KB|MB|GB +
+
+

+ If set, do separate rate limiting for each connection from a non-relay. + You should never need to change this value, since a network-wide value is + published in the consensus and your relay will use that value. (Default: 0) +

+
+
+PerConnBWBurst N bytes|KB|MB|GB +
+
+

+ If set, do separate rate limiting for each connection from a non-relay. + You should never need to change this value, since a network-wide value is + published in the consensus and your relay will use that value. (Default: 0) +

+
+
+ConnLimit NUM +
+
+

+ The minimum number of file descriptors that must be available to the Tor + process before it will start. Tor will ask the OS for as many file + descriptors as the OS will allow (you can find this by "ulimit -H -n"). + If this number is less than ConnLimit, then Tor will refuse to start.
+
+ You probably don’t need to adjust this. It has no effect on Windows + since that platform lacks getrlimit(). (Default: 1000) +

+
+
+ConstrainedSockets 0|1 +
+
+

+ If set, Tor will tell the kernel to attempt to shrink the buffers for all + sockets to the size specified in ConstrainedSockSize. This is useful for + virtual servers and other environments where system level TCP buffers may + be limited. If you’re on a virtual server, and you encounter the "Error + creating network socket: No buffer space available" message, you are + likely experiencing this problem.
+
+ The preferred solution is to have the admin increase the buffer pool for + the host itself via /proc/sys/net/ipv4/tcp_mem or equivalent facility; + this configuration option is a second-resort.
+
+ The DirPort option should also not be used if TCP buffers are scarce. The + cached directory requests consume additional sockets which exacerbates + the problem.
+
+ You should not enable this feature unless you encounter the "no buffer + space available" issue. Reducing the TCP buffers affects window size for + the TCP stream and will reduce throughput in proportion to round trip + time on long paths. (Default: 0.) +

+
+
+ConstrainedSockSize N bytes|KB +
+
+

+ When ConstrainedSockets is enabled the receive and transmit buffers for + all sockets will be set to this limit. Must be a value between 2048 and + 262144, in 1024 byte increments. Default of 8192 is recommended. +

+
+
+ControlPort PORT|auto +
+
+

+ If set, Tor will accept connections on this port and allow those + connections to control the Tor process using the Tor Control Protocol + (described in control-spec.txt). Note: unless you also specify one or + more of HashedControlPassword or CookieAuthentication, + setting this option will cause Tor to allow any process on the local + host to control it. (Setting both authentication methods means either + method is sufficient to authenticate to Tor.) This + option is required for many Tor controllers; most use the value of 9051. + Set it to "auto" to have Tor pick a port for you. (Default: 0). +

+
+
+ControlListenAddress IP[:PORT] +
+
+

+ Bind the controller listener to this address. If you specify a port, bind + to this port rather than the one specified in ControlPort. We strongly + recommend that you leave this alone unless you know what you’re doing, + since giving attackers access to your control listener is really + dangerous. (Default: 127.0.0.1) This directive can be specified multiple + times to bind to multiple addresses/ports. +

+
+
+ControlSocket Path +
+
+

+ Like ControlPort, but listens on a Unix domain socket, rather than a TCP + socket. (Unix and Unix-like systems only.) +

+
+
+ControlSocketsGroupWritable 0|1 +
+
+

+ If this option is set to 0, don’t allow the filesystem group to read and + write unix sockets (e.g. ControlSocket). If the option is set to 1, make + the control socket readable and writable by the default GID. (Default: 0) +

+
+
+HashedControlPassword hashed_password +
+
+

+ Allow connections on the control port if they present + the password whose one-way hash is hashed_password. You + can compute the hash of a password by running "tor --hash-password + password". You can provide several acceptable passwords by using more + than one HashedControlPassword line. +

+
+
+CookieAuthentication 0|1 +
+
+

+ If this option is set to 1, allow connections on the control port + when the connecting process knows the contents of a file named + "control_auth_cookie", which Tor will create in its data directory. This + authentication method should only be used on systems with good filesystem + security. (Default: 0) +

+
+
+CookieAuthFile Path +
+
+

+ If set, this option overrides the default location and file name + for Tor’s cookie file. (See CookieAuthentication above.) +

+
+
+CookieAuthFileGroupReadable 0|1|Groupname +
+
+

+ If this option is set to 0, don’t allow the filesystem group to read the + cookie file. If the option is set to 1, make the cookie file readable by + the default GID. [Making the file readable by other groups is not yet + implemented; let us know if you need this for some reason.] (Default: 0). +

+
+
+ControlPortWriteToFile Path +
+
+

+ If set, Tor writes the address and port of any control port it opens to + this address. Usable by controllers to learn the actual control port + when ControlPort is set to "auto". +

+
+
+ControlPortFileGroupReadable 0|1 +
+
+

+ If this option is set to 0, don’t allow the filesystem group to read the + control port file. If the option is set to 1, make the control port + file readable by the default GID. (Default: 0). +

+
+
+DataDirectory DIR +
+
+

+ Store working data in DIR (Default: /var/lib/tor) +

+
+
+DirServer [nickname] [flags] address:port fingerprint +
+
+

+ Use a nonstandard authoritative directory server at the provided address + and port, with the specified key fingerprint. This option can be repeated + many times, for multiple authoritative directory servers. Flags are + separated by spaces, and determine what kind of an authority this directory + is. By default, every authority is authoritative for current ("v2")-style + directories, unless the "no-v2" flag is given. If the "v1" flags is + provided, Tor will use this server as an authority for old-style (v1) + directories as well. (Only directory mirrors care about this.) Tor will + use this server as an authority for hidden service information if the "hs" + flag is set, or if the "v1" flag is set and the "no-hs" flag is not set. + Tor will use this authority as a bridge authoritative directory if the + "bridge" flag is set. If a flag "orport=port" is given, Tor will use the + given port when opening encrypted tunnels to the dirserver. Lastly, if a + flag "v3ident=fp" is given, the dirserver is a v3 directory authority + whose v3 long-term signing key has the fingerprint fp.
+
+ If no dirserver line is given, Tor will use the default directory + servers. NOTE: this option is intended for setting up a private Tor + network with its own directory authorities. If you use it, you will be + distinguishable from other users, because you won’t believe the same + authorities they do. +

+
+
+

AlternateDirAuthority [nickname] [flags] address:port fingerprint

+

AlternateHSAuthority [nickname] [flags] address:port fingerprint

+
+
+AlternateBridgeAuthority [nickname] [flags] address:port fingerprint +
+
+

+ As DirServer, but replaces less of the default directory authorities. Using + AlternateDirAuthority replaces the default Tor directory authorities, but + leaves the hidden service authorities and bridge authorities in place. + Similarly, Using AlternateHSAuthority replaces the default hidden service + authorities, but not the directory or bridge authorities. +

+
+
+DisableAllSwap 0|1 +
+
+

+ If set to 1, Tor will attempt to lock all current and future memory pages, + so that memory cannot be paged out. Windows, OS X and Solaris are currently + not supported. We believe that this feature works on modern Gnu/Linux + distributions, and that it should work on *BSD systems (untested). This + option requires that you start your Tor as root, and you should use the + User option to properly reduce Tor’s privileges. (Default: 0) +

+
+
+FetchDirInfoEarly 0|1 +
+
+

+ If set to 1, Tor will always fetch directory information like other + directory caches, even if you don’t meet the normal criteria for fetching + early. Normal users should leave it off. (Default: 0) +

+
+
+FetchDirInfoExtraEarly 0|1 +
+
+

+ If set to 1, Tor will fetch directory information before other directory + caches. It will attempt to download directory information closer to the + start of the consensus period. Normal users should leave it off. + (Default: 0) +

+
+
+FetchHidServDescriptors 0|1 +
+
+

+ If set to 0, Tor will never fetch any hidden service descriptors from the + rendezvous directories. This option is only useful if you’re using a Tor + controller that handles hidden service fetches for you. (Default: 1) +

+
+
+FetchServerDescriptors 0|1 +
+
+

+ If set to 0, Tor will never fetch any network status summaries or server + descriptors from the directory servers. This option is only useful if + you’re using a Tor controller that handles directory fetches for you. + (Default: 1) +

+
+
+FetchUselessDescriptors 0|1 +
+
+

+ If set to 1, Tor will fetch every non-obsolete descriptor from the + authorities that it hears about. Otherwise, it will avoid fetching useless + descriptors, for example for routers that are not running. This option is + useful if you’re using the contributed "exitlist" script to enumerate Tor + nodes that exit to certain addresses. (Default: 0) +

+
+
+HTTPProxy host[:port] +
+
+

+ Tor will make all its directory requests through this host:port (or host:80 + if port is not specified), rather than connecting directly to any directory + servers. +

+
+
+HTTPProxyAuthenticator username:password +
+
+

+ If defined, Tor will use this username:password for Basic HTTP proxy + authentication, as in RFC 2617. This is currently the only form of HTTP + proxy authentication that Tor supports; feel free to submit a patch if you + want it to support others. +

+
+
+HTTPSProxy host[:port] +
+
+

+ Tor will make all its OR (SSL) connections through this host:port (or + host:443 if port is not specified), via HTTP CONNECT rather than connecting + directly to servers. You may want to set FascistFirewall to restrict + the set of ports you might try to connect to, if your HTTPS proxy only + allows connecting to certain ports. +

+
+
+HTTPSProxyAuthenticator username:password +
+
+

+ If defined, Tor will use this username:password for Basic HTTPS proxy + authentication, as in RFC 2617. This is currently the only form of HTTPS + proxy authentication that Tor supports; feel free to submit a patch if you + want it to support others. +

+
+
+Socks4Proxy host[:port] +
+
+

+ Tor will make all OR connections through the SOCKS 4 proxy at host:port + (or host:1080 if port is not specified). +

+
+
+Socks5Proxy host[:port] +
+
+

+ Tor will make all OR connections through the SOCKS 5 proxy at host:port + (or host:1080 if port is not specified). +

+
+
+

Socks5ProxyUsername username

+
+
+Socks5ProxyPassword password +
+
+

+ If defined, authenticate to the SOCKS 5 server using username and password + in accordance to RFC 1929. Both username and password must be between 1 and + 255 characters. +

+
+
+KeepalivePeriod NUM +
+
+

+ To keep firewalls from expiring connections, send a padding keepalive cell + every NUM seconds on open connections that are in use. If the connection + has no open circuits, it will instead be closed after NUM seconds of + idleness. (Default: 5 minutes) +

+
+
+Log minSeverity[-maxSeverity] stderr|stdout|syslog +
+
+

+ Send all messages between minSeverity and maxSeverity to the standard + output stream, the standard error stream, or to the system log. (The + "syslog" value is only supported on Unix.) Recognized severity levels are + debug, info, notice, warn, and err. We advise using "notice" in most cases, + since anything more verbose may provide sensitive information to an + attacker who obtains the logs. If only one severity level is given, all + messages of that level or higher will be sent to the listed destination. +

+
+
+Log minSeverity[-maxSeverity] file FILENAME +
+
+

+ As above, but send log messages to the listed filename. The + "Log" option may appear more than once in a configuration file. + Messages are sent to all the logs that match their severity + level. +

+
+
+

Log [domain,…]minSeverity[-maxSeverity] … file FILENAME

+
+
+Log [domain,…]minSeverity[-maxSeverity] … stderr|stdout|syslog +
+
+

+ As above, but select messages by range of log severity and by a + set of "logging domains". Each logging domain corresponds to an area of + functionality inside Tor. You can specify any number of severity ranges + for a single log statement, each of them prefixed by a comma-separated + list of logging domains. You can prefix a domain with ~ to indicate + negation, and use * to indicate "all domains". If you specify a severity + range without a list of domains, it matches all domains.
+
+ This is an advanced feature which is most useful for debugging one or two + of Tor’s subsystems at a time.
+
+ The currently recognized domains are: general, crypto, net, config, fs, + protocol, mm, http, app, control, circ, rend, bug, dir, dirserv, or, edge, + acct, hist, and handshake. Domain names are case-insensitive.
+
+ For example, "Log [handshake]debug [~net,~mm]info notice stdout" sends + to stdout: all handshake messages of any severity, all info-and-higher + messages from domains other than networking and memory management, and all + messages of severity notice or higher. +

+
+
+LogMessageDomains 0|1 +
+
+

+ If 1, Tor includes message domains with each log message. Every log + message currently has at least one domain; most currently have exactly + one. This doesn’t affect controller log messages. (Default: 0) +

+
+
+OutboundBindAddress IP +
+
+

+ Make all outbound connections originate from the IP address specified. This + is only useful when you have multiple network interfaces, and you want all + of Tor’s outgoing connections to use a single one. This setting will be + ignored for connections to the loopback addresses (127.0.0.0/8 and ::1). +

+
+
+PidFile FILE +
+
+

+ On startup, write our PID to FILE. On clean shutdown, remove + FILE. +

+
+
+ProtocolWarnings 0|1 +
+
+

+ If 1, Tor will log with severity 'warn' various cases of other parties not + following the Tor specification. Otherwise, they are logged with severity + 'info'. (Default: 0) +

+
+
+RunAsDaemon 0|1 +
+
+

+ If 1, Tor forks and daemonizes to the background. This option has no effect + on Windows; instead you should use the --service command-line option. + (Default: 0) +

+
+
+SafeLogging 0|1|relay +
+
+

+ Tor can scrub potentially sensitive strings from log messages (e.g. + addresses) by replacing them with the string [scrubbed]. This way logs can + still be useful, but they don’t leave behind personally identifying + information about what sites a user might have visited.
+
+ If this option is set to 0, Tor will not perform any scrubbing, if it is + set to 1, all potentially sensitive strings are replaced. If it is set to + relay, all log messages generated when acting as a relay are sanitized, but + all messages generated when acting as a client are not. (Default: 1) +

+
+
+User UID +
+
+

+ On startup, setuid to this user and setgid to their primary group. +

+
+
+HardwareAccel 0|1 +
+
+

+ If non-zero, try to use built-in (static) crypto hardware acceleration when + available. (Default: 0) +

+
+
+AccelName NAME +
+
+

+ When using OpenSSL hardware crypto acceleration attempt to load the dynamic + engine of this name. This must be used for any dynamic hardware engine. + Names can be verified with the openssl engine command. +

+
+
+AccelDir DIR +
+
+

+ Specify this option if using dynamic hardware acceleration and the engine + implementation library resides somewhere other than the OpenSSL default. +

+
+
+AvoidDiskWrites 0|1 +
+
+

+ If non-zero, try to write to disk less frequently than we would otherwise. + This is useful when running on flash memory or other media that support + only a limited number of writes. (Default: 0) +

+
+
+TunnelDirConns 0|1 +
+
+

+ If non-zero, when a directory server we contact supports it, we will build + a one-hop circuit and make an encrypted connection via its ORPort. + (Default: 1) +

+
+
+PreferTunneledDirConns 0|1 +
+
+

+ If non-zero, we will avoid directory servers that don’t support tunneled + directory connections, when possible. (Default: 1) +

+
+
+CircuitPriorityHalflife NUM1 +
+
+

+ If this value is set, we override the default algorithm for choosing which + circuit’s cell to deliver or relay next. When the value is 0, we + round-robin between the active circuits on a connection, delivering one + cell from each in turn. When the value is positive, we prefer delivering + cells from whichever connection has the lowest weighted cell count, where + cells are weighted exponentially according to the supplied + CircuitPriorityHalflife value (in seconds). If this option is not set at + all, we use the behavior recommended in the current consensus + networkstatus. This is an advanced option; you generally shouldn’t have + to mess with it. (Default: not set.) +

+
+
+
+

CLIENT OPTIONS

+
+

The following options are useful only for clients (that is, if +SocksPort is non-zero):

+
+
+AllowInvalidNodes entry|exit|middle|introduction|rendezvous| +
+
+

+ If some Tor servers are obviously not working right, the directory + authorities can manually mark them as invalid, meaning that it’s not + recommended you use them for entry or exit positions in your circuits. You + can opt to use them in some circuit positions, though. The default is + "middle,rendezvous", and other choices are not advised. +

+
+
+ExcludeSingleHopRelays 0|1 +
+
+

+ This option controls whether circuits built by Tor will include relays with + the AllowSingleHopExits flag set to true. If ExcludeSingleHopRelays is set + to 0, these relays will be included. Note that these relays might be at + higher risk of being seized or observed, so they are not normally + included. Also note that relatively few clients turn off this option, + so using these relays might make your client stand out. + (Default: 1) +

+
+
+Bridge IP:ORPort [fingerprint] +
+
+

+ When set along with UseBridges, instructs Tor to use the relay at + "IP:ORPort" as a "bridge" relaying into the Tor network. If "fingerprint" + is provided (using the same format as for DirServer), we will verify that + the relay running at that location has the right fingerprint. We also use + fingerprint to look up the bridge descriptor at the bridge authority, if + it’s provided and if UpdateBridgesFromAuthority is set too. +

+
+
+LearnCircuitBuildTimeout 0|1 +
+
+

+ If 0, CircuitBuildTimeout adaptive learning is disabled. (Default: 1) +

+
+
+CircuitBuildTimeout NUM +
+
+

+ Try for at most NUM seconds when building circuits. If the circuit isn’t + open in that time, give up on it. If LearnCircuitBuildTimeout is 1, this + value serves as the initial value to use before a timeout is learned. If + LearnCircuitBuildTimeout is 0, this value is the only value used. + (Default: 60 seconds.) +

+
+
+CircuitIdleTimeout NUM +
+
+

+ If we have kept a clean (never used) circuit around for NUM seconds, then + close it. This way when the Tor client is entirely idle, it can expire all + of its circuits, and then expire its TLS connections. Also, if we end up + making a circuit that is not useful for exiting any of the requests we’re + receiving, it won’t forever take up a slot in the circuit list. (Default: 1 + hour.) +

+
+
+CircuitStreamTimeout NUM +
+
+

+ If non-zero, this option overrides our internal timeout schedule for how + many seconds until we detach a stream from a circuit and try a new circuit. + If your network is particularly slow, you might want to set this to a + number like 60. (Default: 0) +

+
+
+ClientOnly 0|1 +
+
+

+ If set to 1, Tor will under no circumstances run as a server or serve + directory requests. The default is to run as a client unless ORPort is + configured. (Usually, you don’t need to set this; Tor is pretty smart at + figuring out whether you are reliable and high-bandwidth enough to be a + useful server.) (Default: 0) +

+
+
+ExcludeNodes node,node, +
+
+

+ A list of identity fingerprints, nicknames, country codes and address + patterns of nodes to avoid when building a circuit. + (Example: + ExcludeNodes SlowServer, ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, {cc}, 255.254.0.0/8)
+
+ By default, this option is treated as a preference that Tor is allowed + to override in order to keep working. + For example, if you try to connect to a hidden service, + but you have excluded all of the hidden service’s introduction points, + Tor will connect to one of them anyway. If you do not want this + behavior, set the StrictNodes option (documented below).
+
+ Note also that if you are a relay, this (and the other node selection + options below) only affects your own circuits that Tor builds for you. + Clients can still build circuits through you to any node. Controllers + can tell Tor to build circuits through any node. +

+
+
+ExcludeExitNodes node,node, +
+
+

+ A list of identity fingerprints, nicknames, country codes and address + patterns of nodes to never use when picking an exit node---that is, a + node that delivers traffic for you outside the Tor network. Note that any + node listed in ExcludeNodes is automatically considered to be part of this + list too. See also the caveats on the "ExitNodes" option below. +

+
+
+ExitNodes node,node, +
+
+

+ A list of identity fingerprints, nicknames, country codes and address + patterns of nodes to use as exit node---that is, a + node that delivers traffic for you outside the Tor network.
+
+ Note that if you list too few nodes here, or if you exclude too many exit + nodes with ExcludeExitNodes, you can degrade functionality. For example, + if none of the exits you list allows traffic on port 80 or 443, you won’t + be able to browse the web.
+
+ Note also that not every circuit is used to deliver traffic outside of + the Tor network. It is normal to see non-exit circuits (such as those + used to connect to hidden services, those that do directory fetches, + those used for relay reachability self-tests, and so on) that end + at a non-exit node. To + keep a node from being used entirely, see ExcludeNodes and StrictNodes.
+
+ The ExcludeNodes option overrides this option: any node listed in both + ExitNodes and ExcludeNodes is treated as excluded.
+
+ The .exit address notation, if enabled via AllowDotExit, overrides + this option. +

+
+
+EntryNodes node,node, +
+
+

+ A list of identity fingerprints and nicknames of nodes + to use for the first hop in your normal circuits. (Country codes and + address patterns are not yet supported.) Normal circuits include all + circuits except for direct connections to directory servers. The Bridge + option overrides this option; if you have configured bridges and + UseBridges is 1, the Bridges are used as your entry nodes.
+
+ The ExcludeNodes option overrides this option: any node listed in both + EntryNodes and ExcludeNodes is treated as excluded. +

+
+
+StrictNodes 0|1 +
+
+

+ If StrictNodes is set to 1, Tor will treat the ExcludeNodes option as a + requirement to follow for all the circuits you generate, even if doing so + will break functionality for you. If StrictNodes is set to 0, Tor will + still try to avoid nodes in the ExcludeNodes list, but it will err on the + side of avoiding unexpected errors. Specifically, StrictNodes 0 tells + Tor that it is okay to use an excluded node when it is necessary to + perform relay reachability self-tests, connect to + a hidden service, provide a hidden service to a client, fulfill a .exit + request, upload directory information, or download directory information. + (Default: 0) +

+
+
+FascistFirewall 0|1 +
+
+

+ If 1, Tor will only create outgoing connections to ORs running on ports + that your firewall allows (defaults to 80 and 443; see FirewallPorts). + This will allow you to run Tor as a client behind a firewall with + restrictive policies, but will not allow you to run as a server behind such + a firewall. If you prefer more fine-grained control, use + ReachableAddresses instead. +

+
+
+FirewallPorts PORTS +
+
+

+ A list of ports that your firewall allows you to connect to. Only used when + FascistFirewall is set. This option is deprecated; use ReachableAddresses + instead. (Default: 80, 443) +

+
+
+HidServAuth onion-address auth-cookie [service-name] +
+
+

+ Client authorization for a hidden service. Valid onion addresses contain 16 + characters in a-z2-7 plus ".onion", and valid auth cookies contain 22 + characters in A-Za-z0-9+/. The service name is only used for internal + purposes, e.g., for Tor controllers. This option may be used multiple times + for different hidden services. If a hidden service uses authorization and + this option is not set, the hidden service is not accessible. Hidden + services can be configured to require authorization using the + HiddenServiceAuthorizeClient option. +

+
+
+ReachableAddresses ADDR[/MASK][:PORT]… +
+
+

+ A comma-separated list of IP addresses and ports that your firewall allows + you to connect to. The format is as for the addresses in ExitPolicy, except + that "accept" is understood unless "reject" is explicitly provided. For + example, 'ReachableAddresses 99.0.0.0/8, reject 18.0.0.0/8:80, accept + *:80' means that your firewall allows connections to everything inside net + 99, rejects port 80 connections to net 18, and accepts connections to port + 80 otherwise. (Default: 'accept *:*'.) +

+
+
+ReachableDirAddresses ADDR[/MASK][:PORT]… +
+
+

+ Like ReachableAddresses, a list of addresses and ports. Tor will obey + these restrictions when fetching directory information, using standard HTTP + GET requests. If not set explicitly then the value of + ReachableAddresses is used. If HTTPProxy is set then these + connections will go through that proxy. +

+
+
+ReachableORAddresses ADDR[/MASK][:PORT]… +
+
+

+ Like ReachableAddresses, a list of addresses and ports. Tor will obey + these restrictions when connecting to Onion Routers, using TLS/SSL. If not + set explicitly then the value of ReachableAddresses is used. If + HTTPSProxy is set then these connections will go through that proxy.
+
+ The separation between ReachableORAddresses and + ReachableDirAddresses is only interesting when you are connecting + through proxies (see HTTPProxy and HTTPSProxy). Most proxies limit + TLS connections (which Tor uses to connect to Onion Routers) to port 443, + and some limit HTTP GET requests (which Tor uses for fetching directory + information) to port 80. +

+
+
+LongLivedPorts PORTS +
+
+

+ A list of ports for services that tend to have long-running connections + (e.g. chat and interactive shells). Circuits for streams that use these + ports will contain only high-uptime nodes, to reduce the chance that a node + will go down before the stream is finished. (Default: 21, 22, 706, 1863, + 5050, 5190, 5222, 5223, 6667, 6697, 8300) +

+
+
+MapAddress address newaddress +
+
+

+ When a request for address arrives to Tor, it will rewrite it to newaddress + before processing it. For example, if you always want connections to + www.indymedia.org to exit via torserver (where torserver is the + nickname of the server), use "MapAddress www.indymedia.org + www.indymedia.org.torserver.exit". +

+
+
+NewCircuitPeriod NUM +
+
+

+ Every NUM seconds consider whether to build a new circuit. (Default: 30 + seconds) +

+
+
+MaxCircuitDirtiness NUM +
+
+

+ Feel free to reuse a circuit that was first used at most NUM seconds ago, + but never attach a new stream to a circuit that is too old. (Default: 10 + minutes) +

+
+
+NodeFamily node,node, +
+
+

+ The Tor servers, defined by their identity fingerprints or nicknames, + constitute a "family" of similar or co-administered servers, so never use + any two of them in the same circuit. Defining a NodeFamily is only needed + when a server doesn’t list the family itself (with MyFamily). This option + can be used multiple times. +

+
+
+EnforceDistinctSubnets 0|1 +
+
+

+ If 1, Tor will not put two servers whose IP addresses are "too close" on + the same circuit. Currently, two addresses are "too close" if they lie in + the same /16 range. (Default: 1) +

+
+
+SocksPort PORT|auto +
+
+

+ Advertise this port to listen for connections from Socks-speaking + applications. Set this to 0 if you don’t want to allow application + connections via SOCKS. Set it to "auto" to have Tor pick a port for + you. (Default: 9050) +

+
+
+SocksListenAddress IP[:PORT] +
+
+

+ Bind to this address to listen for connections from Socks-speaking + applications. (Default: 127.0.0.1) You can also specify a port (e.g. + 192.168.0.1:9100). This directive can be specified multiple times to bind + to multiple addresses/ports. +

+
+
+SocksPolicy policy,policy, +
+
+

+ Set an entrance policy for this server, to limit who can connect to the + SocksPort and DNSPort ports. The policies have the same form as exit + policies below. +

+
+
+SocksTimeout NUM +
+
+

+ Let a socks connection wait NUM seconds handshaking, and NUM seconds + unattached waiting for an appropriate circuit, before we fail it. (Default: + 2 minutes.) +

+
+
+TrackHostExits host,.domain, +
+
+

+ For each value in the comma separated list, Tor will track recent + connections to hosts that match this value and attempt to reuse the same + exit node for each. If the value is prepended with a '.', it is treated as + matching an entire domain. If one of the values is just a '.', it means + match everything. This option is useful if you frequently connect to sites + that will expire all your authentication cookies (i.e. log you out) if + your IP address changes. Note that this option does have the disadvantage + of making it more clear that a given history is associated with a single + user. However, most people who would wish to observe this will observe it + through cookies or other protocol-specific means anyhow. +

+
+
+TrackHostExitsExpire NUM +
+
+

+ Since exit servers go up and down, it is desirable to expire the + association between host and exit server after NUM seconds. The default is + 1800 seconds (30 minutes). +

+
+
+UpdateBridgesFromAuthority 0|1 +
+
+

+ When set (along with UseBridges), Tor will try to fetch bridge descriptors + from the configured bridge authorities when feasible. It will fall back to + a direct request if the authority responds with a 404. (Default: 0) +

+
+
+UseBridges 0|1 +
+
+

+ When set, Tor will fetch descriptors for each bridge listed in the "Bridge" + config lines, and use these relays as both entry guards and directory + guards. (Default: 0) +

+
+
+UseEntryGuards 0|1 +
+
+

+ If this option is set to 1, we pick a few long-term entry servers, and try + to stick with them. This is desirable because constantly changing servers + increases the odds that an adversary who owns some servers will observe a + fraction of your paths. (Defaults to 1.) +

+
+
+NumEntryGuards NUM +
+
+

+ If UseEntryGuards is set to 1, we will try to pick a total of NUM routers + as long-term entries for our circuits. (Defaults to 3.) +

+
+
+SafeSocks 0|1 +
+
+

+ When this option is enabled, Tor will reject application connections that + use unsafe variants of the socks protocol — ones that only provide an IP + address, meaning the application is doing a DNS resolve first. + Specifically, these are socks4 and socks5 when not doing remote DNS. + (Defaults to 0.) +

+
+
+TestSocks 0|1 +
+
+

+ When this option is enabled, Tor will make a notice-level log entry for + each connection to the Socks port indicating whether the request used a + safe socks protocol or an unsafe one (see above entry on SafeSocks). This + helps to determine whether an application using Tor is possibly leaking + DNS requests. (Default: 0) +

+
+
+WarnUnsafeSocks 0|1 +
+
+

+ When this option is enabled, Tor will warn whenever a request is + received that only contains an IP address instead of a hostname. Allowing + applications to do DNS resolves themselves is usually a bad idea and + can leak your location to attackers. (Default: 1) +

+
+
+VirtualAddrNetwork Address/bits +
+
+

+ When Tor needs to assign a virtual (unused) address because of a MAPADDRESS + command from the controller or the AutomapHostsOnResolve feature, Tor + picks an unassigned address from this range. (Default: + 127.192.0.0/10)
+
+ When providing proxy server service to a network of computers using a tool + like dns-proxy-tor, change this address to "10.192.0.0/10" or + "172.16.0.0/12". The default VirtualAddrNetwork address range on a + properly configured machine will route to the loopback interface. For + local use, no change to the default VirtualAddrNetwork setting is needed. +

+
+
+AllowNonRFC953Hostnames 0|1 +
+
+

+ When this option is disabled, Tor blocks hostnames containing illegal + characters (like @ and :) rather than sending them to an exit node to be + resolved. This helps trap accidental attempts to resolve URLs and so on. + (Default: 0) +

+
+
+AllowDotExit 0|1 +
+
+

+ If enabled, we convert "www.google.com.foo.exit" addresses on the + SocksPort/TransPort/NATDPort into "www.google.com" addresses that exit from + the node "foo". Disabled by default since attacking websites and exit + relays can use it to manipulate your path selection. (Default: 0) +

+
+
+FastFirstHopPK 0|1 +
+
+

+ When this option is disabled, Tor uses the public key step for the first + hop of creating circuits. Skipping it is generally safe since we have + already used TLS to authenticate the relay and to establish forward-secure + keys. Turning this option off makes circuit building slower.
+
+ Note that Tor will always use the public key step for the first hop if it’s + operating as a relay, and it will never use the public key step if it + doesn’t yet know the onion key of the first hop. (Default: 1) +

+
+
+TransPort PORT|auto +
+
+

+ If non-zero, enables transparent proxy support on PORT (by convention, + 9040). Requires OS support for transparent proxies, such as BSDs' pf or + Linux’s IPTables. If you’re planning to use Tor as a transparent proxy for + a network, you’ll want to examine and change VirtualAddrNetwork from the + default setting. You’ll also want to set the TransListenAddress option for + the network you’d like to proxy. Set it to "auto" to have Tor pick a + port for you. (Default: 0). +

+
+
+TransListenAddress IP[:PORT] +
+
+

+ Bind to this address to listen for transparent proxy connections. (Default: + 127.0.0.1). This is useful for exporting a transparent proxy server to an + entire network. +

+
+
+NATDPort PORT|auto +
+
+

+ Allow old versions of ipfw (as included in old versions of FreeBSD, etc.) + to send connections through Tor using the NATD protocol. This option is + only for people who cannot use TransPort. Set it to "auto" to have Tor + pick a port for you. (Default: 0) +

+
+
+NATDListenAddress IP[:PORT] +
+
+

+ Bind to this address to listen for NATD connections. (Default: 127.0.0.1). +

+
+
+AutomapHostsOnResolve 0|1 +
+
+

+ When this option is enabled, and we get a request to resolve an address + that ends with one of the suffixes in AutomapHostsSuffixes, we map an + unused virtual address to that address, and return the new virtual address. + This is handy for making ".onion" addresses work with applications that + resolve an address and then connect to it. (Default: 0). +

+
+
+AutomapHostsSuffixes SUFFIX,SUFFIX, +
+
+

+ A comma-separated list of suffixes to use with AutomapHostsOnResolve. + The "." suffix is equivalent to "all addresses." (Default: .exit,.onion). +

+
+
+DNSPort PORT|auto +
+
+

+ If non-zero, Tor listens for UDP DNS requests on this port and resolves + them anonymously. Set it to "auto" to have Tor pick a port for + you. (Default: 0). +

+
+
+DNSListenAddress IP[:PORT] +
+
+

+ Bind to this address to listen for DNS connections. (Default: 127.0.0.1). +

+
+
+ClientDNSRejectInternalAddresses 0|1 +
+
+

+ If true, Tor does not believe any anonymously retrieved DNS answer that + tells it that an address resolves to an internal address (like 127.0.0.1 or + 192.168.0.1). This option prevents certain browser-based attacks; don’t + turn it off unless you know what you’re doing. (Default: 1). +

+
+
+ClientRejectInternalAddresses 0|1 +
+
+

+ If true, Tor does not try to fulfill requests to connect to an internal + address (like 127.0.0.1 or 192.168.0.1) unless a exit node is + specifically requested (for example, via a .exit hostname, or a + controller request). (Default: 1). +

+
+
+DownloadExtraInfo 0|1 +
+
+

+ If true, Tor downloads and caches "extra-info" documents. These documents + contain information about servers other than the information in their + regular router descriptors. Tor does not use this information for anything + itself; to save bandwidth, leave this option turned off. (Default: 0). +

+
+
+FallbackNetworkstatusFile FILENAME +
+
+

+ If Tor doesn’t have a cached networkstatus file, it starts out using this + one instead. Even if this file is out of date, Tor can still use it to + learn about directory mirrors, so it doesn’t need to put load on the + authorities. (Default: None). +

+
+
+WarnPlaintextPorts port,port, +
+
+

+ Tells Tor to issue a warnings whenever the user tries to make an anonymous + connection to one of these ports. This option is designed to alert users + to services that risk sending passwords in the clear. (Default: + 23,109,110,143). +

+
+
+RejectPlaintextPorts port,port, +
+
+

+ Like WarnPlaintextPorts, but instead of warning about risky port uses, Tor + will instead refuse to make the connection. (Default: None). +

+
+
+AllowSingleHopCircuits 0|1 +
+
+

+ When this option is set, the attached Tor controller can use relays + that have the AllowSingleHopExits option turned on to build + one-hop Tor connections. (Default: 0) +

+
+
+
+

SERVER OPTIONS

+
+

The following options are useful only for servers (that is, if ORPort +is non-zero):

+
+
+Address address +
+
+

+ The IP address or fully qualified domain name of this server (e.g. + moria.mit.edu). You can leave this unset, and Tor will guess your IP + address. This IP address is the one used to tell clients and other + servers where to find your Tor server; it doesn’t affect the IP that your + Tor client binds to. To bind to a different address, use the + *ListenAddress and OutboundBindAddress options. +

+
+
+AllowSingleHopExits 0|1 +
+
+

+ This option controls whether clients can use this server as a single hop + proxy. If set to 1, clients can use this server as an exit even if it is + the only hop in the circuit. Note that most clients will refuse to use + servers that set this option, since most clients have + ExcludeSingleHopRelays set. (Default: 0) +

+
+
+AssumeReachable 0|1 +
+
+

+ This option is used when bootstrapping a new Tor network. If set to 1, + don’t do self-reachability testing; just upload your server descriptor + immediately. If AuthoritativeDirectory is also set, this option + instructs the dirserver to bypass remote reachability testing too and list + all connected servers as running. +

+
+
+BridgeRelay 0|1 +
+
+

+ Sets the relay to act as a "bridge" with respect to relaying connections + from bridge users to the Tor network. It mainly causes Tor to publish a + server descriptor to the bridge database, rather than publishing a relay + descriptor to the public directory authorities. +

+
+
+ContactInfo email_address +
+
+

+ Administrative contact information for server. This line might get picked + up by spam harvesters, so you may want to obscure the fact that it’s an + email address. +

+
+
+ExitPolicy policy,policy, +
+
+

+ Set an exit policy for this server. Each policy is of the form + "accept|reject ADDR[/MASK][:PORT]". If /MASK is + omitted then this policy just applies to the host given. Instead of giving + a host or network you can also use "*" to denote the universe (0.0.0.0/0). + PORT can be a single port number, an interval of ports + "FROM_PORT-TO_PORT", or "*". If PORT is omitted, that means + "*".
+
+ For example, "accept 18.7.22.69:*,reject 18.0.0.0/8:*,accept *:*" would + reject any traffic destined for MIT except for web.mit.edu, and accept + anything else.
+
+ To specify all internal and link-local networks (including 0.0.0.0/8, + 169.254.0.0/16, 127.0.0.0/8, 192.168.0.0/16, 10.0.0.0/8, and + 172.16.0.0/12), you can use the "private" alias instead of an address. + These addresses are rejected by default (at the beginning of your exit + policy), along with your public IP address, unless you set the + ExitPolicyRejectPrivate config option to 0. For example, once you’ve done + that, you could allow HTTP to 127.0.0.1 and block all other connections to + internal networks with "accept 127.0.0.1:80,reject private:*", though that + may also allow connections to your own computer that are addressed to its + public (external) IP address. See RFC 1918 and RFC 3330 for more details + about internal and reserved IP address space.
+
+ This directive can be specified multiple times so you don’t have to put it + all on one line.
+
+ Policies are considered first to last, and the first match wins. If you + want to _replace_ the default exit policy, end your exit policy with + either a reject *:* or an accept *:*. Otherwise, you’re _augmenting_ + (prepending to) the default exit policy. The default exit policy is:
+

+
+
+
reject *:25
+reject *:119
+reject *:135-139
+reject *:445
+reject *:563
+reject *:1214
+reject *:4661-4666
+reject *:6346-6429
+reject *:6699
+reject *:6881-6999
+accept *:*
+
+
+
+ExitPolicyRejectPrivate 0|1 +
+
+

+ Reject all private (local) networks, along with your own public IP address, + at the beginning of your exit policy. See above entry on ExitPolicy. + (Default: 1) +

+
+
+MaxOnionsPending NUM +
+
+

+ If you have more than this number of onionskins queued for decrypt, reject + new ones. (Default: 100) +

+
+
+MyFamily node,node, +
+
+

+ Declare that this Tor server is controlled or administered by a group or + organization identical or similar to that of the other servers, defined by + their identity fingerprints or nicknames. When two servers both declare + that they are in the same 'family', Tor clients will not use them in the + same circuit. (Each server only needs to list the other servers in its + family; it doesn’t need to list itself, but it won’t hurt.) +

+
+
+Nickname name +
+
+

+ Set the server’s nickname to 'name'. Nicknames must be between 1 and 19 + characters inclusive, and must contain only the characters [a-zA-Z0-9]. +

+
+
+NumCPUs num +
+
+

+ How many processes to use at once for decrypting onionskins. (Default: 1) +

+
+
+ORPort PORT|auto +
+
+

+ Advertise this port to listen for connections from Tor clients and + servers. This option is required to be a Tor server. + Set it to "auto" to have Tor pick a port for you. (Default: 0). +

+
+
+ORListenAddress IP[:PORT] +
+
+

+ Bind to this IP address to listen for connections from Tor clients and + servers. If you specify a port, bind to this port rather than the one + specified in ORPort. (Default: 0.0.0.0) This directive can be specified + multiple times to bind to multiple addresses/ports. +

+
+
+PublishServerDescriptor 0|1|v1|v2|v3|bridge, +
+
+

+ This option specifies which descriptors Tor will publish when acting as + a relay. You can + choose multiple arguments, separated by commas. +
+ If this option is set to 0, Tor will not publish its + descriptors to any directories. (This is useful if you’re testing + out your server, or if you’re using a Tor controller that handles directory + publishing for you.) Otherwise, Tor will publish its descriptors of all + type(s) specified. The default is "1", + which means "if running as a server, publish the + appropriate descriptors to the authorities". +

+
+
+ShutdownWaitLength NUM +
+
+

+ When we get a SIGINT and we’re a server, we begin shutting down: + we close listeners and start refusing new circuits. After NUM + seconds, we exit. If we get a second SIGINT, we exit immedi- + ately. (Default: 30 seconds) +

+
+
+AccountingMax N bytes|KB|MB|GB|TB +
+
+

+ Never send more than the specified number of bytes in a given accounting + period, or receive more than that number in the period. For example, with + AccountingMax set to 1 GB, a server could send 900 MB and receive 800 MB + and continue running. It will only hibernate once one of the two reaches 1 + GB. When the number of bytes gets low, Tor will stop accepting new + connections and circuits. When the number of bytes + is exhausted, Tor will hibernate until some + time in the next accounting period. To prevent all servers from waking at + the same time, Tor will also wait until a random point in each period + before waking up. If you have bandwidth cost issues, enabling hibernation + is preferable to setting a low bandwidth, since it provides users with a + collection of fast servers that are up some of the time, which is more + useful than a set of slow servers that are always "available". +

+
+
+AccountingStart day|week|month [day] HH:MM +
+
+

+ Specify how long accounting periods last. If month is given, each + accounting period runs from the time HH:MM on the dayth day of one + month to the same day and time of the next. (The day must be between 1 and + 28.) If week is given, each accounting period runs from the time HH:MM + of the dayth day of one week to the same day and time of the next week, + with Monday as day 1 and Sunday as day 7. If day is given, each + accounting period runs from the time HH:MM each day to the same time on + the next day. All times are local, and given in 24-hour time. (Defaults to + "month 1 0:00".) +

+
+
+RefuseUnknownExits 0|1|auto +
+
+

+ Prevent nodes that don’t appear in the consensus from exiting using this + relay. If the option is 1, we always block exit attempts from such + nodes; if it’s 0, we never do, and if the option is "auto", then we do + whatever the authorities suggest in the consensus. (Defaults to auto.) +

+
+
+ServerDNSResolvConfFile filename +
+
+

+ Overrides the default DNS configuration with the configuration in + filename. The file format is the same as the standard Unix + "resolv.conf" file (7). This option, like all other ServerDNS options, + only affects name lookups that your server does on behalf of clients. + (Defaults to use the system DNS configuration.) +

+
+
+ServerDNSAllowBrokenConfig 0|1 +
+
+

+ If this option is false, Tor exits immediately if there are problems + parsing the system DNS configuration or connecting to nameservers. + Otherwise, Tor continues to periodically retry the system nameservers until + it eventually succeeds. (Defaults to "1".) +

+
+
+ServerDNSSearchDomains 0|1 +
+
+

+ If set to 1, then we will search for addresses in the local search domain. + For example, if this system is configured to believe it is in + "example.com", and a client tries to connect to "www", the client will be + connected to "www.example.com". This option only affects name lookups that + your server does on behalf of clients. (Defaults to "0".) +

+
+
+ServerDNSDetectHijacking 0|1 +
+
+

+ When this option is set to 1, we will test periodically to determine + whether our local nameservers have been configured to hijack failing DNS + requests (usually to an advertising site). If they are, we will attempt to + correct this. This option only affects name lookups that your server does + on behalf of clients. (Defaults to "1".) +

+
+
+ServerDNSTestAddresses address,address, +
+
+

+ When we’re detecting DNS hijacking, make sure that these valid addresses + aren’t getting redirected. If they are, then our DNS is completely useless, + and we’ll reset our exit policy to "reject :". This option only affects + name lookups that your server does on behalf of clients. (Defaults to + "www.google.com, www.mit.edu, www.yahoo.com, www.slashdot.org".) +

+
+
+ServerDNSAllowNonRFC953Hostnames 0|1 +
+
+

+ When this option is disabled, Tor does not try to resolve hostnames + containing illegal characters (like @ and :) rather than sending them to an + exit node to be resolved. This helps trap accidental attempts to resolve + URLs and so on. This option only affects name lookups that your server does + on behalf of clients. (Default: 0) +

+
+
+BridgeRecordUsageByCountry 0|1 +
+
+

+ When this option is enabled and BridgeRelay is also enabled, and we have + GeoIP data, Tor keeps a keep a per-country count of how many client + addresses have contacted it so that it can help the bridge authority guess + which countries have blocked access to it. (Default: 1) +

+
+
+ServerDNSRandomizeCase 0|1 +
+
+

+ When this option is set, Tor sets the case of each character randomly in + outgoing DNS requests, and makes sure that the case matches in DNS replies. + This so-called "0x20 hack" helps resist some types of DNS poisoning attack. + For more information, see "Increased DNS Forgery Resistance through + 0x20-Bit Encoding". This option only affects name lookups that your server + does on behalf of clients. (Default: 1) +

+
+
+GeoIPFile filename +
+
+

+ A filename containing GeoIP data, for use with BridgeRecordUsageByCountry. +

+
+
+CellStatistics 0|1 +
+
+

+ When this option is enabled, Tor writes statistics on the mean time that + cells spend in circuit queues to disk every 24 hours. (Default: 0) +

+
+
+DirReqStatistics 0|1 +
+
+

+ When this option is enabled, Tor writes statistics on the number and + response time of network status requests to disk every 24 hours. + (Default: 0) +

+
+
+EntryStatistics 0|1 +
+
+

+ When this option is enabled, Tor writes statistics on the number of + directly connecting clients to disk every 24 hours. (Default: 0) +

+
+
+ExitPortStatistics 0|1 +
+
+

+ When this option is enabled, Tor writes statistics on the number of relayed + bytes and opened stream per exit port to disk every 24 hours. (Default: 0) +

+
+
+ExtraInfoStatistics 0|1 +
+
+

+ When this option is enabled, Tor includes previously gathered statistics in + its extra-info documents that it uploads to the directory authorities. + (Default: 0) +

+
+
+
+

DIRECTORY SERVER OPTIONS

+
+

The following options are useful only for directory servers (that is, +if DirPort is non-zero):

+
+
+AuthoritativeDirectory 0|1 +
+
+

+ When this option is set to 1, Tor operates as an authoritative directory + server. Instead of caching the directory, it generates its own list of + good servers, signs it, and sends that to the clients. Unless the clients + already have you listed as a trusted directory, you probably do not want + to set this option. Please coordinate with the other admins at + tor-ops@torproject.org if you think you should be a directory. +

+
+
+DirPortFrontPage FILENAME +
+
+

+ When this option is set, it takes an HTML file and publishes it as "/" on + the DirPort. Now relay operators can provide a disclaimer without needing + to set up a separate webserver. There’s a sample disclaimer in + contrib/tor-exit-notice.html. +

+
+
+V1AuthoritativeDirectory 0|1 +
+
+

+ When this option is set in addition to AuthoritativeDirectory, Tor + generates version 1 directory and running-routers documents (for legacy + Tor clients up to 0.1.0.x). +

+
+
+V2AuthoritativeDirectory 0|1 +
+
+

+ When this option is set in addition to AuthoritativeDirectory, Tor + generates version 2 network statuses and serves descriptors, etc as + described in doc/spec/dir-spec-v2.txt (for Tor clients and servers running + 0.1.1.x and 0.1.2.x). +

+
+
+V3AuthoritativeDirectory 0|1 +
+
+

+ When this option is set in addition to AuthoritativeDirectory, Tor + generates version 3 network statuses and serves descriptors, etc as + described in doc/spec/dir-spec.txt (for Tor clients and servers running at + least 0.2.0.x). +

+
+
+VersioningAuthoritativeDirectory 0|1 +
+
+

+ When this option is set to 1, Tor adds information on which versions of + Tor are still believed safe for use to the published directory. Each + version 1 authority is automatically a versioning authority; version 2 + authorities provide this service optionally. See RecommendedVersions, + RecommendedClientVersions, and RecommendedServerVersions. +

+
+
+NamingAuthoritativeDirectory 0|1 +
+
+

+ When this option is set to 1, then the server advertises that it has + opinions about nickname-to-fingerprint bindings. It will include these + opinions in its published network-status pages, by listing servers with + the flag "Named" if a correct binding between that nickname and fingerprint + has been registered with the dirserver. Naming dirservers will refuse to + accept or publish descriptors that contradict a registered binding. See + approved-routers in the FILES section below. +

+
+
+HSAuthoritativeDir 0|1 +
+
+

+ When this option is set in addition to AuthoritativeDirectory, Tor also + accepts and serves v0 hidden service descriptors, + which are produced and used by Tor 0.2.1.x and older. (Default: 0) +

+
+
+HidServDirectoryV2 0|1 +
+
+

+ When this option is set, Tor accepts and serves v2 hidden service + descriptors. Setting DirPort is not required for this, because clients + connect via the ORPort by default. (Default: 1) +

+
+
+BridgeAuthoritativeDir 0|1 +
+
+

+ When this option is set in addition to AuthoritativeDirectory, Tor + accepts and serves router descriptors, but it caches and serves the main + networkstatus documents rather than generating its own. (Default: 0) +

+
+
+MinUptimeHidServDirectoryV2 N seconds|minutes|hours|days|weeks +
+
+

+ Minimum uptime of a v2 hidden service directory to be accepted as such by + authoritative directories. (Default: 25 hours) +

+
+
+DirPort PORT|auto +
+
+

+ If this option is nonzero, advertise the directory service on this port. + Set it to "auto" to have Tor pick a port for you. (Default: 0) +

+
+
+DirListenAddress IP[:PORT] +
+
+

+ Bind the directory service to this address. If you specify a port, bind to + this port rather than the one specified in DirPort. (Default: 0.0.0.0) + This directive can be specified multiple times to bind to multiple + addresses/ports. +

+
+
+DirPolicy policy,policy, +
+
+

+ Set an entrance policy for this server, to limit who can connect to the + directory ports. The policies have the same form as exit policies above. +

+
+
+FetchV2Networkstatus 0|1 +
+
+

+ If set, we try to fetch the (obsolete, unused) version 2 network status + consensus documents from the directory authorities. No currently + supported Tor version uses them. (Default: 0.) +

+
+
+
+

DIRECTORY AUTHORITY SERVER OPTIONS

+
+
+
+RecommendedVersions STRING +
+
+

+ STRING is a comma-separated list of Tor versions currently believed to be + safe. The list is included in each directory, and nodes which pull down the + directory learn whether they need to upgrade. This option can appear + multiple times: the values from multiple lines are spliced together. When + this is set then VersioningAuthoritativeDirectory should be set too. +

+
+
+RecommendedClientVersions STRING +
+
+

+ STRING is a comma-separated list of Tor versions currently believed to be + safe for clients to use. This information is included in version 2 + directories. If this is not set then the value of RecommendedVersions + is used. When this is set then VersioningAuthoritativeDirectory should + be set too. +

+
+
+RecommendedServerVersions STRING +
+
+

+ STRING is a comma-separated list of Tor versions currently believed to be + safe for servers to use. This information is included in version 2 + directories. If this is not set then the value of RecommendedVersions + is used. When this is set then VersioningAuthoritativeDirectory should + be set too. +

+
+
+ConsensusParams STRING +
+
+

+ STRING is a space-separated list of key=value pairs that Tor will include + in the "params" line of its networkstatus vote. +

+
+
+DirAllowPrivateAddresses 0|1 +
+
+

+ If set to 1, Tor will accept router descriptors with arbitrary "Address" + elements. Otherwise, if the address is not an IP address or is a private IP + address, it will reject the router descriptor. Defaults to 0. +

+
+
+AuthDirBadDir AddressPattern… +
+
+

+ Authoritative directories only. A set of address patterns for servers that + will be listed as bad directories in any network status document this + authority publishes, if AuthDirListBadDirs is set. +

+
+
+AuthDirBadExit AddressPattern… +
+
+

+ Authoritative directories only. A set of address patterns for servers that + will be listed as bad exits in any network status document this authority + publishes, if AuthDirListBadExits is set. +

+
+
+AuthDirInvalid AddressPattern… +
+
+

+ Authoritative directories only. A set of address patterns for servers that + will never be listed as "valid" in any network status document that this + authority publishes. +

+
+
+AuthDirReject AddressPattern… +
+
+

+ Authoritative directories only. A set of address patterns for servers that + will never be listed at all in any network status document that this + authority publishes, or accepted as an OR address in any descriptor + submitted for publication by this authority. +

+
+
+AuthDirListBadDirs 0|1 +
+
+

+ Authoritative directories only. If set to 1, this directory has some + opinion about which nodes are unsuitable as directory caches. (Do not set + this to 1 unless you plan to list non-functioning directories as bad; + otherwise, you are effectively voting in favor of every declared + directory.) +

+
+
+AuthDirListBadExits 0|1 +
+
+

+ Authoritative directories only. If set to 1, this directory has some + opinion about which nodes are unsuitable as exit nodes. (Do not set this to + 1 unless you plan to list non-functioning exits as bad; otherwise, you are + effectively voting in favor of every declared exit as an exit.) +

+
+
+AuthDirRejectUnlisted 0|1 +
+
+

+ Authoritative directories only. If set to 1, the directory server rejects + all uploaded server descriptors that aren’t explicitly listed in the + fingerprints file. This acts as a "panic button" if we get hit with a Sybil + attack. (Default: 0) +

+
+
+AuthDirMaxServersPerAddr NUM +
+
+

+ Authoritative directories only. The maximum number of servers that we will + list as acceptable on a single IP address. Set this to "0" for "no limit". + (Default: 2) +

+
+
+AuthDirMaxServersPerAuthAddr NUM +
+
+

+ Authoritative directories only. Like AuthDirMaxServersPerAddr, but applies + to addresses shared with directory authorities. (Default: 5) +

+
+
+AuthDirFastGuarantee N bytes|KB|MB|GB +
+
+

+ Authoritative directories only. If non-zero, always vote the + Fast flag for any relay advertising this amount of capacity or + more. (Default: 20 KB) +

+
+
+AuthDirGuardBWGuarantee N bytes|KB|MB|GB +
+
+

+ Authoritative directories only. If non-zero, this advertised capacity + or more is always sufficient to satisfy the bandwidth requirement + for the Guard flag. (Default: 250 KB) +

+
+
+BridgePassword Password +
+
+

+ If set, contains an HTTP authenticator that tells a bridge authority to + serve all requested bridge information. Used for debugging. (Default: + not set.) +

+
+
+V3AuthVotingInterval N minutes|hours +
+
+

+ V3 authoritative directories only. Configures the server’s preferred voting + interval. Note that voting will actually happen at an interval chosen + by consensus from all the authorities' preferred intervals. This time + SHOULD divide evenly into a day. (Default: 1 hour) +

+
+
+V3AuthVoteDelay N minutes|hours +
+
+

+ V3 authoritative directories only. Configures the server’s preferred delay + between publishing its vote and assuming it has all the votes from all the + other authorities. Note that the actual time used is not the server’s + preferred time, but the consensus of all preferences. (Default: 5 minutes.) +

+
+
+V3AuthDistDelay N minutes|hours +
+
+

+ V3 authoritative directories only. Configures the server’s preferred delay + between publishing its consensus and signature and assuming it has all the + signatures from all the other authorities. Note that the actual time used + is not the server’s preferred time, but the consensus of all preferences. + (Default: 5 minutes.) +

+
+
+V3AuthNIntervalsValid NUM +
+
+

+ V3 authoritative directories only. Configures the number of VotingIntervals + for which each consensus should be valid for. Choosing high numbers + increases network partitioning risks; choosing low numbers increases + directory traffic. Note that the actual number of intervals used is not the + server’s preferred number, but the consensus of all preferences. Must be at + least 2. (Default: 3.) +

+
+
+V3BandwidthsFile FILENAME +
+
+

+ V3 authoritative directories only. Configures the location of the + bandiwdth-authority generated file storing information on relays' measured + bandwidth capacities. (Default: unset.) +

+
+
+V3AuthUseLegacyKey 0|1 +
+
+

+ If set, the directory authority will sign consensuses not only with its + own signing key, but also with a "legacy" key and certificate with a + different identity. This feature is used to migrate directory authority + keys in the event of a compromise. (Default: 0.) +

+
+
+RephistTrackTime N seconds|minutes|hours|days|weeks +
+
+

+ Tells an authority, or other node tracking node reliability and history, + that fine-grained information about nodes can be discarded when it hasn’t + changed for a given amount of time. (Default: 24 hours) +

+
+
+VoteOnHidServDirectoriesV2 0|1 +
+
+

+ When this option is set in addition to AuthoritativeDirectory, Tor + votes on whether to accept relays as hidden service directories. + (Default: 1) +

+
+
+
+

HIDDEN SERVICE OPTIONS

+
+

The following options are used to configure a hidden service.

+
+
+HiddenServiceDir DIRECTORY +
+
+

+ Store data files for a hidden service in DIRECTORY. Every hidden service + must have a separate directory. You may use this option multiple times to + specify multiple services. DIRECTORY must be an existing directory. +

+
+
+HiddenServicePort VIRTPORT [TARGET] +
+
+

+ Configure a virtual port VIRTPORT for a hidden service. You may use this + option multiple times; each time applies to the service using the most + recent hiddenservicedir. By default, this option maps the virtual port to + the same port on 127.0.0.1. You may override the target port, address, or + both by specifying a target of addr, port, or addr:port. You may also have + multiple lines with the same VIRTPORT: when a user connects to that + VIRTPORT, one of the TARGETs from those lines will be chosen at random. +

+
+
+PublishHidServDescriptors 0|1 +
+
+

+ If set to 0, Tor will run any hidden services you configure, but it won’t + advertise them to the rendezvous directory. This option is only useful if + you’re using a Tor controller that handles hidserv publishing for you. + (Default: 1) +

+
+
+HiddenServiceVersion version,version, +
+
+

+ A list of rendezvous service descriptor versions to publish for the hidden + service. Currently, only version 2 is supported. (Default: 2) +

+
+
+HiddenServiceAuthorizeClient auth-type client-name,client-name, +
+
+

+ If configured, the hidden service is accessible for authorized clients + only. The auth-type can either be 'basic' for a general-purpose + authorization protocol or 'stealth' for a less scalable protocol that also + hides service activity from unauthorized clients. Only clients that are + listed here are authorized to access the hidden service. Valid client names + are 1 to 19 characters long and only use characters in A-Za-z0-9+-_ (no + spaces). If this option is set, the hidden service is not accessible for + clients without authorization any more. Generated authorization data can be + found in the hostname file. Clients need to put this authorization data in + their configuration file using HidServAuth. +

+
+
+RendPostPeriod N seconds|minutes|hours|days|weeks +
+
+

+ Every time the specified period elapses, Tor uploads any rendezvous + service descriptors to the directory servers. This information is also + uploaded whenever it changes. (Default: 1 hour) +

+
+
+
+

TESTING NETWORK OPTIONS

+
+

The following options are used for running a testing Tor network.

+
+
+TestingTorNetwork 0|1 +
+
+

+ If set to 1, Tor adjusts default values of the configuration options below, + so that it is easier to set up a testing Tor network. May only be set if + non-default set of DirServers is set. Cannot be unset while Tor is running. + (Default: 0)
+

+
+
+
ServerDNSAllowBrokenConfig 1
+DirAllowPrivateAddresses 1
+EnforceDistinctSubnets 0
+AssumeReachable 1
+AuthDirMaxServersPerAddr 0
+AuthDirMaxServersPerAuthAddr 0
+ClientDNSRejectInternalAddresses 0
+ClientRejectInternalAddresses 0
+ExitPolicyRejectPrivate 0
+V3AuthVotingInterval 5 minutes
+V3AuthVoteDelay 20 seconds
+V3AuthDistDelay 20 seconds
+MinUptimeHidServDirectoryV2 0 seconds
+TestingV3AuthInitialVotingInterval 5 minutes
+TestingV3AuthInitialVoteDelay 20 seconds
+TestingV3AuthInitialDistDelay 20 seconds
+TestingAuthDirTimeToLearnReachability 0 minutes
+TestingEstimatedDescriptorPropagationTime 0 minutes
+
+
+
+TestingV3AuthInitialVotingInterval N minutes|hours +
+
+

+ Like V3AuthVotingInterval, but for initial voting interval before the first + consensus has been created. Changing this requires that + TestingTorNetwork is set. (Default: 30 minutes) +

+
+
+TestingV3AuthInitialVoteDelay N minutes|hours +
+
+

+ Like TestingV3AuthInitialVoteDelay, but for initial voting interval before + the first consensus has been created. Changing this requires that + TestingTorNetwork is set. (Default: 5 minutes) +

+
+
+TestingV3AuthInitialDistDelay N minutes|hours +
+
+

+ Like TestingV3AuthInitialDistDelay, but for initial voting interval before + the first consensus has been created. Changing this requires that + TestingTorNetwork is set. (Default: 5 minutes) +

+
+
+TestingAuthDirTimeToLearnReachability N minutes|hours +
+
+

+ After starting as an authority, do not make claims about whether routers + are Running until this much time has passed. Changing this requires + that TestingTorNetwork is set. (Default: 30 minutes) +

+
+
+TestingEstimatedDescriptorPropagationTime N minutes|hours +
+
+

+ Clients try downloading router descriptors from directory caches after this + time. Changing this requires that TestingTorNetwork is set. (Default: + 10 minutes) +

+
+
+
+

SIGNALS

+
+

Tor catches the following signals:

+
+
+SIGTERM +
+
+

+ Tor will catch this, clean up and sync to disk if necessary, and exit. +

+
+
+SIGINT +
+
+

+ Tor clients behave as with SIGTERM; but Tor servers will do a controlled + slow shutdown, closing listeners and waiting 30 seconds before exiting. + (The delay can be configured with the ShutdownWaitLength config option.) +

+
+
+SIGHUP +
+
+

+ The signal instructs Tor to reload its configuration (including closing and + reopening logs), and kill and restart its helper processes if applicable. +

+
+
+SIGUSR1 +
+
+

+ Log statistics about current connections, past connections, and throughput. +

+
+
+SIGUSR2 +
+
+

+ Switch all logs to loglevel debug. You can go back to the old loglevels by + sending a SIGHUP. +

+
+
+SIGCHLD +
+
+

+ Tor receives this signal when one of its helper processes has exited, so it + can clean up. +

+
+
+SIGPIPE +
+
+

+ Tor catches this signal and ignores it. +

+
+
+SIGXFSZ +
+
+

+ If this signal exists on your platform, Tor catches and ignores it. +

+
+
+
+

FILES

+
+
+
+/etc/tor/torrc +
+
+

+ The configuration file, which contains "option value" pairs. +

+
+
+/var/lib/tor/ +
+
+

+ The tor process stores keys and other data here. +

+
+
+DataDirectory/cached-status/ +
+
+

+ The most recently downloaded network status document for each authority. + Each file holds one such document; the filenames are the hexadecimal + identity key fingerprints of the directory authorities. +

+
+
+DataDirectory/cached-descriptors and cached-descriptors.new +
+
+

+ These files hold downloaded router statuses. Some routers may appear more + than once; if so, the most recently published descriptor is used. Lines + beginning with @-signs are annotations that contain more information about + a given router. The ".new" file is an append-only journal; when it gets + too large, all entries are merged into a new cached-descriptors file. +

+
+
+DataDirectory/cached-routers and cached-routers.new +
+
+

+ Obsolete versions of cached-descriptors and cached-descriptors.new. When + Tor can’t find the newer files, it looks here instead. +

+
+
+DataDirectory/state +
+
+

+ A set of persistent key-value mappings. These are documented in + the file. These include: +

+
    +
  • +

    +The current entry guards and their status. +

    +
  • +
  • +

    +The current bandwidth accounting values (unused so far; see + below). +

    +
  • +
  • +

    +When the file was last written +

    +
  • +
  • +

    +What version of Tor generated the state file +

    +
  • +
  • +

    +A short history of bandwidth usage, as produced in the router + descriptors. +

    +
  • +
+
+
+DataDirectory/bw_accounting +
+
+

+ Used to track bandwidth accounting values (when the current period starts + and ends; how much has been read and written so far this period). This file + is obsolete, and the data is now stored in the 'state' file as well. Only + used when bandwidth accounting is enabled. +

+
+
+DataDirectory/control_auth_cookie +
+
+

+ Used for cookie authentication with the controller. Location can be + overridden by the CookieAuthFile config option. Regenerated on startup. See + control-spec.txt for details. Only used when cookie authentication is + enabled. +

+
+
+DataDirectory/keys/* +
+
+

+ Only used by servers. Holds identity keys and onion keys. +

+
+
+DataDirectory/fingerprint +
+
+

+ Only used by servers. Holds the fingerprint of the server’s identity key. +

+
+
+DataDirectory/approved-routers +
+
+

+ Only for naming authoritative directory servers (see + NamingAuthoritativeDirectory). This file lists nickname to identity + bindings. Each line lists a nickname and a fingerprint separated by + whitespace. See your fingerprint file in the DataDirectory for an + example line. If the nickname is !reject then descriptors from the + given identity (fingerprint) are rejected by this server. If it is + !invalid then descriptors are accepted but marked in the directory as + not valid, that is, not recommended. +

+
+
+DataDirectory/router-stability +
+
+

+ Only used by authoritative directory servers. Tracks measurements for + router mean-time-between-failures so that authorities have a good idea of + how to set their Stable flags. +

+
+
+HiddenServiceDirectory/hostname +
+
+

+ The <base32-encoded-fingerprint>.onion domain name for this hidden service. + If the hidden service is restricted to authorized clients only, this file + also contains authorization data for all clients. +

+
+
+HiddenServiceDirectory/private_key +
+
+

+ The private key for this hidden service. +

+
+
+HiddenServiceDirectory/client_keys +
+
+

+ Authorization data for a hidden service that is only accessible by + authorized clients. +

+
+
+
+

SEE ALSO

+
+

privoxy(1), tsocks(1), torify(1)

+

https://www.torproject.org/

+
+

BUGS

+
+

Plenty, probably. Tor is still in development. Please report them.

+
+

AUTHORS

+
+

Roger Dingledine [arma at mit.edu], Nick Mathewson [nickm at alum.mit.edu].

+
+ + + diff --git a/puppet/modules/tor/manifests/arm.pp b/puppet/modules/tor/manifests/arm.pp new file mode 100644 index 00000000..44ddcbbf --- /dev/null +++ b/puppet/modules/tor/manifests/arm.pp @@ -0,0 +1,9 @@ +# manage tor-arm +class tor::arm ( + $ensure_version = 'installed' +){ + include ::tor + package{'tor-arm': + ensure => $ensure_version, + } +} diff --git a/puppet/modules/tor/manifests/base.pp b/puppet/modules/tor/manifests/base.pp new file mode 100644 index 00000000..b98451be --- /dev/null +++ b/puppet/modules/tor/manifests/base.pp @@ -0,0 +1,14 @@ +# basic management of resources for tor +class tor::base { + package { [ 'tor', 'tor-geoipdb' ]: + ensure => $tor::ensure_version, + } + + service { 'tor': + ensure => running, + enable => true, + hasrestart => true, + hasstatus => true, + require => Package['tor'], + } +} diff --git a/puppet/modules/tor/manifests/compact.pp b/puppet/modules/tor/manifests/compact.pp new file mode 100644 index 00000000..c0f59199 --- /dev/null +++ b/puppet/modules/tor/manifests/compact.pp @@ -0,0 +1,7 @@ +# manage a complete tor +# installation with all the basics +class tor::compact { + include ::tor + include tor::polipo + include tor::torsocks +} diff --git a/puppet/modules/tor/manifests/daemon.pp b/puppet/modules/tor/manifests/daemon.pp new file mode 100644 index 00000000..2522b2cc --- /dev/null +++ b/puppet/modules/tor/manifests/daemon.pp @@ -0,0 +1,22 @@ +# manage a snippet based tor installation +class tor::daemon ( + $ensure_version = 'installed', + $use_munin = false, + $data_dir = '/var/lib/tor', + $config_file = '/etc/tor/torrc', + $use_bridges = 0, + $automap_hosts_on_resolve = 0, + $log_rules = [ 'notice file /var/log/tor/notices.log' ], + $safe_logging = 1, +) { + + class{'tor': + ensure_version => $ensure_version, + } + + include tor::daemon::base + + if $use_munin { + include tor::munin + } +} diff --git a/puppet/modules/tor/manifests/daemon/base.pp b/puppet/modules/tor/manifests/daemon/base.pp new file mode 100644 index 00000000..63d7bc4d --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/base.pp @@ -0,0 +1,77 @@ +# extend basic tor things with a snippet based daemon configuration +class tor::daemon::base inherits tor::base { + # packages, user, group + Service['tor'] { + subscribe => File[$tor::daemon::config_file], + } + + Package[ 'tor' ] { + require => File[$tor::daemon::data_dir], + } + + group { 'debian-tor': + ensure => present, + allowdupe => false, + } + + user { 'debian-tor': + ensure => present, + allowdupe => false, + comment => 'tor user,,,', + home => $tor::daemon::data_dir, + shell => '/bin/false', + gid => 'debian-tor', + require => Group['debian-tor'], + } + + # directories + file { $tor::daemon::data_dir: + ensure => directory, + mode => '0700', + owner => 'debian-tor', + group => 'debian-tor', + require => User['debian-tor'], + } + + file { '/etc/tor': + ensure => directory, + mode => '0755', + owner => 'debian-tor', + group => 'debian-tor', + require => User['debian-tor'], + } + + file { '/var/lib/puppet/modules/tor': + ensure => absent, + recurse => true, + force => true, + } + + # tor configuration file + concat { $tor::daemon::config_file: + mode => '0600', + owner => 'debian-tor', + group => 'debian-tor', + } + + # config file headers + concat::fragment { '00.header': + ensure => present, + content => template('tor/torrc.header.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => 00, + target => $tor::daemon::config_file, + } + + # global configurations + concat::fragment { '01.global': + content => template('tor/torrc.global.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => 01, + target => $tor::daemon::config_file, + } +} diff --git a/puppet/modules/tor/manifests/daemon/bridge.pp b/puppet/modules/tor/manifests/daemon/bridge.pp new file mode 100644 index 00000000..063f5656 --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/bridge.pp @@ -0,0 +1,18 @@ +# Bridge definition +define tor::daemon::bridge( + $ip, + $port, + $fingerprint = false, + $ensure = present ) { + + concat::fragment { "10.bridge.${name}": + ensure => $ensure, + content => template('tor/torrc.bridge.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => 10, + target => $tor::daemon::config_file, + } +} + diff --git a/puppet/modules/tor/manifests/daemon/control.pp b/puppet/modules/tor/manifests/daemon/control.pp new file mode 100644 index 00000000..01726562 --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/control.pp @@ -0,0 +1,27 @@ +# control definition +define tor::daemon::control( + $port = 0, + $hashed_control_password = '', + $cookie_authentication = 0, + $cookie_auth_file = '', + $cookie_auth_file_group_readable = '', + $ensure = present ) { + + if $cookie_authentication == '0' and $hashed_control_password == '' and $ensure != 'absent' { + fail('You need to define the tor control password') + } + + if $cookie_authentication == 0 and ($cookie_auth_file != '' or $cookie_auth_file_group_readable != '') { + notice('You set a tor cookie authentication option, but do not have cookie_authentication on') + } + + concat::fragment { '04.control': + ensure => $ensure, + content => template('tor/torrc.control.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0600', + order => 04, + target => $tor::daemon::config_file, + } +} diff --git a/puppet/modules/tor/manifests/daemon/directory.pp b/puppet/modules/tor/manifests/daemon/directory.pp new file mode 100644 index 00000000..d877a861 --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/directory.pp @@ -0,0 +1,27 @@ +# directory advertising +define tor::daemon::directory ( + $port = 0, + $listen_addresses = [], + $port_front_page = '/etc/tor/tor-exit-notice.html', + $ensure = present ) { + + concat::fragment { '06.directory': + ensure => $ensure, + content => template('tor/torrc.directory.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => 06, + target => $tor::daemon::config_file, + } + + file { '/etc/tor/tor-exit-notice.html': + ensure => $ensure, + source => 'puppet:///modules/tor/tor-exit-notice.html', + require => File['/etc/tor'], + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + } +} + diff --git a/puppet/modules/tor/manifests/daemon/dns.pp b/puppet/modules/tor/manifests/daemon/dns.pp new file mode 100644 index 00000000..4677f24d --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/dns.pp @@ -0,0 +1,17 @@ +# DNS definition +define tor::daemon::dns( + $port = 0, + $listen_addresses = [], + $ensure = present ) { + + concat::fragment { "08.dns.${name}": + ensure => $ensure, + content => template('tor/torrc.dns.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => '08', + target => $tor::daemon::config_file, + } +} + diff --git a/puppet/modules/tor/manifests/daemon/exit_policy.pp b/puppet/modules/tor/manifests/daemon/exit_policy.pp new file mode 100644 index 00000000..f459ece7 --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/exit_policy.pp @@ -0,0 +1,18 @@ +# exit policies +define tor::daemon::exit_policy( + $accept = [], + $reject = [], + $reject_private = 1, + $ensure = present ) { + + concat::fragment { "07.exit_policy.${name}": + ensure => $ensure, + content => template('tor/torrc.exit_policy.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => 07, + target => $tor::daemon::config_file, + } +} + diff --git a/puppet/modules/tor/manifests/daemon/hidden_service.pp b/puppet/modules/tor/manifests/daemon/hidden_service.pp new file mode 100644 index 00000000..c8272116 --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/hidden_service.pp @@ -0,0 +1,17 @@ +# hidden services definition +define tor::daemon::hidden_service( + $ports = [], + $data_dir = $tor::daemon::data_dir, + $ensure = present ) { + + concat::fragment { "05.hidden_service.${name}": + ensure => $ensure, + content => template('tor/torrc.hidden_service.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => 05, + target => $tor::daemon::config_file, + } +} + diff --git a/puppet/modules/tor/manifests/daemon/map_address.pp b/puppet/modules/tor/manifests/daemon/map_address.pp new file mode 100644 index 00000000..270eac21 --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/map_address.pp @@ -0,0 +1,17 @@ +# map address definition +define tor::daemon::map_address( + $address = '', + $newaddress = '', + $ensure = 'present') { + + concat::fragment { "08.map_address.${name}": + ensure => $ensure, + content => template('tor/torrc.map_address.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => '08', + target => $tor::daemon::config_file, + } +} + diff --git a/puppet/modules/tor/manifests/daemon/relay.pp b/puppet/modules/tor/manifests/daemon/relay.pp new file mode 100644 index 00000000..ff528937 --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/relay.pp @@ -0,0 +1,42 @@ +# relay definition +define tor::daemon::relay( + $port = 0, + $listen_addresses = [], + $outbound_bindaddresses = [], + $portforwarding = 0, + # KB/s, defaulting to using tor's default: 5120KB/s + $bandwidth_rate = '', + # KB/s, defaulting to using tor's default: 10240KB/s + $bandwidth_burst = '', + # KB/s, 0 for no limit + $relay_bandwidth_rate = 0, + # KB/s, 0 for no limit + $relay_bandwidth_burst = 0, + # GB, 0 for no limit + $accounting_max = 0, + $accounting_start = [], + $contact_info = '', + # TODO: autofill with other relays + $my_family = '', + $address = "tor.${::domain}", + $bridge_relay = 0, + $ensure = present ) { + + $nickname = $name + + if $outbound_bindaddresses == [] { + $real_outbound_bindaddresses = [] + } else { + $real_outbound_bindaddresses = $outbound_bindaddresses + } + + concat::fragment { '03.relay': + ensure => $ensure, + content => template('tor/torrc.relay.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => 03, + target => $tor::daemon::config_file, + } +} diff --git a/puppet/modules/tor/manifests/daemon/snippet.pp b/puppet/modules/tor/manifests/daemon/snippet.pp new file mode 100644 index 00000000..b9089b40 --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/snippet.pp @@ -0,0 +1,16 @@ +# Arbitrary torrc snippet definition +define tor::daemon::snippet( + $content = '', + $ensure = present ) { + + concat::fragment { "99.snippet.${name}": + ensure => $ensure, + content => $content, + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => 99, + target => $tor::daemon::config_file, + } +} + diff --git a/puppet/modules/tor/manifests/daemon/socks.pp b/puppet/modules/tor/manifests/daemon/socks.pp new file mode 100644 index 00000000..910461c9 --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/socks.pp @@ -0,0 +1,15 @@ +# socks definition +define tor::daemon::socks( + $port = 0, + $listen_addresses = [], + $policies = [] ) { + + concat::fragment { '02.socks': + content => template('tor/torrc.socks.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => 02, + target => $tor::daemon::config_file, + } +} diff --git a/puppet/modules/tor/manifests/daemon/transparent.pp b/puppet/modules/tor/manifests/daemon/transparent.pp new file mode 100644 index 00000000..65d744f4 --- /dev/null +++ b/puppet/modules/tor/manifests/daemon/transparent.pp @@ -0,0 +1,17 @@ +# Transparent proxy definition +define tor::daemon::transparent( + $port = 0, + $listen_addresses = [], + $ensure = present ) { + + concat::fragment { "09.transparent.${name}": + ensure => $ensure, + content => template('tor/torrc.transparent.erb'), + owner => 'debian-tor', + group => 'debian-tor', + mode => '0644', + order => '09', + target => $tor::daemon::config_file, + } +} + diff --git a/puppet/modules/tor/manifests/init.pp b/puppet/modules/tor/manifests/init.pp new file mode 100644 index 00000000..9c19c648 --- /dev/null +++ b/puppet/modules/tor/manifests/init.pp @@ -0,0 +1,6 @@ +# manage a basic tor installation +class tor ( + $ensure_version = 'installed' +){ + include tor::base +} diff --git a/puppet/modules/tor/manifests/munin.pp b/puppet/modules/tor/manifests/munin.pp new file mode 100644 index 00000000..4412337a --- /dev/null +++ b/puppet/modules/tor/manifests/munin.pp @@ -0,0 +1,21 @@ +# munin plugins for puppet +class tor::munin { + tor::daemon::control{ + 'control_port_for_munin': + port => 19051, + cookie_authentication => 1, + cookie_auth_file => '/var/run/tor/control.authcookie', + } + + Munin::Plugin::Deploy { + config => "user debian-tor\n env.cookiefile /var/run/tor/control.authcookie\n env.port 19051" + } + munin::plugin::deploy { + 'tor_connections': + source => 'tor/munin/tor_connections'; + 'tor_routers': + source => 'tor/munin/tor_routers'; + 'tor_traffic': + source => 'tor/munin/tor_traffic'; + } +} diff --git a/puppet/modules/tor/manifests/polipo.pp b/puppet/modules/tor/manifests/polipo.pp new file mode 100644 index 00000000..73dc2262 --- /dev/null +++ b/puppet/modules/tor/manifests/polipo.pp @@ -0,0 +1,9 @@ +# manage the polipo proxy service +class tor::polipo { + include ::tor + + case $::operatingsystem { + 'debian': { include tor::polipo::debian } + default: { include tor::polipo::base } + } +} diff --git a/puppet/modules/tor/manifests/polipo/base.pp b/puppet/modules/tor/manifests/polipo/base.pp new file mode 100644 index 00000000..df2d6ea6 --- /dev/null +++ b/puppet/modules/tor/manifests/polipo/base.pp @@ -0,0 +1,22 @@ +# manage polipo resources +class tor::polipo::base { + package{'polipo': + ensure => present, + } + + file { '/etc/polipo/config': + ensure => present, + owner => root, + group => root, + mode => '0644', + source => 'puppet:///modules/tor/polipo/polipo.conf', + require => Package['polipo'], + notify => Service['polipo'], + } + + service { 'polipo': + ensure => running, + enable => true, + require => [ Package['polipo'], Service['tor'] ], + } +} diff --git a/puppet/modules/tor/manifests/polipo/debian.pp b/puppet/modules/tor/manifests/polipo/debian.pp new file mode 100644 index 00000000..607b3617 --- /dev/null +++ b/puppet/modules/tor/manifests/polipo/debian.pp @@ -0,0 +1,7 @@ +# manage polipo on debian +class tor::polipo::debian inherits tor::polipo::base { + Service['polipo'] { + hasstatus => false, + pattern => '/usr/bin/polipo', + } +} diff --git a/puppet/modules/tor/manifests/repo.pp b/puppet/modules/tor/manifests/repo.pp new file mode 100644 index 00000000..f6255995 --- /dev/null +++ b/puppet/modules/tor/manifests/repo.pp @@ -0,0 +1,16 @@ +class tor::repo ( + $ensure = present, + $source_name = 'torproject.org', + $include_src = false, +) { + case $::osfamily { + 'Debian': { + $key = '886DDD89' + $location = 'https://deb.torproject.org/torproject.org/' + class { 'tor::repo::debian': } + } + default: { + fail("Unsupported managed repository for osfamily: ${::osfamily}, operatingsystem: ${::operatingsystem}, module ${module_name} currently only supports managing repos for osfamily Debian and Ubuntu") + } + } +} diff --git a/puppet/modules/tor/manifests/repo/debian.pp b/puppet/modules/tor/manifests/repo/debian.pp new file mode 100644 index 00000000..174c3310 --- /dev/null +++ b/puppet/modules/tor/manifests/repo/debian.pp @@ -0,0 +1,9 @@ +# PRIVATE CLASS: do not use directly +class tor::repo::debian inherits tor::repo { + apt::source { $source_name: + ensure => $::tor::repo::ensure, + location => $::tor::repo::location, + key => $::tor::repo::key, + include_src => $::tor::repo::include_src, + } +} diff --git a/puppet/modules/tor/manifests/torsocks.pp b/puppet/modules/tor/manifests/torsocks.pp new file mode 100644 index 00000000..e9fc75b2 --- /dev/null +++ b/puppet/modules/tor/manifests/torsocks.pp @@ -0,0 +1,9 @@ +# manage torsocks +class tor::torsocks ( + $ensure_version = 'installed' +){ + include ::tor + package{'torsocks': + ensure => $ensure_version, + } +} diff --git a/puppet/modules/tor/templates/torrc.bridge.erb b/puppet/modules/tor/templates/torrc.bridge.erb new file mode 100644 index 00000000..559ce5df --- /dev/null +++ b/puppet/modules/tor/templates/torrc.bridge.erb @@ -0,0 +1,3 @@ +# Bridge <%= @name %> +Bridge <%= @ip %>:<%= @port %><% if @fingerprint -%> <%= @fingerprint%><% end -%> + diff --git a/puppet/modules/tor/templates/torrc.control.erb b/puppet/modules/tor/templates/torrc.control.erb new file mode 100644 index 00000000..0b68faff --- /dev/null +++ b/puppet/modules/tor/templates/torrc.control.erb @@ -0,0 +1,16 @@ +# tor controller +<% if @port != '0' -%> +ControlPort <%= @port %> +<% if @cookie_authentication != '0' -%> +CookieAuthentication 1 +<% if @cookie_auth_file != '' -%> +CookieAuthFile <%= @cookie_auth_file %> +<% end -%> +<% if @cookie_auth_file_group_readable != '' -%> +CookieAuthFileGroupReadable <%= @cookie_auth_file_group_readable %> +<% end -%> +<% else -%> +HashedControlPassword <%= @hashed_control_password %> +<% end -%> +<% end -%> + diff --git a/puppet/modules/tor/templates/torrc.directory.erb b/puppet/modules/tor/templates/torrc.directory.erb new file mode 100644 index 00000000..1af9f40f --- /dev/null +++ b/puppet/modules/tor/templates/torrc.directory.erb @@ -0,0 +1,11 @@ +# directory listing +<% if port != '0' -%> +DirPort <%= @port %> +<% end -%> +<% listen_addresses.each do |listen_address| -%> +DirListenAddress <%= listen_address %> +<% end -%> +<% if @port_front_page != '' -%> +DirPortFrontPage <%= port_front_page %> +<%- end -%> + diff --git a/puppet/modules/tor/templates/torrc.dns.erb b/puppet/modules/tor/templates/torrc.dns.erb new file mode 100644 index 00000000..57cf46d9 --- /dev/null +++ b/puppet/modules/tor/templates/torrc.dns.erb @@ -0,0 +1,5 @@ +# DNS +DNSPort <%= @port %> +<% @listen_addresses.each do |listen_address| -%> +DNSListenAddress <%= listen_address %> +<% end -%> diff --git a/puppet/modules/tor/templates/torrc.exit_policy.erb b/puppet/modules/tor/templates/torrc.exit_policy.erb new file mode 100644 index 00000000..a30d43b8 --- /dev/null +++ b/puppet/modules/tor/templates/torrc.exit_policy.erb @@ -0,0 +1,11 @@ +# exit policies: <%= @name %> +<% if @reject_private != '1' -%> +ExitPolicyRejectPrivate <%= @reject_private %> +<% end -%> +<% @accept.each do |policy| -%> +ExitPolicy accept <%= policy %> +<% end -%> +<% @reject.each do |policy| -%> +ExitPolicy reject <%= policy %> +<% end -%> + diff --git a/puppet/modules/tor/templates/torrc.global.erb b/puppet/modules/tor/templates/torrc.global.erb new file mode 100644 index 00000000..f577673d --- /dev/null +++ b/puppet/modules/tor/templates/torrc.global.erb @@ -0,0 +1,24 @@ +# runtime +RunAsDaemon 1 +<% if (v=scope.lookupvar('tor::daemon::data_dir')) != '/var/lib/tor' -%> +DataDirectory <%= v %> +<% end -%> + +# log +<% if (rules=scope.lookupvar('tor::daemon::log_rules')).empty? -%> +Log notice syslog +<% else -%> +<% rules.each do |log_rule| -%> +Log <%= log_rule %> +<% end -%> +<% end -%> +<%- if @safe_logging != 1 then -%> +SafeLogging <%= @safe_logging %> +<%- end -%> + +<% if (v=scope.lookupvar('tor::daemon::automap_hosts_on_resolve')) != '0' -%> +AutomapHostsOnResolve <%= v %> +<% end -%> +<% if (v=scope.lookupvar('tor::daemon::use_bridges')) != '0' -%> +UseBridges <%= v %> +<%- end -%> diff --git a/puppet/modules/tor/templates/torrc.header.erb b/puppet/modules/tor/templates/torrc.header.erb new file mode 100644 index 00000000..79d6da9d --- /dev/null +++ b/puppet/modules/tor/templates/torrc.header.erb @@ -0,0 +1,2 @@ +# This file is managed by puppet. + diff --git a/puppet/modules/tor/templates/torrc.hidden_service.erb b/puppet/modules/tor/templates/torrc.hidden_service.erb new file mode 100644 index 00000000..4dec0b25 --- /dev/null +++ b/puppet/modules/tor/templates/torrc.hidden_service.erb @@ -0,0 +1,6 @@ +# hidden service <%= @name %> +HiddenServiceDir <%= @data_dir %>/<%= @name %> +<% @ports.each do |port| -%> +HiddenServicePort <%= port %> +<% end -%> + diff --git a/puppet/modules/tor/templates/torrc.map_address.erb b/puppet/modules/tor/templates/torrc.map_address.erb new file mode 100644 index 00000000..ef4f2683 --- /dev/null +++ b/puppet/modules/tor/templates/torrc.map_address.erb @@ -0,0 +1,3 @@ +# map address <%= @name %> +MapAddress <%= @address %> <%= @newaddress %> + diff --git a/puppet/modules/tor/templates/torrc.relay.erb b/puppet/modules/tor/templates/torrc.relay.erb new file mode 100644 index 00000000..a286459f --- /dev/null +++ b/puppet/modules/tor/templates/torrc.relay.erb @@ -0,0 +1,46 @@ +# relay +<% if @port != 0 -%> +ORPort <%= @port %> +<% @listen_addresses.each do |listen_address| -%> +ORListenAddress <%= @listen_address %> +<% end -%> +<% @real_outbound_bindaddresses.each do |outbound_bindaddress| -%> +OutboundBindAddress <%= @outbound_bindaddress %> +<% end -%> +<% if @nickname != '' -%> +Nickname <%= @nickname %> +<% end -%> +<% if @address != '' -%> +Address <%= @address %> +<% end -%> +<% if @portforwarding != '0' -%> +PortForwarding <%= @portforwarding %> +<% end -%> +<% if @bandwidth_rate != '' -%> +BandwidthRate <%= @bandwidth_rate %> KB +<% end -%> +<% if @bandwidth_burst != '' -%> +BandwidthBurst <%= @bandwidth_burst %> KB +<% end -%> +<% if @relay_bandwidth_rate != '0' -%> +RelayBandwidthRate <%= @relay_bandwidth_rate %> KB +<% end -%> +<% if @relay_bandwidth_burst != '0' -%> +RelayBandwidthBurst <%= @relay_bandwidth_burst %> KB +<% end -%> +<% if @accounting_max != '0' -%> +AccountingMax <%= @accounting_max %> GB +<% if @accounting_start -%> +AccountingStart <%= @accounting_start %> +<% end -%> +<% end -%> +<% if @contact_info != '' -%> +ContactInfo <%= @contact_info %> +<% end -%> +<% end -%> +<% if @my_family != '' -%> +MyFamily <%= @my_family %> +<% end -%> +<% if @bridge_relay != '0' -%> +BridgeRelay <%= @bridge_relay %> +<% end -%> diff --git a/puppet/modules/tor/templates/torrc.socks.erb b/puppet/modules/tor/templates/torrc.socks.erb new file mode 100644 index 00000000..4bc3ddc1 --- /dev/null +++ b/puppet/modules/tor/templates/torrc.socks.erb @@ -0,0 +1,9 @@ +# socks +SocksPort <%= @port %> +<% @listen_addresses.each do |listen_address| -%> +SocksListenAddress <%= listen_address %> +<% end -%> +<% @policies.each do |policy| -%> +SocksPolicy <%= policy %> +<% end -%> + diff --git a/puppet/modules/tor/templates/torrc.transparent.erb b/puppet/modules/tor/templates/torrc.transparent.erb new file mode 100644 index 00000000..c683150f --- /dev/null +++ b/puppet/modules/tor/templates/torrc.transparent.erb @@ -0,0 +1,5 @@ +# Transparent proxy +TransPort <%= @port %> +<% @listen_addresses.each do |listen_address| -%> +TransListenAddress <%= listen_address %> +<% end -%> -- cgit v1.2.3 From 04279dd8d1390d61d696d2c14817199304ccd4d8 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:46:21 -0400 Subject: git subrepo clone https://leap.se/git/puppet_stunnel puppet/modules/stunnel subrepo: subdir: "puppet/modules/stunnel" merged: "523612f" upstream: origin: "https://leap.se/git/puppet_stunnel" branch: "master" commit: "523612f" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: If384c84c99d9cabc67d2b4b9d7d2fbfa4a47550a --- puppet/modules/stunnel/.gitrepo | 11 + puppet/modules/stunnel/LICENSE | 674 +++++++++++++++++++++ puppet/modules/stunnel/README | 77 +++ puppet/modules/stunnel/files/CentOS/stunnel.init | 143 +++++ puppet/modules/stunnel/manifests/base.pp | 13 + puppet/modules/stunnel/manifests/centos.pp | 35 ++ puppet/modules/stunnel/manifests/debian.pp | 23 + puppet/modules/stunnel/manifests/init.pp | 65 ++ puppet/modules/stunnel/manifests/linux.pp | 6 + puppet/modules/stunnel/manifests/service.pp | 79 +++ puppet/modules/stunnel/manifests/service/nagios.pp | 12 + puppet/modules/stunnel/templates/Debian/default | 13 + .../stunnel/templates/refresh_stunnel.sh.erb | 22 + puppet/modules/stunnel/templates/service.conf.erb | 47 ++ 14 files changed, 1220 insertions(+) create mode 100644 puppet/modules/stunnel/.gitrepo create mode 100644 puppet/modules/stunnel/LICENSE create mode 100644 puppet/modules/stunnel/README create mode 100644 puppet/modules/stunnel/files/CentOS/stunnel.init create mode 100644 puppet/modules/stunnel/manifests/base.pp create mode 100644 puppet/modules/stunnel/manifests/centos.pp create mode 100644 puppet/modules/stunnel/manifests/debian.pp create mode 100644 puppet/modules/stunnel/manifests/init.pp create mode 100644 puppet/modules/stunnel/manifests/linux.pp create mode 100644 puppet/modules/stunnel/manifests/service.pp create mode 100644 puppet/modules/stunnel/manifests/service/nagios.pp create mode 100644 puppet/modules/stunnel/templates/Debian/default create mode 100644 puppet/modules/stunnel/templates/refresh_stunnel.sh.erb create mode 100644 puppet/modules/stunnel/templates/service.conf.erb (limited to 'puppet/modules') diff --git a/puppet/modules/stunnel/.gitrepo b/puppet/modules/stunnel/.gitrepo new file mode 100644 index 00000000..d7540f10 --- /dev/null +++ b/puppet/modules/stunnel/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_stunnel + branch = master + commit = 523612fb6daff51837423619f5014e62dc835559 + parent = 297fadc8e6ad4729589d4ec21683f05a1e50bdf9 + cmdver = 0.3.0 diff --git a/puppet/modules/stunnel/LICENSE b/puppet/modules/stunnel/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/puppet/modules/stunnel/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/puppet/modules/stunnel/README b/puppet/modules/stunnel/README new file mode 100644 index 00000000..b6a3124c --- /dev/null +++ b/puppet/modules/stunnel/README @@ -0,0 +1,77 @@ +Overview +======== + +This module manages stunnel4. It installs and configures the software, makes +sure it is running, and enables you to create different stunnels. + + +! Upgrade Notice ! +================== + +Previous versions of this module were not using parameterized classes. If you +were using a previous version, you may need to change how you are using the +module to accomodate for that. If you were previously setting some stunnel +variables before including the class, you will now need to pass those variables +to the class as parameters. If you were just simply doing 'include stunnel', +then you will not need to change anything. + +Classes +======= + +stunnel +------- + +This is the main class which brings you stunnel support. You will need to +instantiate it by doing the following: + +class { 'stunnel': } + +Class parameters: + +* ensure_version - If this parameter is passed, you can force a particular + version of stunnel to be installed, if it is available with your packaging + system, for example: + + class { 'stunnel': ensure_version = '3:4.53-1' } + + If you do not pass this parameter, it will default to just be 'present'. + +* startboot (Debian) - This parameter controls if stunnel should be started at + boot or not, if you do not pass this paramter, by default it will be started + +* default_extra (Debian) - This parameter lets you add arbitrary extra text to + the bottom of /etc/default/stunnel4, this can be useful to set ulimit for + example + + +Defines +======= + +stunnel::service +---------------- + +This define lets you setup any number of stunnels, it allows you to pass every +stunnel configuration variable (see manifests/server.pp) which will be used to +create the /etc/stunnel/${name}.conf file, and then notify the stunnel service +so it will restart. + +If you pass $manage_nagios to this define, it will create a nagios::service +entry for stunnel_${name} which will watch for the appropriate number processes +with that configuration name + +Note that if you need to use some specific logic to decide whether or not to +create a nagios service check, you should set $manage_nagios to false, and +use stunnel::service::nagios from within your own manifests. + +stunnel::service::nagios +------------------------ + +This define creates a nagios service check for a specific tunnel. The resource +name should be the name of the tunnel's configuration file without the '.conf' +suffix. For example: + + stunnel::service::nagios { 'carpal': } + +The above example would verify that the tunnel defined in +`/etc/stunnel/carpal.conf'. + diff --git a/puppet/modules/stunnel/files/CentOS/stunnel.init b/puppet/modules/stunnel/files/CentOS/stunnel.init new file mode 100644 index 00000000..d5c60fd8 --- /dev/null +++ b/puppet/modules/stunnel/files/CentOS/stunnel.init @@ -0,0 +1,143 @@ +#!/bin/bash +# +# Script to run stunnel in daemon mode at boot time. +# +# Check http://www.gaztronics.net/ for the +# most up-to-date version of this script. +# +# This script is realeased under the terms of the GPL. +# You can source a copy at: +# http://www.fsf.org/copyleft/copyleft.html +# +# Please feel free to modify the script to suite your own needs. +# I always welcome email feedback with suggestions for improvements. +# Please do not email for general support. I do not have time to answer +# personal help requests. + +# Author: Gary Myers MIIE MBCS +# email: http://www.gaztronics.net/webform/ +# Revision 1.0 - 4th March 2005 + +#==================================================================== +# Run level information: +# +# chkconfig: 2345 99 99 +# description: Secure Tunnel +# processname: stunnel +# +# Run "/sbin/chkconfig --add stunnel" to add the Run levels. +# This will setup the symlinks and set the process to run at boot. +#==================================================================== + +#==================================================================== +# Paths and variables and system checks. + +# Source function library (It's a Red Hat thing!) +. /etc/rc.d/init.d/functions + +# Check that networking is up. +# +[ ${NETWORKING} ="yes" ] || exit 0 + +# Path to the executable. +# +SEXE=/usr/sbin/stunnel + +# Path to the configuration file. +# +CONF=/etc/stunnel/stunnel.conf + +# Check the configuration file exists. +# +if [ ! -f $CONF ] ; then + echo "The configuration file cannot be found!" +exit 0 +fi + +CHROOT=`grep '^chroot' /etc/stunnel/stunnel.conf | head -n 1 | sed 's/ //g' | awk -F= '{ print $2 }'` +PIDFILE=`grep '^pid' /etc/stunnel/stunnel.conf | head -n 1 | sed 's/ //g' | awk -F= '{ print $2 }'` +if [ -n "$CHROOT" ]; then + PIDFILE=$CHROOT/$PIDFILE +fi + +# Path to the lock file. +# +LOCK_FILE=/var/lock/subsys/stunnel + +#==================================================================== + +#==================================================================== +# Run controls: + +prog=$"stunnel" + +RETVAL=0 + +# Start stunnel as daemon. +# +start() { + if [ -f $LOCK_FILE ]; then + echo "stunnel is already running!" + exit 0 + else + echo -n $"Starting $prog: " + $SEXE $CONF + fi + + RETVAL=$? + [ $RETVAL -eq 0 ] && success + echo + [ $RETVAL -eq 0 ] && touch $LOCK_FILE + return $RETVAL +} + + +# Stop stunnel. +# +stop() { + if [ ! -f $LOCK_FILE ]; then + echo "stunnel is not running!" + exit 0 + + else + + echo -n $"Shutting down $prog: " + killproc -p $PIDFILE stunnel + RETVAL=$? + [ $RETVAL -eq 0 ] + rm -f $LOCK_FILE + echo + return $RETVAL + + fi +} + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + condrestart) + if [ -f $LOCK_FILE ]; then + stop + start + RETVAL=$? + fi + ;; + status) + status -p $PIDFILE stunnel + RETVAL=$? + ;; + *) + echo $"Usage: $0 {start|stop|restart|condrestart|status}" + RETVAL=1 +esac + +exit $RETVAL diff --git a/puppet/modules/stunnel/manifests/base.pp b/puppet/modules/stunnel/manifests/base.pp new file mode 100644 index 00000000..9fed2de7 --- /dev/null +++ b/puppet/modules/stunnel/manifests/base.pp @@ -0,0 +1,13 @@ +class stunnel::base { + + file { '/etc/stunnel': + ensure => directory; + } + + service { 'stunnel': + ensure => running, + name => 'stunnel', + enable => true, + hasstatus => false; + } +} diff --git a/puppet/modules/stunnel/manifests/centos.pp b/puppet/modules/stunnel/manifests/centos.pp new file mode 100644 index 00000000..3b0a6e2a --- /dev/null +++ b/puppet/modules/stunnel/manifests/centos.pp @@ -0,0 +1,35 @@ +class stunnel::centos inherits stunnel::linux { + + file { '/etc/init.d/stunnel': + source => "puppet:///modules/stunnel/${::operatingsystem}/stunnel.init", + require => Package['stunnel'], + before => Service['stunnel'], + owner => root, + group => 0, + mode => '0755'; + } + + user::managed { 'stunnel': + homedir => '/var/run/stunnel', + shell => '/sbin/nologin', + uid => 105, + gid => 105; + } + + Service['stunnel']{ + hasstatus => true, + require => [ User['stunnel'], File['/etc/init.d/stunnel'] ] + } + + file { '/etc/stunnel/stunnel.conf': + source => [ "puppet:///modules/site-stunnel/${::fqdn}/stunnel.conf", + "puppet:///modules/site-stunnel/${stunnel::cluster}/stunnel.conf", + 'puppet:///modules/site-stunnel/stunnel.conf', + "puppet:///modules/stunnel/${::operatingsystem}/stunnel.conf" ], + require => Package['stunnel'], + notify => Service['stunnel'], + owner => root, + group => 0, + mode => '0600'; + } +} diff --git a/puppet/modules/stunnel/manifests/debian.pp b/puppet/modules/stunnel/manifests/debian.pp new file mode 100644 index 00000000..1135b98d --- /dev/null +++ b/puppet/modules/stunnel/manifests/debian.pp @@ -0,0 +1,23 @@ +class stunnel::debian inherits stunnel::linux { + + Package['stunnel'] { + name => 'stunnel4', + } + + Service['stunnel'] { + name => 'stunnel4', + pattern => '/usr/bin/stunnel4', + subscribe => File['/etc/default/stunnel4'], + require => Package['stunnel4'] + } + + file { '/etc/default/stunnel4': + content => template('stunnel/Debian/default'), + before => Package['stunnel4'], + notify => Service['stunnel4'], + owner => root, + group => 0, + mode => '0644'; + } +} + diff --git a/puppet/modules/stunnel/manifests/init.pp b/puppet/modules/stunnel/manifests/init.pp new file mode 100644 index 00000000..544ac04e --- /dev/null +++ b/puppet/modules/stunnel/manifests/init.pp @@ -0,0 +1,65 @@ +# +# stunnel puppet module +# +# Copyright 2009, Riseup Networks +# +# +# This program is free software; you can redistribute +# it and/or modify it under the terms of the GNU +# General Public License version 3 as published by +# the Free Software Foundation. +# +# 1. include stunnel: this will automatically include stunnel::debian, +# which automatically includes stunnel::linux, which automatically +# includes stunnel::base +# 2. stunnel::client allows you to configure different /etc/stunnel/*.conf files +# to provide various stunnel configurations + +# TODO: warn on cert/key issues, fail on false accept? + +class stunnel ( + $ensure_version = 'present', + $startboot = '1', + $default_extra = '', + $cluster = '' ) +{ + + case $::operatingsystem { + debian: { class { 'stunnel::debian': } } + centos: { class { 'stunnel::centos': } } + default: { class { 'stunnel::default': } } + } + + $stunnel_staging = "${::puppet_vardir}/stunnel4" + $stunnel_compdir = "${stunnel_staging}/configs" + + file { + [ $stunnel_staging, "${stunnel_staging}/bin" ]: + ensure => directory, + owner => 0, + group => 0, + mode => '0750'; + + "${stunnel_staging}/configs": + ensure => directory, + owner => 0, + group => 0, + mode => '0750', + recurse => true, + purge => true, + force => true, + source => undef, + notify => Exec['refresh_stunnel']; + + "${stunnel_staging}/bin/refresh_stunnel.sh": + owner => 0, + group => 0, + mode => '0755', + content => template('stunnel/refresh_stunnel.sh.erb'); + } + + exec { 'refresh_stunnel': + command => "${stunnel_staging}/bin/refresh_stunnel.sh", + require => [ Package['stunnel4'], File['/etc/default/stunnel4'] ] + } +} diff --git a/puppet/modules/stunnel/manifests/linux.pp b/puppet/modules/stunnel/manifests/linux.pp new file mode 100644 index 00000000..a4a926e4 --- /dev/null +++ b/puppet/modules/stunnel/manifests/linux.pp @@ -0,0 +1,6 @@ +class stunnel::linux inherits stunnel::base { + + package { 'stunnel': + ensure => $stunnel::ensure_version + } +} diff --git a/puppet/modules/stunnel/manifests/service.pp b/puppet/modules/stunnel/manifests/service.pp new file mode 100644 index 00000000..8a98d8ff --- /dev/null +++ b/puppet/modules/stunnel/manifests/service.pp @@ -0,0 +1,79 @@ +define stunnel::service ( + $ensure = present, + $accept = false, + $capath = false, + $cafile = false, + $cert = false, + $chroot = false, + $ciphers = false, + $client = false, + $compress = false, + $connect = false, + $crlpath = false, + $crlfile = false, + $debuglevel = false, + $delay = false, + $egd = false, + $engine = false, + $engineCtrl = false, + $enginenum = false, + $exec = false, + $execargs = false, + $failover = false, + $ident = false, + $key = false, + $local = false, + $oscp = false, + $ocspflag = false, + $options = false, + $output = false, + $pid = false, + $protocol = false, + $protocolauthentication = false, + $protocolhost = false, + $protocolpassword = false, + $protocolusername = false, + $pty = false, + $retry = false, + $rndbytes = false, + $rndfile = false, + $rndoverwrite = false, + $service = false, + $session = false, + $setuid = 'stunnel4', + $setgid = 'stunnel4', + $socket = [ 'l:TCP_NODELAY=1', 'r:TCP_NODELAY=1'], + $sslversion = 'SSLv3', + $stack = false, + $syslog = false, + $timeoutbusy = false, + $timeoutclose = false, + $timeoutconnect = false, + $timeoutidle = false, + $transparent = false, + $manage_nagios = false, + $verify = false +) { + + include stunnel + + $real_client = $client ? { default => 'yes' } + $real_pid = $pid ? { false => "/${name}.pid", default => $pid } + + $stunnel_compdir = "${::puppet_vardir}/stunnel4/configs" + + file { + "${stunnel_compdir}/${name}.conf": + ensure => $ensure, + content => template('stunnel/service.conf.erb'), + require => Package['stunnel'], + notify => Exec['refresh_stunnel'], + owner => 'root', + group => 0, + mode => '0600'; + } + + if $manage_nagios { + stunnel::service::nagios { $name: } + } +} diff --git a/puppet/modules/stunnel/manifests/service/nagios.pp b/puppet/modules/stunnel/manifests/service/nagios.pp new file mode 100644 index 00000000..578b417e --- /dev/null +++ b/puppet/modules/stunnel/manifests/service/nagios.pp @@ -0,0 +1,12 @@ +# Put a Nagios service check in place for a specific tunnel. +# +# The resource name will be used to point to the corresponding stunnel +# configuration file. +# +define stunnel::service::nagios () { + + nagios::service { "stunnel_${name}": + check_command => "nagios-stat-proc!/usr/bin/stunnel4 /etc/stunnel/${name}.conf!6!5!proc"; + } + +} diff --git a/puppet/modules/stunnel/templates/Debian/default b/puppet/modules/stunnel/templates/Debian/default new file mode 100644 index 00000000..9e2f4d37 --- /dev/null +++ b/puppet/modules/stunnel/templates/Debian/default @@ -0,0 +1,13 @@ +# /etc/default/stunnel +# Julien LEMOINE +# September 2003 + +# Change to one to enable stunnel automatic startup +ENABLED=<%= scope.lookupvar('stunnel::startboot') %> +FILES="/etc/stunnel/*.conf" +OPTIONS="" + +# Change to one to enable ppp restart scripts +PPP_RESTART=0 + +<%= scope.lookupvar('stunnel::default_extra') %> diff --git a/puppet/modules/stunnel/templates/refresh_stunnel.sh.erb b/puppet/modules/stunnel/templates/refresh_stunnel.sh.erb new file mode 100644 index 00000000..1af0cff7 --- /dev/null +++ b/puppet/modules/stunnel/templates/refresh_stunnel.sh.erb @@ -0,0 +1,22 @@ +#!/bin/sh -x + +for difference in `diff -q /etc/stunnel <%= @stunnel_staging %>/configs | grep differ | awk '{print $2}'` +do + old_config=`basename $difference` + /etc/init.d/stunnel4 stop $(basename $old_config .conf) + rm $difference +done + +for only in `diff -q /etc/stunnel <%= @stunnel_staging %>/configs | grep 'Only in /etc/stunnel:' | awk '{print $4}'` +do + old_config=`basename $only` + /etc/init.d/stunnel4 stop $(basename $only .conf) + rm /etc/stunnel/${only} +done + +cp <%= @stunnel_staging %>/configs/*.conf /etc/stunnel + +/etc/init.d/stunnel4 start + + + diff --git a/puppet/modules/stunnel/templates/service.conf.erb b/puppet/modules/stunnel/templates/service.conf.erb new file mode 100644 index 00000000..47f1c9d2 --- /dev/null +++ b/puppet/modules/stunnel/templates/service.conf.erb @@ -0,0 +1,47 @@ +; templated stunnel configuration file to be used by puppet stunnel module +; NOTE: any changes you make to this file will be overwritten the next time +; puppet runs, please make configuration changes to this service in puppet + +; Global configuration options +<%= 'debug = ' + @debuglevel %> +<%= 'pid = ' + @real_pid %> +<%- %w{chroot setuid setgid service compression}.each do |v| + if has_variable?(v) and instance_variable_get("@#{v}").to_s != "false" -%> +<%= v + " = " + instance_variable_get("@#{v}").to_s %> +<%- + end +end -%> + +; Some performance tunings +<% if @socket.is_a? String -%> +<%= 'socket = ' + @socket %> +<% elsif @socket.is_a? Array -%> +<%= @socket.map { |i| "socket = #{i}" }. join("\n") %> +<% end -%> + +<%- %w{output syslog}.each do |v| + if has_variable?(v) and instance_variable_get("@#{v}").to_s != "false" -%> +<%= v + " = " + instance_variable_get("@#{v}").to_s %> +<%- + end +end -%> + +<%- %w{egd engine enginectrl rndbytes rndfile rndoverwrite}.each do |v| + if has_variable?(v) and instance_variable_get("@#{v}").to_s != "false" -%> +<%= v + " = " + instance_variable_get("@#{v}").to_s %> +<%- + end +end -%> + +; Service-level configuration +<%= '[' + @name + ']' %> +<%- %w{accept connect capath cafile cert ciphers crlpath crlfile delay enginenum exec + execargs failover ident key local oscp ocspflag options protocol protocolauthentication + protocolhost protocolpassword protocolusername pty retry session sslversion stack + timeoutbusy timeoutclose timeoutconnect timeoutidle transparent verify}.each do |v| + if has_variable?(v) and instance_variable_get("@#{v}").to_s != "false" -%> +<%= v + ' = ' + instance_variable_get("@#{v}").to_s %> +<%- + end +end -%> +client = <%= @client ? 'yes' : 'no' %> -- cgit v1.2.3 From a658f5c30ada5e03468257f90d08f6cd2ba25488 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:46:22 -0400 Subject: git subrepo clone https://leap.se/git/puppet_haproxy puppet/modules/haproxy subrepo: subdir: "puppet/modules/haproxy" merged: "af322a7" upstream: origin: "https://leap.se/git/puppet_haproxy" branch: "master" commit: "af322a7" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: Iabf2dd01dc00acd7d886420968bda9aab7190770 --- puppet/modules/haproxy/.fixtures.yml | 5 + puppet/modules/haproxy/.gemfile | 5 + puppet/modules/haproxy/.gitrepo | 11 ++ puppet/modules/haproxy/.travis.yml | 23 ++++ puppet/modules/haproxy/CHANGELOG | 5 + puppet/modules/haproxy/Modulefile | 12 ++ puppet/modules/haproxy/README.md | 87 ++++++++++++ puppet/modules/haproxy/Rakefile | 1 + puppet/modules/haproxy/manifests/balancermember.pp | 95 +++++++++++++ puppet/modules/haproxy/manifests/init.pp | 149 +++++++++++++++++++++ puppet/modules/haproxy/manifests/listen.pp | 95 +++++++++++++ puppet/modules/haproxy/manifests/params.pp | 65 +++++++++ .../modules/haproxy/spec/classes/haproxy_spec.rb | 138 +++++++++++++++++++ .../haproxy/spec/defines/balancermember_spec.rb | 82 ++++++++++++ puppet/modules/haproxy/spec/defines/listen_spec.rb | 53 ++++++++ puppet/modules/haproxy/spec/spec.opts | 6 + puppet/modules/haproxy/spec/spec_helper.rb | 1 + .../modules/haproxy/templates/haproxy-base.cfg.erb | 21 +++ .../haproxy/templates/haproxy_balancermember.erb | 3 + .../haproxy/templates/haproxy_listen_block.erb | 10 ++ puppet/modules/haproxy/tests/init.pp | 69 ++++++++++ 21 files changed, 936 insertions(+) create mode 100644 puppet/modules/haproxy/.fixtures.yml create mode 100644 puppet/modules/haproxy/.gemfile create mode 100644 puppet/modules/haproxy/.gitrepo create mode 100644 puppet/modules/haproxy/.travis.yml create mode 100644 puppet/modules/haproxy/CHANGELOG create mode 100644 puppet/modules/haproxy/Modulefile create mode 100644 puppet/modules/haproxy/README.md create mode 100644 puppet/modules/haproxy/Rakefile create mode 100644 puppet/modules/haproxy/manifests/balancermember.pp create mode 100644 puppet/modules/haproxy/manifests/init.pp create mode 100644 puppet/modules/haproxy/manifests/listen.pp create mode 100644 puppet/modules/haproxy/manifests/params.pp create mode 100644 puppet/modules/haproxy/spec/classes/haproxy_spec.rb create mode 100644 puppet/modules/haproxy/spec/defines/balancermember_spec.rb create mode 100644 puppet/modules/haproxy/spec/defines/listen_spec.rb create mode 100644 puppet/modules/haproxy/spec/spec.opts create mode 100644 puppet/modules/haproxy/spec/spec_helper.rb create mode 100644 puppet/modules/haproxy/templates/haproxy-base.cfg.erb create mode 100644 puppet/modules/haproxy/templates/haproxy_balancermember.erb create mode 100644 puppet/modules/haproxy/templates/haproxy_listen_block.erb create mode 100644 puppet/modules/haproxy/tests/init.pp (limited to 'puppet/modules') diff --git a/puppet/modules/haproxy/.fixtures.yml b/puppet/modules/haproxy/.fixtures.yml new file mode 100644 index 00000000..8d6f22d6 --- /dev/null +++ b/puppet/modules/haproxy/.fixtures.yml @@ -0,0 +1,5 @@ +fixtures: + repositories: + concat: "git://github.com/ripienaar/puppet-concat.git" + symlinks: + haproxy: "#{source_dir}" diff --git a/puppet/modules/haproxy/.gemfile b/puppet/modules/haproxy/.gemfile new file mode 100644 index 00000000..9aad840c --- /dev/null +++ b/puppet/modules/haproxy/.gemfile @@ -0,0 +1,5 @@ +source :rubygems + +puppetversion = ENV.key?('PUPPET_VERSION') ? "= #{ENV['PUPPET_VERSION']}" : ['>= 2.7'] +gem 'puppet', puppetversion +gem 'puppetlabs_spec_helper', '>= 0.1.0' diff --git a/puppet/modules/haproxy/.gitrepo b/puppet/modules/haproxy/.gitrepo new file mode 100644 index 00000000..ed92831a --- /dev/null +++ b/puppet/modules/haproxy/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_haproxy + branch = master + commit = af322a73c013f80a958ab7d5d31d0c75cf6d0523 + parent = 04279dd8d1390d61d696d2c14817199304ccd4d8 + cmdver = 0.3.0 diff --git a/puppet/modules/haproxy/.travis.yml b/puppet/modules/haproxy/.travis.yml new file mode 100644 index 00000000..fdbc95dc --- /dev/null +++ b/puppet/modules/haproxy/.travis.yml @@ -0,0 +1,23 @@ +language: ruby +rvm: + - 1.8.7 + - 1.9.3 +script: "rake spec" +branches: + only: + - master +env: + - PUPPET_VERSION=2.6.17 + - PUPPET_VERSION=2.7.19 + #- PUPPET_VERSION=3.0.1 # Breaks due to rodjek/rspec-puppet#58 +notifications: + email: false +gemfile: .gemfile +matrix: + exclude: + - rvm: 1.9.3 + gemfile: .gemfile + env: PUPPET_VERSION=2.6.17 + - rvm: 1.8.7 + gemfile: .gemfile + env: PUPPET_VERSION=3.0.1 diff --git a/puppet/modules/haproxy/CHANGELOG b/puppet/modules/haproxy/CHANGELOG new file mode 100644 index 00000000..0b6d670f --- /dev/null +++ b/puppet/modules/haproxy/CHANGELOG @@ -0,0 +1,5 @@ +2012-10-12 - Version 0.2.0 +- Initial public release +- Backwards incompatible changes all around +- No longer needs ordering passed for more than one listener +- Accepts multiple listen ips/ports/server_names diff --git a/puppet/modules/haproxy/Modulefile b/puppet/modules/haproxy/Modulefile new file mode 100644 index 00000000..e729739b --- /dev/null +++ b/puppet/modules/haproxy/Modulefile @@ -0,0 +1,12 @@ +name 'puppetlabs-haproxy' +version '0.2.0' +source 'git://github.com/puppetlabs/puppetlabs-haproxy' +author 'Puppet Labs' +license 'Apache License, Version 2.0' +summary 'Haproxy Module' +description 'An Haproxy module for Redhat family OSes using Storeconfigs' +project_page 'http://github.com/puppetlabs/puppetlabs-haproxy' + +## Add dependencies, if any: +# dependency 'username/name', '>= 1.2.0' +dependency 'ripienaar/concat', '>= 0.1.0' diff --git a/puppet/modules/haproxy/README.md b/puppet/modules/haproxy/README.md new file mode 100644 index 00000000..d209e9ab --- /dev/null +++ b/puppet/modules/haproxy/README.md @@ -0,0 +1,87 @@ +PuppetLabs Module for haproxy +============================= + +HAProxy is an HA proxying daemon for load-balancing to clustered services. It +can proxy TCP directly, or other kinds of traffic such as HTTP. + +Dependencies +------------ + +Tested and built on Debian, Ubuntu and CentOS + +Currently requires the ripienaar/concat module on the Puppet Forge and uses storeconfigs on the Puppet Master to export/collect resources +from all balancer members. + +Basic Usage +----------- + +This haproxy uses storeconfigs to collect and realize balancer member servers +on a load balancer server. + +*To install and configure HAProxy server listening on port 8140* + +```puppet +node 'haproxy-server' { + class { 'haproxy': } + haproxy::listen { 'puppet00': + ipaddress => $::ipaddress, + ports => '8140', + } +} +``` + +*To add backend loadbalance members* + +```puppet +node 'webserver01' { + @@haproxy::balancermember { $fqdn: + listening_service => 'puppet00', + server_names => $::hostname, + ipaddresses => $::ipaddress, + ports => '8140', + options => 'check' + } +} +``` + +Configuring haproxy options +--------------------------- + +The base `haproxy` class can accept two parameters which will configure basic +behaviour of the haproxy server daemon: + +- `global_options` to configure the `global` section in `haproxy.cfg` +- `defaults_options` to configure the `defaults` section in `haproxy.cfg` + +Configuring haproxy daemon listener +----------------------------------- + +One `haproxy::listen` defined resource should be defined for each HAProxy loadbalanced set of backend servers. The title of the `haproxy::listen` resource is the key to which balancer members will be proxied to. The `ipaddress` field should be the public ip address which the loadbalancer will be contacted on. The `ports` attribute can accept an array or comma-separated list of ports which should be proxied to the `haproxy::balancermemeber` nodes. + +Configuring haproxy loadbalanced member nodes +--------------------------------------------- + +The `haproxy::balacemember` defined resource should be exported from each node +which is serving loadbalanced traffic. the `listening_service` attribute will +associate it with `haproxy::listen` directives on the haproxy node. +`ipaddresses` and `ports` will be assigned to the member to be contacted on. If an array of `ipaddresses` and `server_names` are provided then they will be added to the config in lock-step. + + +Copyright and License +--------------------- + +Copyright (C) 2012 [Puppet Labs](https://www.puppetlabs.com/) Inc + +Puppet Labs can be contacted at: info@puppetlabs.com + +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/puppet/modules/haproxy/Rakefile b/puppet/modules/haproxy/Rakefile new file mode 100644 index 00000000..cd3d3799 --- /dev/null +++ b/puppet/modules/haproxy/Rakefile @@ -0,0 +1 @@ +require 'puppetlabs_spec_helper/rake_tasks' diff --git a/puppet/modules/haproxy/manifests/balancermember.pp b/puppet/modules/haproxy/manifests/balancermember.pp new file mode 100644 index 00000000..a0e27539 --- /dev/null +++ b/puppet/modules/haproxy/manifests/balancermember.pp @@ -0,0 +1,95 @@ +# == Define Resource Type: haproxy::balancermember +# +# This type will setup a balancer member inside a listening service +# configuration block in /etc/haproxy/haproxy.cfg on the load balancer. +# currently it only has the ability to specify the instance name, +# ip address, port, and whether or not it is a backup. More features +# can be added as needed. The best way to implement this is to export +# this resource for all haproxy balancer member servers, and then collect +# them on the main haproxy load balancer. +# +# === Requirement/Dependencies: +# +# Currently requires the ripienaar/concat module on the Puppet Forge and +# uses storeconfigs on the Puppet Master to export/collect resources +# from all balancer members. +# +# === Parameters +# +# [*name*] +# The title of the resource is arbitrary and only utilized in the concat +# fragment name. +# +# [*listening_service*] +# The haproxy service's instance name (or, the title of the +# haproxy::listen resource). This must match up with a declared +# haproxy::listen resource. +# +# [*ports*] +# An array or commas-separated list of ports for which the balancer member +# will accept connections from the load balancer. Note that cookie values +# aren't yet supported, but shouldn't be difficult to add to the +# configuration. If you use an array in server_names and ipaddresses, the +# same port is used for all balancermembers. +# +# [*server_names*] +# The name of the balancer member server as known to haproxy in the +# listening service's configuration block. This defaults to the +# hostname. Can be an array of the same length as ipaddresses, +# in which case a balancermember is created for each pair of +# server_names and ipaddresses (in lockstep). +# +# [*ipaddresses*] +# The ip address used to contact the balancer member server. +# Can be an array, see documentation to server_names. +# +# [*options*] +# An array of options to be specified after the server declaration +# in the listening service's configuration block. +# +# +# === Examples +# +# Exporting the resource for a balancer member: +# +# @@haproxy::balancermember { 'haproxy': +# listening_service => 'puppet00', +# ports => '8140', +# server_names => $::hostname, +# ipaddresses => $::ipaddress, +# options => 'check', +# } +# +# +# Collecting the resource on a load balancer +# +# Haproxy::Balancermember <<| listening_service == 'puppet00' |>> +# +# Creating the resource for multiple balancer members at once +# (for single-pass installation of haproxy without requiring a first +# pass to export the resources if you know the members in advance): +# +# haproxy::balancermember { 'haproxy': +# listening_service => 'puppet00', +# ports => '8140', +# server_names => ['server01', 'server02'], +# ipaddresses => ['192.168.56.200', '192.168.56.201'], +# options => 'check', +# } +# +# (this resource can be declared anywhere) +# +define haproxy::balancermember ( + $listening_service, + $ports, + $server_names = $::hostname, + $ipaddresses = $::ipaddress, + $options = '' +) { + # Template uses $ipaddresses, $server_name, $ports, $option + concat::fragment { "${listening_service}_balancermember_${name}": + order => "20-${listening_service}-${name}", + target => '/etc/haproxy/haproxy.cfg', + content => template('haproxy/haproxy_balancermember.erb'), + } +} diff --git a/puppet/modules/haproxy/manifests/init.pp b/puppet/modules/haproxy/manifests/init.pp new file mode 100644 index 00000000..b91591a3 --- /dev/null +++ b/puppet/modules/haproxy/manifests/init.pp @@ -0,0 +1,149 @@ +# == Class: haproxy +# +# A Puppet module, using storeconfigs, to model an haproxy configuration. +# Currently VERY limited - Pull requests accepted! +# +# === Requirement/Dependencies: +# +# Currently requires the ripienaar/concat module on the Puppet Forge and +# uses storeconfigs on the Puppet Master to export/collect resources +# from all balancer members. +# +# === Parameters +# +# [*enable*] +# Chooses whether haproxy should be installed or ensured absent. +# Currently ONLY accepts valid boolean true/false values. +# +# [*version*] +# Allows you to specify what version of the package to install. +# Default is simply 'present' +# +# [*global_options*] +# A hash of all the haproxy global options. If you want to specify more +# than one option (i.e. multiple timeout or stats options), pass those +# options as an array and you will get a line for each of them in the +# resultant haproxy.cfg file. +# +# [*defaults_options*] +# A hash of all the haproxy defaults options. If you want to specify more +# than one option (i.e. multiple timeout or stats options), pass those +# options as an array and you will get a line for each of them in the +# resultant haproxy.cfg file. +# +# +# === Examples +# +# class { 'haproxy': +# enable => true, +# global_options => { +# 'log' => "${::ipaddress} local0", +# 'chroot' => '/var/lib/haproxy', +# 'pidfile' => '/var/run/haproxy.pid', +# 'maxconn' => '4000', +# 'user' => 'haproxy', +# 'group' => 'haproxy', +# 'daemon' => '', +# 'stats' => 'socket /var/lib/haproxy/stats' +# }, +# defaults_options => { +# 'log' => 'global', +# 'stats' => 'enable', +# 'option' => 'redispatch', +# 'retries' => '3', +# 'timeout' => [ +# 'http-request 10s', +# 'queue 1m', +# 'connect 10s', +# 'client 1m', +# 'server 1m', +# 'check 10s' +# ], +# 'maxconn' => '8000' +# }, +# } +# +class haproxy ( + $manage_service = true, + $enable = true, + $version = 'present', + $global_options = $haproxy::params::global_options, + $defaults_options = $haproxy::params::defaults_options +) inherits haproxy::params { + include concat::setup + + package { 'haproxy': + ensure => $enable ? { + true => $version, + false => absent, + }, + name => 'haproxy', + } + + if $enable { + concat { '/etc/haproxy/haproxy.cfg': + owner => '0', + group => '0', + mode => '0644', + require => Package['haproxy'], + notify => $manage_service ? { + true => Service['haproxy'], + false => undef, + }, + } + + # Simple Header + concat::fragment { '00-header': + target => '/etc/haproxy/haproxy.cfg', + order => '01', + content => "# This file managed by Puppet\n", + } + + # Template uses $global_options, $defaults_options + concat::fragment { 'haproxy-base': + target => '/etc/haproxy/haproxy.cfg', + order => '10', + content => template('haproxy/haproxy-base.cfg.erb'), + } + + if ($::osfamily == 'Debian') { + file { '/etc/default/haproxy': + content => 'ENABLED=1', + require => Package['haproxy'], + before => $manage_service ? { + true => Service['haproxy'], + false => undef, + }, + } + } + + file { $global_options['chroot']: + ensure => directory, + owner => $global_options['user'], + group => $global_options['group'], + mode => '0550', + require => Package['haproxy'] + } + + } + + if $manage_service { + service { 'haproxy': + ensure => $enable ? { + true => running, + false => stopped, + }, + enable => $enable ? { + true => true, + false => false, + }, + name => 'haproxy', + hasrestart => true, + hasstatus => true, + require => [ + Concat['/etc/haproxy/haproxy.cfg'], + File[$global_options['chroot']], + ], + } + } +} diff --git a/puppet/modules/haproxy/manifests/listen.pp b/puppet/modules/haproxy/manifests/listen.pp new file mode 100644 index 00000000..00636e3d --- /dev/null +++ b/puppet/modules/haproxy/manifests/listen.pp @@ -0,0 +1,95 @@ +# == Define Resource Type: haproxy::listen +# +# This type will setup a listening service configuration block inside +# the haproxy.cfg file on an haproxy load balancer. Each listening service +# configuration needs one or more load balancer member server (that can be +# declared with the haproxy::balancermember defined resource type). Using +# storeconfigs, you can export the haproxy::balancermember resources on all +# load balancer member servers, and then collect them on a single haproxy +# load balancer server. +# +# === Requirement/Dependencies: +# +# Currently requires the ripienaar/concat module on the Puppet Forge and +# uses storeconfigs on the Puppet Master to export/collect resources +# from all balancer members. +# +# === Parameters +# +# [*name*] +# The namevar of the defined resource type is the listening service's name. +# This name goes right after the 'listen' statement in haproxy.cfg +# +# [*ports*] +# Ports on which the proxy will listen for connections on the ip address +# specified in the virtual_ip parameter. Accepts either a single +# comma-separated string or an array of strings which may be ports or +# hyphenated port ranges. +# +# [*ipaddress*] +# The ip address the proxy binds to. Empty addresses, '*', and '0.0.0.0' +# mean that the proxy listens to all valid addresses on the system. +# +# [*mode*] +# The mode of operation for the listening service. Valid values are 'tcp', +# HTTP', and 'health'. +# +# [*options*] +# A hash of options that are inserted into the listening service +# configuration block. +# +# [*collect_exported*] +# Boolean, default 'true'. True means 'collect exported @@balancermember resources' +# (for the case when every balancermember node exports itself), false means +# 'rely on the existing declared balancermember resources' (for the case when you +# know the full set of balancermembers in advance and use haproxy::balancermember +# with array arguments, which allows you to deploy everything in 1 run) +# +# +# === Examples +# +# Exporting the resource for a balancer member: +# +# haproxy::listen { 'puppet00': +# ipaddress => $::ipaddress, +# ports => '18140', +# mode => 'tcp', +# options => { +# 'option' => [ +# 'tcplog', +# 'ssl-hello-chk' +# ], +# 'balance' => 'roundrobin' +# }, +# } +# +# === Authors +# +# Gary Larizza +# +define haproxy::listen ( + $ports, + $ipaddress = [$::ipaddress], + $mode = 'tcp', + $collect_exported = true, + $options = { + 'option' => [ + 'tcplog', + 'ssl-hello-chk' + ], + 'balance' => 'roundrobin' + } +) { + # Template uses: $name, $ipaddress, $ports, $options + concat::fragment { "${name}_listen_block": + order => "20-${name}-00", + target => '/etc/haproxy/haproxy.cfg', + content => template('haproxy/haproxy_listen_block.erb'), + } + + if $collect_exported { + Haproxy::Balancermember <<| listening_service == $name |>> + } + # else: the resources have been created and they introduced their + # concat fragments. We don't have to do anything about them. +} diff --git a/puppet/modules/haproxy/manifests/params.pp b/puppet/modules/haproxy/manifests/params.pp new file mode 100644 index 00000000..53442ddc --- /dev/null +++ b/puppet/modules/haproxy/manifests/params.pp @@ -0,0 +1,65 @@ +# == Class: haproxy::params +# +# This is a container class holding default parameters for for haproxy class. +# currently, only the Redhat family is supported, but this can be easily +# extended by changing package names and configuration file paths. +# +class haproxy::params { + case $osfamily { + Redhat: { + $global_options = { + 'log' => "${::ipaddress} local0", + 'chroot' => '/var/lib/haproxy', + 'pidfile' => '/var/run/haproxy.pid', + 'maxconn' => '4000', + 'user' => 'haproxy', + 'group' => 'haproxy', + 'daemon' => '', + 'stats' => 'socket /var/lib/haproxy/stats' + } + $defaults_options = { + 'log' => 'global', + 'stats' => 'enable', + 'option' => 'redispatch', + 'retries' => '3', + 'timeout' => [ + 'http-request 10s', + 'queue 1m', + 'connect 10s', + 'client 1m', + 'server 1m', + 'check 10s', + ], + 'maxconn' => '8000' + } + } + Debian: { + $global_options = { + 'log' => "${::ipaddress} local0", + 'chroot' => '/var/lib/haproxy', + 'pidfile' => '/var/run/haproxy.pid', + 'maxconn' => '4000', + 'user' => 'haproxy', + 'group' => 'haproxy', + 'daemon' => '', + 'stats' => 'socket /var/lib/haproxy/stats' + } + $defaults_options = { + 'log' => 'global', + 'stats' => 'enable', + 'option' => 'redispatch', + 'retries' => '3', + 'timeout' => [ + 'http-request 10s', + 'queue 1m', + 'connect 10s', + 'client 1m', + 'server 1m', + 'check 10s', + ], + 'maxconn' => '8000' + } + } + default: { fail("The $::osfamily operating system is not supported with the haproxy module") } + } +} diff --git a/puppet/modules/haproxy/spec/classes/haproxy_spec.rb b/puppet/modules/haproxy/spec/classes/haproxy_spec.rb new file mode 100644 index 00000000..4b5902ce --- /dev/null +++ b/puppet/modules/haproxy/spec/classes/haproxy_spec.rb @@ -0,0 +1,138 @@ +require 'spec_helper' + +describe 'haproxy', :type => :class do + let(:default_facts) do + { + :concat_basedir => '/dne', + :ipaddress => '10.10.10.10' + } + end + context 'on supported platforms' do + describe 'for OS-agnostic configuration' do + ['Debian', 'RedHat'].each do |osfamily| + context "on #{osfamily} family operatingsystems" do + let(:facts) do + { :osfamily => osfamily }.merge default_facts + end + let(:params) do + {'enable' => true} + end + it { should include_class('concat::setup') } + it 'should install the haproxy package' do + subject.should contain_package('haproxy').with( + 'ensure' => 'present' + ) + end + it 'should install the haproxy service' do + subject.should contain_service('haproxy').with( + 'ensure' => 'running', + 'enable' => 'true', + 'hasrestart' => 'true', + 'hasstatus' => 'true', + 'require' => [ + 'Concat[/etc/haproxy/haproxy.cfg]', + 'File[/var/lib/haproxy]' + ] + ) + end + it 'should set up /etc/haproxy/haproxy.cfg as a concat resource' do + subject.should contain_concat('/etc/haproxy/haproxy.cfg').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644' + ) + end + it 'should manage the chroot directory' do + subject.should contain_file('/var/lib/haproxy').with( + 'ensure' => 'directory' + ) + end + it 'should contain a header concat fragment' do + subject.should contain_concat__fragment('00-header').with( + 'target' => '/etc/haproxy/haproxy.cfg', + 'order' => '01', + 'content' => "# This file managed by Puppet\n" + ) + end + it 'should contain a haproxy-base concat fragment' do + subject.should contain_concat__fragment('haproxy-base').with( + 'target' => '/etc/haproxy/haproxy.cfg', + 'order' => '10' + ) + end + describe 'Base concat fragment contents' do + let(:contents) { param_value(subject, 'concat::fragment', 'haproxy-base', 'content').split("\n") } + it 'should contain global and defaults sections' do + contents.should include('global') + contents.should include('defaults') + end + it 'should log to an ip address for local0' do + contents.should be_any { |match| match =~ / log \d+(\.\d+){3} local0/ } + end + it 'should specify the default chroot' do + contents.should include(' chroot /var/lib/haproxy') + end + it 'should specify the correct user' do + contents.should include(' user haproxy') + end + it 'should specify the correct group' do + contents.should include(' group haproxy') + end + it 'should specify the correct pidfile' do + contents.should include(' pidfile /var/run/haproxy.pid') + end + end + end + context "on #{osfamily} family operatingsystems without managing the service" do + let(:facts) do + { :osfamily => osfamily }.merge default_facts + end + let(:params) do + { + 'enable' => true, + 'manage_service' => false, + } + end + it { should include_class('concat::setup') } + it 'should install the haproxy package' do + subject.should contain_package('haproxy').with( + 'ensure' => 'present' + ) + end + it 'should install the haproxy service' do + subject.should_not contain_service('haproxy') + end + end + end + end + describe 'for OS-specific configuration' do + context 'only on Debian family operatingsystems' do + let(:facts) do + { :osfamily => 'Debian' }.merge default_facts + end + it 'should manage haproxy service defaults' do + subject.should contain_file('/etc/default/haproxy').with( + 'before' => 'Service[haproxy]', + 'require' => 'Package[haproxy]' + ) + verify_contents(subject, '/etc/default/haproxy', ['ENABLED=1']) + end + end + context 'only on RedHat family operatingsystems' do + let(:facts) do + { :osfamily => 'RedHat' }.merge default_facts + end + end + end + end + context 'on unsupported operatingsystems' do + let(:facts) do + { :osfamily => 'RainbowUnicorn' }.merge default_facts + end + it do + expect { + should contain_service('haproxy') + }.to raise_error(Puppet::Error, /operating system is not supported with the haproxy module/) + end + end +end diff --git a/puppet/modules/haproxy/spec/defines/balancermember_spec.rb b/puppet/modules/haproxy/spec/defines/balancermember_spec.rb new file mode 100644 index 00000000..74bc7a8b --- /dev/null +++ b/puppet/modules/haproxy/spec/defines/balancermember_spec.rb @@ -0,0 +1,82 @@ +require 'spec_helper' + +describe 'haproxy::balancermember' do + let(:title) { 'tyler' } + let(:facts) do + { + :ipaddress => '1.1.1.1', + :hostname => 'dero' + } + end + + context 'with a single balancermember option' do + let(:params) do + { + :name => 'tyler', + :listening_service => 'croy', + :ports => '18140', + :options => 'check' + } + end + + it { should contain_concat__fragment('croy_balancermember_tyler').with( + 'order' => '20-croy-tyler', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => " server dero 1.1.1.1:18140 check\n\n" + ) } + end + + context 'with multiple balancermember options' do + let(:params) do + { + :name => 'tyler', + :listening_service => 'croy', + :ports => '18140', + :options => ['check', 'close'] + } + end + + it { should contain_concat__fragment('croy_balancermember_tyler').with( + 'order' => '20-croy-tyler', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => " server dero 1.1.1.1:18140 check close\n\n" + ) } + end + + context 'with multiple servers' do + let(:params) do + { + :name => 'tyler', + :listening_service => 'croy', + :ports => '18140', + :server_names => ['server01', 'server02'], + :ipaddresses => ['192.168.56.200', '192.168.56.201'], + :options => ['check'] + } + end + + it { should contain_concat__fragment('croy_balancermember_tyler').with( + 'order' => '20-croy-tyler', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => " server server01 192.168.56.200:18140 check\n server server02 192.168.56.201:18140 check\n\n" + ) } + end + context 'with multiple servers and multiple ports' do + let(:params) do + { + :name => 'tyler', + :listening_service => 'croy', + :ports => ['18140','18150'], + :server_names => ['server01', 'server02'], + :ipaddresses => ['192.168.56.200', '192.168.56.201'], + :options => ['check'] + } + end + + it { should contain_concat__fragment('croy_balancermember_tyler').with( + 'order' => '20-croy-tyler', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => " server server01 192.168.56.200:18140,192.168.56.200:18150 check\n server server02 192.168.56.201:18140,192.168.56.201:18150 check\n\n" + ) } + end +end diff --git a/puppet/modules/haproxy/spec/defines/listen_spec.rb b/puppet/modules/haproxy/spec/defines/listen_spec.rb new file mode 100644 index 00000000..31dd4c85 --- /dev/null +++ b/puppet/modules/haproxy/spec/defines/listen_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +describe 'haproxy::listen' do + let(:title) { 'tyler' } + let(:facts) {{ :ipaddress => '1.1.1.1' }} + context "when only one port is provided" do + let(:params) do + { + :name => 'croy', + :ports => '18140' + } + end + + it { should contain_concat__fragment('croy_listen_block').with( + 'order' => '20-croy-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "listen croy\n\n bind 1.1.1.1:18140\n\n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + ) } + end + context "when an array of ports is provided" do + let(:params) do + { + :name => 'apache', + :ipaddress => '23.23.23.23', + :ports => [ + '80', + '443', + ] + } + end + + it { should contain_concat__fragment('apache_listen_block').with( + 'order' => '20-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "listen apache\n\n bind 23.23.23.23:80\n\n bind 23.23.23.23:443\n\n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + ) } + end + context "when a comma-separated list of ports is provided" do + let(:params) do + { + :name => 'apache', + :ipaddress => '23.23.23.23', + :ports => '80,443' + } + end + + it { should contain_concat__fragment('apache_listen_block').with( + 'order' => '20-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "listen apache\n\n bind 23.23.23.23:80\n\n bind 23.23.23.23:443\n\n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + ) } + end +end diff --git a/puppet/modules/haproxy/spec/spec.opts b/puppet/modules/haproxy/spec/spec.opts new file mode 100644 index 00000000..91cd6427 --- /dev/null +++ b/puppet/modules/haproxy/spec/spec.opts @@ -0,0 +1,6 @@ +--format +s +--colour +--loadby +mtime +--backtrace diff --git a/puppet/modules/haproxy/spec/spec_helper.rb b/puppet/modules/haproxy/spec/spec_helper.rb new file mode 100644 index 00000000..2c6f5664 --- /dev/null +++ b/puppet/modules/haproxy/spec/spec_helper.rb @@ -0,0 +1 @@ +require 'puppetlabs_spec_helper/module_spec_helper' diff --git a/puppet/modules/haproxy/templates/haproxy-base.cfg.erb b/puppet/modules/haproxy/templates/haproxy-base.cfg.erb new file mode 100644 index 00000000..f25d5c34 --- /dev/null +++ b/puppet/modules/haproxy/templates/haproxy-base.cfg.erb @@ -0,0 +1,21 @@ +global +<% @global_options.sort.each do |key,val| -%> +<% if val.is_a?(Array) -%> +<% val.each do |item| -%> + <%= key %> <%= item %> +<% end -%> +<% else -%> + <%= key %> <%= val %> +<% end -%> +<% end -%> + +defaults +<% @defaults_options.sort.each do |key,val| -%> +<% if val.is_a?(Array) -%> +<% val.each do |item| -%> + <%= key %> <%= item %> +<% end -%> +<% else -%> + <%= key %> <%= val %> +<% end -%> +<% end -%> diff --git a/puppet/modules/haproxy/templates/haproxy_balancermember.erb b/puppet/modules/haproxy/templates/haproxy_balancermember.erb new file mode 100644 index 00000000..1d03f565 --- /dev/null +++ b/puppet/modules/haproxy/templates/haproxy_balancermember.erb @@ -0,0 +1,3 @@ +<% Array(ipaddresses).zip(Array(server_names)).each do |ipaddress,host| -%> + server <%= host %> <%= ipaddress %>:<%= Array(ports).collect {|x|x.split(',')}.flatten.join(",#{ipaddress}:") %> <%= Array(options).join(" ") %> +<% end %> diff --git a/puppet/modules/haproxy/templates/haproxy_listen_block.erb b/puppet/modules/haproxy/templates/haproxy_listen_block.erb new file mode 100644 index 00000000..129313f1 --- /dev/null +++ b/puppet/modules/haproxy/templates/haproxy_listen_block.erb @@ -0,0 +1,10 @@ +listen <%= name %> + mode <%= mode %> +<% Array(ipaddress).uniq.each do |virtual_ip| (ports.is_a?(Array) ? ports : Array(ports.split(","))).each do |port| %> + bind <%= virtual_ip %>:<%= port %> +<% end end %> +<% options.sort.each do |key, val| -%> +<% Array(val).each do |item| -%> + <%= key %> <%= item %> +<% end -%> +<% end -%> diff --git a/puppet/modules/haproxy/tests/init.pp b/puppet/modules/haproxy/tests/init.pp new file mode 100644 index 00000000..77590ac8 --- /dev/null +++ b/puppet/modules/haproxy/tests/init.pp @@ -0,0 +1,69 @@ +# Declare haproxy base class with configuration options +class { 'haproxy': + enable => true, + global_options => { + 'log' => "${::ipaddress} local0", + 'chroot' => '/var/lib/haproxy', + 'pidfile' => '/var/run/haproxy.pid', + 'maxconn' => '4000', + 'user' => 'haproxy', + 'group' => 'haproxy', + 'daemon' => '', + 'stats' => 'socket /var/lib/haproxy/stats', + }, + defaults_options => { + 'log' => 'global', + 'stats' => 'enable', + 'option' => 'redispatch', + 'retries' => '3', + 'timeout' => [ + 'http-request 10s', + 'queue 1m', + 'connect 10s', + 'client 1m', + 'server 1m', + 'check 10s', + ], + 'maxconn' => '8000', + }, +} + +# Export a balancermember server, note that the listening_service parameter +# will/must correlate with an haproxy::listen defined resource type. +@@haproxy::balancermember { $fqdn: + order => '21', + listening_service => 'puppet00', + server_name => $::hostname, + balancer_ip => $::ipaddress, + balancer_port => '8140', + balancermember_options => 'check' +} + +# Declare a couple of Listening Services for haproxy.cfg +# Note that the balancermember server resources are being collected in +# the haproxy::config defined resource type with the following line: +# Haproxy::Balancermember <<| listening_service == $name |>> +haproxy::listen { 'puppet00': + order => '20', + ipaddress => $::ipaddress, + ports => '18140', + options => { + 'option' => [ + 'tcplog', + 'ssl-hello-chk', + ], + 'balance' => 'roundrobin', + }, +} +haproxy::listen { 'stats': + order => '30', + ipaddress => '', + ports => '9090', + options => { + 'mode' => 'http', + 'stats' => [ + 'uri /', + 'auth puppet:puppet' + ], + }, +} -- cgit v1.2.3 From d8a8d30b04d34387f309d9f5b7afdbcad01f7cbc Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:46:23 -0400 Subject: git subrepo clone https://leap.se/git/puppet_squid_deb_proxy puppet/modules/squid_deb_proxy subrepo: subdir: "puppet/modules/squid_deb_proxy" merged: "08bfacc" upstream: origin: "https://leap.se/git/puppet_squid_deb_proxy" branch: "master" commit: "08bfacc" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I4afe250a7d95c927ee2c1e06f7efd6f733fefe29 --- puppet/modules/squid_deb_proxy/.gitrepo | 11 ++ puppet/modules/squid_deb_proxy/README.md | 8 ++ .../files/Debian/squid-deb-proxy.conf | 91 ++++++++++++++ .../files/Ubuntu/squid-deb-proxy.conf | 89 +++++++++++++ .../files/allowed-networks-src.acl.d/20-custom | 1 + .../files/client/apt-avahi-discover | 138 +++++++++++++++++++++ .../files/mirror-dstdomain.acl.d/20-custom | 1 + puppet/modules/squid_deb_proxy/manifests/client.pp | 16 +++ puppet/modules/squid_deb_proxy/manifests/server.pp | 41 ++++++ 9 files changed, 396 insertions(+) create mode 100644 puppet/modules/squid_deb_proxy/.gitrepo create mode 100644 puppet/modules/squid_deb_proxy/README.md create mode 100644 puppet/modules/squid_deb_proxy/files/Debian/squid-deb-proxy.conf create mode 100644 puppet/modules/squid_deb_proxy/files/Ubuntu/squid-deb-proxy.conf create mode 100644 puppet/modules/squid_deb_proxy/files/allowed-networks-src.acl.d/20-custom create mode 100755 puppet/modules/squid_deb_proxy/files/client/apt-avahi-discover create mode 100644 puppet/modules/squid_deb_proxy/files/mirror-dstdomain.acl.d/20-custom create mode 100644 puppet/modules/squid_deb_proxy/manifests/client.pp create mode 100644 puppet/modules/squid_deb_proxy/manifests/server.pp (limited to 'puppet/modules') diff --git a/puppet/modules/squid_deb_proxy/.gitrepo b/puppet/modules/squid_deb_proxy/.gitrepo new file mode 100644 index 00000000..78765952 --- /dev/null +++ b/puppet/modules/squid_deb_proxy/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_squid_deb_proxy + branch = master + commit = 08bfaccaea01fd2d334946428504e71a51748e3d + parent = a658f5c30ada5e03468257f90d08f6cd2ba25488 + cmdver = 0.3.0 diff --git a/puppet/modules/squid_deb_proxy/README.md b/puppet/modules/squid_deb_proxy/README.md new file mode 100644 index 00000000..c183c826 --- /dev/null +++ b/puppet/modules/squid_deb_proxy/README.md @@ -0,0 +1,8 @@ +This module installes squid-deb-proxy (server or client) +see https://launchpad.net/squid-deb-proxy for more details + +Debian Support +============== + +* As of 2013-07, squid-deb-proxy just arrived in jessie, so you need to + configure apt to use jessie. diff --git a/puppet/modules/squid_deb_proxy/files/Debian/squid-deb-proxy.conf b/puppet/modules/squid_deb_proxy/files/Debian/squid-deb-proxy.conf new file mode 100644 index 00000000..2a528f84 --- /dev/null +++ b/puppet/modules/squid_deb_proxy/files/Debian/squid-deb-proxy.conf @@ -0,0 +1,91 @@ + +# WELCOME TO SQUID DEB PROXY +# ------------------ +# +# This config file is a version of a squid proxy file optimized +# as a configuration for a caching proxy for Debian/Ubuntu systems. +# +# More information about squid and its configuration can be found here +# http://www.squid-cache.org/ and in the FAQ + +# settings that you may want to customize +# --------------------------------------- + +# this file contains private networks (10.0.0.0/8, 172.16.0.0/12, +# 192.168.0.0/16) by default, you can add/remove additional allowed +# source networks in it to customize it for your setup +acl allowed_networks src "/etc/squid-deb-proxy/autogenerated/allowed-networks-src.acl" + +# this file contains the archive mirrors by default, +# if you use a different mirror, add it there +acl to_archive_mirrors dstdomain "/etc/squid-deb-proxy/autogenerated/mirror-dstdomain.acl" + +# this contains the package blacklist +acl blockedpkgs urlpath_regex "/etc/squid-deb-proxy/autogenerated/pkg-blacklist-regexp.acl" + +# default to a different port than stock squid +http_port 8000 + +# ------------------------------------------------- +# settings below probably do not need customization + +# user visible name +visible_hostname squid-deb-proxy + +# we need a big cache, some debs are huge +maximum_object_size 512 MB + +# use a different dir than stock squid and default to 40G +cache_dir aufs /var/cache/squid-deb-proxy 40000 16 256 + +# use different logs +cache_access_log /var/log/squid-deb-proxy/access.log +cache_log /var/log/squid-deb-proxy/cache.log +cache_store_log /var/log/squid-deb-proxy/store.log + +# tweaks to speed things up +cache_mem 200 MB +maximum_object_size_in_memory 10240 KB + +# pid +pid_filename /var/run/squid-deb-proxy.pid + +# refresh pattern for debs and udebs +refresh_pattern deb$ 129600 100% 129600 +refresh_pattern udeb$ 129600 100% 129600 +refresh_pattern tar.gz$ 129600 100% 129600 + +# always refresh Packages and Release files +refresh_pattern \/(Packages|Sources)(|\.bz2|\.gz)$ 0 0% 0 +refresh_pattern \/Release(|\.gpg)$ 0 0% 0 +refresh_pattern \/InRelease$ 0 0% 0 + +# handle meta-release and changelogs.ubuntu.com special +# (fine to have this on debian too) +refresh_pattern changelogs.ubuntu.com/* 0 1% 1 + +# only allow connects to ports for http, https +acl Safe_ports port 80 +acl Safe_ports port 443 563 + +# only allow ports we trust +http_access deny !Safe_ports + +# do not allow to download from the pkg blacklist +http_access deny blockedpkgs + +# allow access only to official archive mirrors +# uncomment the third and fouth line to permit any unlisted domain +http_access deny !to_archive_mirrors +#http_access allow !to_archive_mirrors + +# don't cache domains not listed in the mirrors file +# uncomment the third and fourth line to cache any unlisted domains +cache deny !to_archive_mirrors +#cache allow !to_archive_mirrors + +# allow access from our network and localhost +http_access allow allowed_networks + +# And finally deny all other access to this proxy +http_access deny all diff --git a/puppet/modules/squid_deb_proxy/files/Ubuntu/squid-deb-proxy.conf b/puppet/modules/squid_deb_proxy/files/Ubuntu/squid-deb-proxy.conf new file mode 100644 index 00000000..ab5bac8a --- /dev/null +++ b/puppet/modules/squid_deb_proxy/files/Ubuntu/squid-deb-proxy.conf @@ -0,0 +1,89 @@ + +# WELCOME TO SQUID DEB PROXY +# ------------------ +# +# This config file is a version of a squid proxy file optimized +# as a configuration for a caching proxy for Ubuntu systems. +# +# More information about squid and its configuration can be found here +# http://www.squid-cache.org/ and in the FAQ + +# settings that you may want to customize +# --------------------------------------- + +# this file contains private networks (10.0.0.0/8, 172.16.0.0/12, +# 192.168.0.0/16) by default, you can add/remove additional allowed +# source networks in it to customize it for your setup +acl allowed_networks src "/etc/squid-deb-proxy/autogenerated/allowed-networks-src.acl" + +# this file contains the *archive.ubuntu.com mirrors by default, +# if you use a different mirror, add it there +acl to_ubuntu_mirrors dstdomain "/etc/squid-deb-proxy/autogenerated/mirror-dstdomain.acl" + +# this contains the package blacklist +acl blockedpkgs urlpath_regex "/etc/squid-deb-proxy/autogenerated/pkg-blacklist-regexp.acl" + +# default to a different port than stock squid +http_port 8000 + +# ------------------------------------------------- +# settings below probably do not need customization + +# user visible name +visible_hostname squid-deb-proxy + +# we need a big cache, some debs are huge +maximum_object_size 512 MB + +# use a different dir than stock squid and default to 40G +cache_dir aufs /var/cache/squid-deb-proxy 40000 16 256 + +# use different logs +cache_access_log /var/log/squid-deb-proxy/access.log +cache_log /var/log/squid-deb-proxy/cache.log +cache_store_log /var/log/squid-deb-proxy/store.log + +# tweaks to speed things up +cache_mem 200 MB +maximum_object_size_in_memory 10240 KB + +# pid +pid_filename /var/run/squid-deb-proxy.pid + +# refresh pattern for debs and udebs +refresh_pattern deb$ 129600 100% 129600 +refresh_pattern udeb$ 129600 100% 129600 +refresh_pattern tar.gz$ 129600 100% 129600 + +# always refresh Packages and Release files +refresh_pattern \/(Packages|Sources)(|\.bz2|\.gz)$ 0 0% 0 +refresh_pattern \/Release(|\.gpg)$ 0 0% 0 + +# handle meta-release and changelogs.ubuntu.com special +refresh_pattern changelogs.ubuntu.com/* 0 1% 1 + +# only allow connects to ports for http, https +acl Safe_ports port 80 +acl Safe_ports port 443 563 + +# only allow ports we trust +http_access deny !Safe_ports + +# do not allow to download from the pkg blacklist +http_access deny blockedpkgs + +# allow access only to official ubuntu mirrors +# uncomment the third and fouth line to permit any unlisted domain +http_access deny !to_ubuntu_mirrors +#http_access allow !to_ubuntu_mirrors + +# don't cache domains not listed in the mirrors file +# uncomment the third and fourth line to cache any unlisted domains +cache deny !to_ubuntu_mirrors +#cache allow !to_ubuntu_mirrors + +# allow access from our network and localhost +http_access allow allowed_networks + +# And finally deny all other access to this proxy +http_access deny all diff --git a/puppet/modules/squid_deb_proxy/files/allowed-networks-src.acl.d/20-custom b/puppet/modules/squid_deb_proxy/files/allowed-networks-src.acl.d/20-custom new file mode 100644 index 00000000..d4058b80 --- /dev/null +++ b/puppet/modules/squid_deb_proxy/files/allowed-networks-src.acl.d/20-custom @@ -0,0 +1 @@ +# managed by puppet diff --git a/puppet/modules/squid_deb_proxy/files/client/apt-avahi-discover b/puppet/modules/squid_deb_proxy/files/client/apt-avahi-discover new file mode 100755 index 00000000..8dbc1be2 --- /dev/null +++ b/puppet/modules/squid_deb_proxy/files/client/apt-avahi-discover @@ -0,0 +1,138 @@ +#!/usr/bin/python +# +# use avahi to find a _apt_proxy._tcp provider and return +# a http proxy string suitable for apt + +import asyncore +import functools +import os +import socket +import sys +import time +from subprocess import Popen, PIPE, call +from syslog import syslog, LOG_INFO, LOG_USER + +DEFAULT_CONNECT_TIMEOUT_SEC = 2 + +def DEBUG(msg): + if "--debug" in sys.argv: + sys.stderr.write(msg + "\n") + + +def get_avahi_discover_timeout(): + APT_AVAHI_TIMEOUT_VAR = "APT::Avahi-Discover::Timeout" + p = Popen( + ["/usr/bin/apt-config", "shell", "TIMEOUT", APT_AVAHI_TIMEOUT_VAR], + stdout=PIPE) + stdout, stderr = p.communicate() + if not stdout: + DEBUG( + "no timeout set, using default '%s'" % DEFAULT_CONNECT_TIMEOUT_SEC) + return DEFAULT_CONNECT_TIMEOUT_SEC + if not stdout.startswith("TIMEOUT="): + raise ValueError("got unexpected apt-config output: '%s'" % stdout) + varname, sep, value = stdout.strip().partition("=") + timeout = int(value.strip("'")) + DEBUG("using timeout: '%s'" % timeout) + return timeout + +@functools.total_ordering +class AptAvahiClient(asyncore.dispatcher): + def __init__(self, addr): + asyncore.dispatcher.__init__(self) + if is_ipv6(addr[0]): + self.create_socket(socket.AF_INET6, socket.SOCK_STREAM) + self.connect( (addr[0], addr[1], 0, 0) ) + else: + self.create_socket(socket.AF_INET, socket.SOCK_STREAM) + self.connect(addr) + self._time_init = time.time() + self.time_to_connect = sys.maxint + self.address = addr + def handle_connect(self): + self.time_to_connect = time.time() - self._time_init + self.close() + def __eq__(self, other): + return self.time_to_connect == other.time_to_connect + def __lt__(self, other): + return self.time_to_connect < other.time_to_connect + def __repr__(self): + return "<%s> %s: %s" % ( + self.__class__.__name__, self.addr, self.time_to_connect) + def log(self, message): + syslog((LOG_INFO|LOG_USER), '%s\n' % str(message)) + def log_info(self, message, type='info'): + if type not in self.ignore_log_types: + self.log('%s: %s' % (type, message)) + + +def is_ipv6(a): + return ':' in a + +def is_linklocal(addr): + # Link-local should start with fe80 and six null bytes + return addr.startswith("fe80::") + +def get_proxy_host_port_from_avahi(): + service = '_apt_proxy._tcp' + + # Obtain all of the services addresses from avahi, pulling the IPv6 + # addresses to the top. + addr4 = [] + addr6 = [] + p = Popen(['avahi-browse', '-kprtf', service], stdout=PIPE) + DEBUG("avahi-browse output:") + for line in p.stdout: + DEBUG(" '%s'" % line) + if line.startswith('='): + tokens = line.split(';') + addr = tokens[7] + port = int(tokens[8]) + if is_ipv6(addr): + # We need to skip ipv6 link-local addresses since + # APT can't use them + if not is_linklocal(addr): + addr6.append((addr, port)) + else: + addr4.append((addr, port)) + + # Run through the offered addresses and see if we we have a bound local + # address for it. + addrs = [] + for (ip, port) in addr6 + addr4: + try: + res = socket.getaddrinfo(ip, port, 0, 0, 0, socket.AI_ADDRCONFIG) + if res: + addrs.append((ip, port)) + except socket.gaierror: + pass + if not addrs: + return None + + # sort by answering speed + hosts = [] + for addr in addrs: + hosts.append(AptAvahiClient(addr)) + # 2s timeout, arbitray + timeout = get_avahi_discover_timeout() + asyncore.loop(timeout=timeout) + DEBUG("sorted hosts: '%s'" % sorted(hosts)) + + # No host wanted to connect + if (all(h.time_to_connect == sys.maxint for h in hosts)): + return None + + fastest_host = sorted(hosts)[0] + fastest_address = fastest_host.address + return fastest_address + + +if __name__ == "__main__": + # Dump the approved address out in an appropriate format. + address = get_proxy_host_port_from_avahi() + if address: + (ip, port) = address + if is_ipv6(ip): + print "http://[%s]:%s/" % (ip, port) + else: + print "http://%s:%s/" % (ip, port) diff --git a/puppet/modules/squid_deb_proxy/files/mirror-dstdomain.acl.d/20-custom b/puppet/modules/squid_deb_proxy/files/mirror-dstdomain.acl.d/20-custom new file mode 100644 index 00000000..d4058b80 --- /dev/null +++ b/puppet/modules/squid_deb_proxy/files/mirror-dstdomain.acl.d/20-custom @@ -0,0 +1 @@ +# managed by puppet diff --git a/puppet/modules/squid_deb_proxy/manifests/client.pp b/puppet/modules/squid_deb_proxy/manifests/client.pp new file mode 100644 index 00000000..049f740a --- /dev/null +++ b/puppet/modules/squid_deb_proxy/manifests/client.pp @@ -0,0 +1,16 @@ +# install squid-deb-proxy-client package +class squid_deb_proxy::client { + package { 'squid-deb-proxy-client': + ensure => installed, + } -> + + # ship newer client discover script than includes in squid-deb-proxy-client + # v. 0.8.13 to fix error messages being sent to stdout instead of stderr, + # see https://bugs.launchpad.net/ubuntu/+source/squid-deb-proxy/+bug/1505670 + file { '/usr/share/squid-deb-proxy-client/apt-avahi-discover': + source => 'puppet:///modules/squid_deb_proxy/client/apt-avahi-discover', + mode => '0755', + owner => 'root', + group => 'root', + } +} diff --git a/puppet/modules/squid_deb_proxy/manifests/server.pp b/puppet/modules/squid_deb_proxy/manifests/server.pp new file mode 100644 index 00000000..b6c3b2ed --- /dev/null +++ b/puppet/modules/squid_deb_proxy/manifests/server.pp @@ -0,0 +1,41 @@ +class squid_deb_proxy::server { + package { 'squid-deb-proxy': + ensure => installed, + } + + service { 'squid-deb-proxy': + ensure => running, + hasstatus => false, + require => Package[ 'squid-deb-proxy' ], + } + + file {'/etc/squid-deb-proxy/mirror-dstdomain.acl.d/20-custom': + source => [ 'puppet:///modules/site_squid_deb_proxy/mirror-dstdomain.acl.d/20-custom', + 'puppet:///modules/squid_deb_proxy/mirror-dstdomain.acl.d/20-custom' ], + notify => Service[ 'squid-deb-proxy' ], + require => Package[ 'squid-deb-proxy' ], + mode => '0644', + owner => 'root', + group => 'root', + } + + file {'/etc/squid-deb-proxy/allowed-networks-src.acl.d/20-custom': + source => [ 'puppet:///modules/site_squid_deb_proxy/allowed-networks-src.acl.d/20-custom', + 'puppet:///modules/squid_deb_proxy/allowed-networks-src.acl.d/20-custom' ], + notify => Service[ 'squid-deb-proxy' ], + require => Package[ 'squid-deb-proxy' ], + mode => '0644', + owner => 'root', + group => 'root', + } + + file { '/etc/squid-deb-proxy/squid-deb-proxy.conf': + source => [ "puppet:///modules/site_squid_deb_proxy/${::operatingsystem}/squid-deb-proxy.conf", + "puppet:///modules/squid_deb_proxy/${::operatingsystem}/squid-deb-proxy.conf" ], + notify => Service[ 'squid-deb-proxy' ], + require => Package[ 'squid-deb-proxy' ], + mode => '0644', + owner => 'root', + group => 'root', + } +} -- cgit v1.2.3 From 5247b7ccf5b5889ee16262dd976b03047e34e32c Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:46:25 -0400 Subject: git subrepo clone https://leap.se/git/puppet_postfix puppet/modules/postfix subrepo: subdir: "puppet/modules/postfix" merged: "cce918f" upstream: origin: "https://leap.se/git/puppet_postfix" branch: "master" commit: "cce918f" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I325a79fe1780ee6a5d61959310cf8e52c9a6896f --- puppet/modules/postfix/.gitrepo | 11 + puppet/modules/postfix/LICENSE | 674 +++++++++++++++++++++ puppet/modules/postfix/README.md | 224 +++++++ .../modules/postfix/files/header_checks.d/.ignore | 0 puppet/modules/postfix/files/main.cf | 1 + puppet/modules/postfix/files/tls_policy.d/.ignore | 0 puppet/modules/postfix/manifests/amavis.pp | 5 + puppet/modules/postfix/manifests/anonsasl.pp | 18 + puppet/modules/postfix/manifests/config.pp | 49 ++ puppet/modules/postfix/manifests/disable.pp | 7 + puppet/modules/postfix/manifests/disable/base.pp | 12 + puppet/modules/postfix/manifests/disable/debian.pp | 11 + puppet/modules/postfix/manifests/hash.pp | 71 +++ puppet/modules/postfix/manifests/header_checks.pp | 32 + .../postfix/manifests/header_checks_snippet.pp | 60 ++ puppet/modules/postfix/manifests/init.pp | 221 +++++++ puppet/modules/postfix/manifests/mailalias.pp | 32 + puppet/modules/postfix/manifests/mailman.pp | 34 ++ puppet/modules/postfix/manifests/mta.pp | 70 +++ puppet/modules/postfix/manifests/satellite.pp | 49 ++ puppet/modules/postfix/manifests/smtp_auth.pp | 37 ++ puppet/modules/postfix/manifests/tlspolicy.pp | 55 ++ .../modules/postfix/manifests/tlspolicy_snippet.pp | 45 ++ puppet/modules/postfix/manifests/transport.pp | 44 ++ .../modules/postfix/manifests/transport_regexp.pp | 56 ++ .../postfix/manifests/transport_regexp_snippet.pp | 67 ++ puppet/modules/postfix/manifests/virtual.pp | 44 ++ puppet/modules/postfix/manifests/virtual_regexp.pp | 56 ++ .../postfix/manifests/virtual_regexp_snippet.pp | 67 ++ .../postfix/templates/anonsasl_header_checks.erb | 2 + .../postfix/templates/master.cf.debian-5.erb | 126 ++++ .../postfix/templates/master.cf.debian-6.erb | 158 +++++ .../postfix/templates/master.cf.debian-7.erb | 161 +++++ .../postfix/templates/master.cf.debian-8.erb | 160 +++++ .../postfix/templates/master.cf.debian-sid.erb | 157 +++++ .../postfix/templates/master.cf.redhat5.erb | 87 +++ 36 files changed, 2903 insertions(+) create mode 100644 puppet/modules/postfix/.gitrepo create mode 100644 puppet/modules/postfix/LICENSE create mode 100644 puppet/modules/postfix/README.md create mode 100644 puppet/modules/postfix/files/header_checks.d/.ignore create mode 100644 puppet/modules/postfix/files/main.cf create mode 100644 puppet/modules/postfix/files/tls_policy.d/.ignore create mode 100644 puppet/modules/postfix/manifests/amavis.pp create mode 100644 puppet/modules/postfix/manifests/anonsasl.pp create mode 100644 puppet/modules/postfix/manifests/config.pp create mode 100644 puppet/modules/postfix/manifests/disable.pp create mode 100644 puppet/modules/postfix/manifests/disable/base.pp create mode 100644 puppet/modules/postfix/manifests/disable/debian.pp create mode 100644 puppet/modules/postfix/manifests/hash.pp create mode 100644 puppet/modules/postfix/manifests/header_checks.pp create mode 100644 puppet/modules/postfix/manifests/header_checks_snippet.pp create mode 100644 puppet/modules/postfix/manifests/init.pp create mode 100644 puppet/modules/postfix/manifests/mailalias.pp create mode 100644 puppet/modules/postfix/manifests/mailman.pp create mode 100644 puppet/modules/postfix/manifests/mta.pp create mode 100644 puppet/modules/postfix/manifests/satellite.pp create mode 100644 puppet/modules/postfix/manifests/smtp_auth.pp create mode 100644 puppet/modules/postfix/manifests/tlspolicy.pp create mode 100644 puppet/modules/postfix/manifests/tlspolicy_snippet.pp create mode 100644 puppet/modules/postfix/manifests/transport.pp create mode 100644 puppet/modules/postfix/manifests/transport_regexp.pp create mode 100644 puppet/modules/postfix/manifests/transport_regexp_snippet.pp create mode 100644 puppet/modules/postfix/manifests/virtual.pp create mode 100644 puppet/modules/postfix/manifests/virtual_regexp.pp create mode 100644 puppet/modules/postfix/manifests/virtual_regexp_snippet.pp create mode 100644 puppet/modules/postfix/templates/anonsasl_header_checks.erb create mode 100644 puppet/modules/postfix/templates/master.cf.debian-5.erb create mode 100644 puppet/modules/postfix/templates/master.cf.debian-6.erb create mode 100644 puppet/modules/postfix/templates/master.cf.debian-7.erb create mode 100644 puppet/modules/postfix/templates/master.cf.debian-8.erb create mode 100644 puppet/modules/postfix/templates/master.cf.debian-sid.erb create mode 100644 puppet/modules/postfix/templates/master.cf.redhat5.erb (limited to 'puppet/modules') diff --git a/puppet/modules/postfix/.gitrepo b/puppet/modules/postfix/.gitrepo new file mode 100644 index 00000000..dfa4389c --- /dev/null +++ b/puppet/modules/postfix/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_postfix + branch = master + commit = cce918f784ebf8a8875f43c79bc3a1f39ab9456b + parent = d8a8d30b04d34387f309d9f5b7afdbcad01f7cbc + cmdver = 0.3.0 diff --git a/puppet/modules/postfix/LICENSE b/puppet/modules/postfix/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/puppet/modules/postfix/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/puppet/modules/postfix/README.md b/puppet/modules/postfix/README.md new file mode 100644 index 00000000..7a6b01fc --- /dev/null +++ b/puppet/modules/postfix/README.md @@ -0,0 +1,224 @@ +Postfix Puppet module +===================== + +This module will help install and configure postfix. + +A couple of classes will preconfigure postfix for common needs. + +This module needs: + +- the concat module: git://labs.riseup.net/shared-concat + +!! Upgrade Notice (01/2013) !! + +This module now uses parameterized classes, where it used global variables +before. So please whatch out before pulling, you need to change the +class declarations in your manifest ! + +Issues +------ + +- Debian wheezy hosts (or below): If you get this error msg: + + "Could not find template 'postfix/master.cf.debian-.erb' at /ssrv/leap/puppet/modules/postfix/manifests/init.pp:158 on node rew07plain1.rewire.org" + + you need to use the facter package from wheezy-backports instead of the wheezy one. See https://gitlab.com/shared-puppet-modules-group/postfix/merge_requests/6#note_1892207 for more details. + + +Deprecation notice +------------------ + +It used to be that one could drop header checks snippets into the +following source directories: + + "puppet:///modules/site-postfix/${fqdn}/header_checks.d" + "puppet:///modules/site-postfix/header_checks.d" + "puppet:///files/etc/postfix/header_checks.d" + "puppet:///modules/postfix/header_checks.d" + +... and TLS policy snippets into those: + + "puppet:///modules/site-postfix/${fqdn}/tls_policy.d" + "puppet:///modules/site-postfix/tls_policy.d" + "puppet:///modules/postfix/tls_policy.d" + +This is not supported anymore. + +Every such snippet much now be configured using the (respectively) +postfix::header_checks_snippet and postfix::tlspolicy_snippet defines. + +Note: You will need to set a global Exec { path => '...' } to a proper pathing +in your manifests, or you will experience some issues such as: + +err: Failed to apply catalog: Parameter unless failed: 'test "x$(postconf -h relay_domains)" == 'xlocalhost host.foo.com'' is not qualified and no path was specified. Please qualify the command or specify a path. + +See: http://www.puppetcookbook.com/posts/set-global-exec-path.html for more +information about how to do this + +Postfix class configuration parameters +-------------------------------------- + + * use_amavisd => 'yes' - to include postfix::amavis + + * anon_sasl => 'yes' - to hide the originating IP in email + relayed for an authenticated SASL client; this needs Postfix + 2.3 or later to work; beware! Postfix logs the header replacement + has been done, which means that you are storing this information, + unless you are anonymizing your logs. + + * manage_header_checks => 'yes' - to manage header checks (see + postfix::header_checks for details) + + * manage_transport_regexp => 'yes' - to manage header checks (see + postfix::transport_regexp for details) + + * manage_virtual_regexp => 'yes' - to manage header checks (see + postfix::virtual_regexp for details) + + * manage_tls_policy => 'yes - to manage TLS policy (see + postfix::tlspolicy for details) + + * inet_interfaces: by default, postfix will bind to all interfaces, but + sometimes you don't want that. To bind to specific interfaces, use the + 'inet_interfaces' parameter and set it to exactly what would be in the + main.cf file. + + * myorigin: some hosts have weird-looking host names (dedicated servers and VPSes). To + set the server's domain of origin, set the 'myorigin' parameter + + * smtp_listen: address on which the smtp service will listen (Default: 127.0.0.1) + + * root_mail_recipient: who will receive root's emails (Default: 'nobody') + + * tls_fingerprint_digest: fingerprint digest for tls policy class (Default: 'sha1') + + * use_dovecot_lda: include dovecot declaration at master.cf + + * use_schleuder: whether to include schleuder portion at master.cf + + * use_sympa: whether to include sympa portion at master.cf + + * use_firma: whether to include firma portion at master.cf + + * use_mlmmj: whether to include mlmmj portion at master.cf + + * use_submission: set to "yes" to enable submission section at master.cf + + * use_smtps: set to "yes" to enable smtps section at master.cf + + * mastercf_tail: set this for additional content to be added at the end of master.cf + +== Examples: + + class { 'postfix': } + + class { 'postfix': anon_sasl => 'yes', myorigin => 'foo.bar.tz' } + + postfix::config { "relay_domains": value => "localhost host.foo.com" } + + +Convience classes +================= + +postfix::config +--------------- +this can be used to pass arbitrary postfix configurations by passing the $name +to postconf to add/alter/remove options in main.cf + +Parameters: +- *name*: name of the parameter. +- *ensure*: present/absent. defaults to present. +- *value*: value of the parameter. +- *nonstandard*: inform postfix::config that this parameter is not recognized + by the "postconf" command. defaults to false. + +Requires: +- Class["postfix"] + +Example usage: + + postfix::config { + "smtp_use_tls" => "yes"; + "smtp_sasl_auth_enable" => "yes"; + "smtp_sasl_password_maps" => "hash:/etc/postfix/my_sasl_passwords"; + "relayhost" => "[mail.example.com]:587"; + } + + +postfix::disable +---------------- +If you include this class, the postfix package will be removed and the service +stopped. + + +postfix::hash +------------- +This can be used to create postfix hashed "map" files. It will create "${name}", +and then build "${name}.db" using the "postmap" command. The map file can then +be referred to using postfix::config. + +Parameters: +- *name*: the name of the map file. +- *ensure*: present/absent, defaults to present. +- *source*: file source. + +Requires: +- Class["postfix"] + +Example usage: + + postfix::hash { "/etc/postfix/virtual": + ensure => present, + } + postfix::config { "virtual_alias_maps": + value => "hash:/etc/postfix/virtual" + } + + +postfix::virtual +---------------- +Manages content of the /etc/postfix/virtual map + +Parameters: +- *name*: name of address postfix will lookup. See virtual(8). +- *destination*: where the emails will be delivered to. See virtual(8). +- *ensure*: present/absent, defaults to present. + +Requires: +- Class["postfix"] +- Postfix::Hash["/etc/postfix/virtual"] +- Postfix::Config["virtual_alias_maps"] +- common::line (from module common) + +Example usage: + + postfix::hash { "/etc/postfix/virtual": + ensure => present, + } + postfix::config { "virtual_alias_maps": + value => "hash:/etc/postfix/virtual" + } + postfix::virtual { "user@example.com": + ensure => present, + destination => "root", + } + +postfix::mailalias +------------------ +Wrapper around Puppet mailalias resource, provides newaliases executable. + +Parameters: +- *name*: the name of the alias. +- *ensure*: present/absent, defaults to present. +- *recipient*: recipient of the alias. + +Requires: +- Class["postfix"] + +Example usage: + + postfix::mailalias { "postmaster": + ensure => present, + recipient => 'foo' + } + diff --git a/puppet/modules/postfix/files/header_checks.d/.ignore b/puppet/modules/postfix/files/header_checks.d/.ignore new file mode 100644 index 00000000..e69de29b diff --git a/puppet/modules/postfix/files/main.cf b/puppet/modules/postfix/files/main.cf new file mode 100644 index 00000000..ec649c71 --- /dev/null +++ b/puppet/modules/postfix/files/main.cf @@ -0,0 +1 @@ +# file managed by puppet diff --git a/puppet/modules/postfix/files/tls_policy.d/.ignore b/puppet/modules/postfix/files/tls_policy.d/.ignore new file mode 100644 index 00000000..e69de29b diff --git a/puppet/modules/postfix/manifests/amavis.pp b/puppet/modules/postfix/manifests/amavis.pp new file mode 100644 index 00000000..b6639234 --- /dev/null +++ b/puppet/modules/postfix/manifests/amavis.pp @@ -0,0 +1,5 @@ +class postfix::amavis { + postfix::config { + "content_filter": value => "amavis:[127.0.0.1]:10024"; + } +} diff --git a/puppet/modules/postfix/manifests/anonsasl.pp b/puppet/modules/postfix/manifests/anonsasl.pp new file mode 100644 index 00000000..ca97f199 --- /dev/null +++ b/puppet/modules/postfix/manifests/anonsasl.pp @@ -0,0 +1,18 @@ +class postfix::anonsasl { + + include postfix::header_checks + + postfix::config { + 'smtpd_sasl_authenticated_header': + value => 'yes'; + } + + postfix::header_checks_snippet { + 'anonsasl': + content => template("postfix/anonsasl_header_checks.erb"), + require => [ + Postfix::Config['smtpd_sasl_authenticated_header'], + ]; + } + +} diff --git a/puppet/modules/postfix/manifests/config.pp b/puppet/modules/postfix/manifests/config.pp new file mode 100644 index 00000000..ce7af9e4 --- /dev/null +++ b/puppet/modules/postfix/manifests/config.pp @@ -0,0 +1,49 @@ +/* +== Definition: postfix::config + +Uses the "postconf" command to add/alter/remove options in postfix main +configuation file (/etc/postfix/main.cf). + +Parameters: +- *name*: name of the parameter. +- *ensure*: present/absent. defaults to present. +- *value*: value of the parameter. +- *nonstandard*: inform postfix::config that this parameter is not recognized + by the "postconf" command. defaults to false. + +Requires: +- Class["postfix"] + +Example usage: + + node "toto.example.com" { + + class { 'postfix': } + + postfix::config { + "smtp_use_tls" => "yes"; + "smtp_sasl_auth_enable" => "yes"; + "smtp_sasl_password_maps" => "hash:/etc/postfix/my_sasl_passwords"; + "relayhost" => "[mail.example.com]:587"; + } + } + +*/ +define postfix::config ($ensure = present, $value, $nonstandard = false) { + case $ensure { + present: { + exec {"postconf -e ${name}='${value}'": + unless => $nonstandard ? { + false => "test \"x$(postconf -h ${name})\" = 'x${value}'", + true => "test \"x$(egrep '^${name} ' /etc/postfix/main.cf | cut -d= -f2 | cut -d' ' -f2)\" = 'x${value}'", + }, + notify => Service["postfix"], + require => File["/etc/postfix/main.cf"], + } + } + + absent: { + fail "postfix::config ensure => absent: Not implemented" + } + } +} diff --git a/puppet/modules/postfix/manifests/disable.pp b/puppet/modules/postfix/manifests/disable.pp new file mode 100644 index 00000000..c233ec6d --- /dev/null +++ b/puppet/modules/postfix/manifests/disable.pp @@ -0,0 +1,7 @@ +# remove postfix +class postfix::disable { + case $::operatingsystem { + debian: { include postfix::disable::debian } + default: { include postfix::disable::base } + } +} diff --git a/puppet/modules/postfix/manifests/disable/base.pp b/puppet/modules/postfix/manifests/disable/base.pp new file mode 100644 index 00000000..5c56c709 --- /dev/null +++ b/puppet/modules/postfix/manifests/disable/base.pp @@ -0,0 +1,12 @@ +class postfix::disable::base { + + service{'postfix': + ensure => stopped, + enable => false, + } + package{'postfix': + ensure => absent, + require => Service['postfix'], + } + +} diff --git a/puppet/modules/postfix/manifests/disable/debian.pp b/puppet/modules/postfix/manifests/disable/debian.pp new file mode 100644 index 00000000..213efc50 --- /dev/null +++ b/puppet/modules/postfix/manifests/disable/debian.pp @@ -0,0 +1,11 @@ +# debian has some issues with absent +# init scripts. +# It's a bug in debian's provider that should be fixed in puppet, but in the +# meantime we need this hack. +# +# see: https://projects.puppetlabs.com/issues/9381 +class postfix::disable::debian inherits postfix::disable::base { + Service['postfix']{ + hasstatus => false, + } +} diff --git a/puppet/modules/postfix/manifests/hash.pp b/puppet/modules/postfix/manifests/hash.pp new file mode 100644 index 00000000..006f8815 --- /dev/null +++ b/puppet/modules/postfix/manifests/hash.pp @@ -0,0 +1,71 @@ +/* +== Definition: postfix::hash + +Creates postfix hashed "map" files. It will create "${name}", and then build +"${name}.db" using the "postmap" command. The map file can then be referred to +using postfix::config. + +Parameters: +- *name*: the name of the map file. +- *ensure*: present/absent, defaults to present. +- *source*: file source. + +Requires: +- Class["postfix"] + +Example usage: + + node "toto.example.com" { + + class { 'postfix': } + + postfix::hash { "/etc/postfix/virtual": + ensure => present, + } + postfix::config { "virtual_alias_maps": + value => "hash:/etc/postfix/virtual" + } + } + +*/ +define postfix::hash ($ensure="present", $source = false) { + include ::postfix + case $source { + false: { + file {"${name}": + ensure => $ensure, + mode => 600, + owner => root, + group => root, + seltype => $postfix::postfix_seltype, + require => Package["postfix"], + } + } + default: { + file {"${name}": + ensure => $ensure, + mode => 600, + owner => root, + group => root, + source => $source, + seltype => $postfix::postfix_seltype, + require => Package["postfix"], + } + } + } + + file {"${name}.db": + ensure => $ensure, + mode => 600, + require => [File["${name}"], Exec["generate ${name}.db"]], + seltype => $postfix::postfix_seltype, + } + + exec {"generate ${name}.db": + command => "postmap ${name}", + #creates => "${name}.db", # this prevents postmap from being run ! + subscribe => File["${name}"], + refreshonly => true, + require => Package["postfix"], + } +} diff --git a/puppet/modules/postfix/manifests/header_checks.pp b/puppet/modules/postfix/manifests/header_checks.pp new file mode 100644 index 00000000..5b0c3c86 --- /dev/null +++ b/puppet/modules/postfix/manifests/header_checks.pp @@ -0,0 +1,32 @@ +# +# == Class: postfix::header_checks +# +# Manages Postfix header_checks by merging snippets configured +# via postfix::header_checks_snippet defines +# +# Note that this class is useless when used directly. +# The postfix::header_checks_snippet defines takes care of importing +# it anyway. +# +class postfix::header_checks { + + concat { '/etc/postfix/header_checks': + owner => root, + group => root, + mode => '0600', + } + + postfix::config { "header_checks": + value => 'regexp:/etc/postfix/header_checks', + require => Concat['/etc/postfix/header_checks'], + } + + # Cleanup previous implementation's internal files + include common::moduledir + file { "${common::moduledir::module_dir_path}/postfix/header_checks": + ensure => absent, + recurse => true, + force => true, + } + +} diff --git a/puppet/modules/postfix/manifests/header_checks_snippet.pp b/puppet/modules/postfix/manifests/header_checks_snippet.pp new file mode 100644 index 00000000..05929a33 --- /dev/null +++ b/puppet/modules/postfix/manifests/header_checks_snippet.pp @@ -0,0 +1,60 @@ +/* +== Definition: postfix::header_checks_snippet + +Adds a header_checks snippets to /etc/postfix/header_checks. +See the postfix::header_checks class for details. + +Parameters: +- *source* or *content*: source or content of the header_checks snippet +- *ensure*: present (default) or absent + +Requires: +- Class["postfix"] + +Example usage: + + node "toto.example.com" { + class { 'postfix': } + postfix::header_checks_snippet { + 'wrong_date': content => 'FIXME'; + 'bla': source => 'puppet:///files/etc/postfix/header_checks.d/bla'; + } + } + +*/ + +define postfix::header_checks_snippet ( + $ensure = "present", + $source = '', + $content = undef +) { + + if $source == '' and $content == undef { + fail("One of \$source or \$content must be specified for postfix::header_checks_snippet ${name}") + } + + if $source != '' and $content != undef { + fail("Only one of \$source or \$content must specified for postfix::header_checks_snippet ${name}") + } + + include postfix::header_checks + + $fragment = "postfix_header_checks_${name}" + + concat::fragment { "$fragment": + ensure => "$ensure", + target => '/etc/postfix/header_checks', + } + + if $source { + Concat::Fragment["$fragment"] { + source => $source, + } + } + else { + Concat::Fragment["$fragment"] { + content => $content, + } + } + +} diff --git a/puppet/modules/postfix/manifests/init.pp b/puppet/modules/postfix/manifests/init.pp new file mode 100644 index 00000000..45c8e0c9 --- /dev/null +++ b/puppet/modules/postfix/manifests/init.pp @@ -0,0 +1,221 @@ +# +# == Class: postfix +# +# This class provides a basic setup of postfix with local and remote +# delivery and an SMTP server listening on the loopback interface. +# +# Parameters: +# - *$smtp_listen*: address on which the smtp service will listen to. defaults to 127.0.0.1 +# - *$root_mail_recipient*: who will recieve root's emails. defaults to "nobody" +# - *$anon_sasl*: set $anon_sasl="yes" to hide the originating IP in email +# - *$manage_header_checks*: manage header checks +# - *$manage_tls_policy*: manage tls policy +# - *$manage_transport_regexp*: manage transport regexps +# - *$manage_virtual_regexp*: manage virtual regexps +# - *$tls_fingerprint_digest*: fingerprint digest for tls policy class +# - *$use_amavisd*: set to "yes" to configure amavis +# - *$use_dovecot_lda*: include dovecot declaration at master.cf +# - *$use_schleuder*: whether to include schleuder portion at master.cf +# - *$use_sympa*: whether to include sympa portion at master.cf +# - *$use_firma*: whether to include firma portion at master.cf +# - *$use_mlmmj*: whether to include mlmmj portion at master.cf +# - *$use_submission*: set to "yes" to enable submission section at master.cf +# - *$use_smtps*: set to "yes" to enable smtps section at master.cf +# - *$mastercf_tail*: set this for additional content to be added at the end of master.cf +# - *$inet_interfaces*: which inet interface postfix should listen on +# - *$myorigin*: sets postfix $myorigin configuration +# +# Example usage: +# +# node "toto.example.com" { +# class { 'postfix': +# smtp_listen => "192.168.1.10" +# } +# } +# +class postfix( + $smtp_listen = '127.0.0.1', + $root_mail_recipient = 'nobody', + $anon_sasl = 'no', + $manage_header_checks = 'no', + $manage_tls_policy = 'no', + $manage_transport_regexp = 'no', + $manage_virtual_regexp = 'no', + $tls_fingerprint_digest = 'sha1', + $use_amavisd = 'no', + $use_dovecot_lda = 'no', + $use_schleuder = 'no', + $use_sympa = 'no', + $use_firma = 'no', + $use_mlmmj = 'no', + $use_postscreen = 'no', + $use_submission = 'no', + $use_smtps = 'no', + $mastercf_tail = '', + $inet_interfaces = 'all', + $myorigin = $::fqdn, + $mailname = $::fqdn, + $preseed = false, + $default_alias_maps = true +) { + + case $::operatingsystem { + + 'RedHat', 'CentOS': { + $master_cf_template = 'postfix/master.cf.redhat5.erb' + + # selinux labels differ from one distribution to another + case $::operatingsystemmajrelease { + '4': { $postfix_seltype = 'etc_t' } + '5': { $postfix_seltype = 'postfix_etc_t' } + default: { $postfix_seltype = undef } + } + + postfix::config { + 'sendmail_path': value => '/usr/sbin/sendmail.postfix'; + 'newaliases_path': value => '/usr/bin/newaliases.postfix'; + 'mailq_path': value => '/usr/bin/mailq.postfix'; + } + } + + 'Debian': { + case $::operatingsystemrelease { + /^5.*/: { + $master_cf_template = 'postfix/master.cf.debian-5.erb' + } + /^6.*/: { + $master_cf_template = 'postfix/master.cf.debian-6.erb' + } + /^7.*/: { + $master_cf_template = 'postfix/master.cf.debian-7.erb' + } + default: { + $master_cf_template = "postfix/master.cf.debian-${::operatingsystemmajrelease}.erb" + } + } + } + + 'Ubuntu': { + $master_cf_template = 'postfix/master.cf.debian-sid.erb' + } + + default: { + $postfix_seltype = undef + $master_cf_template = undef + } + } + + + # Bootstrap moduledir + include common::moduledir + common::module_dir{'postfix': } + + # Include optional classes + if $anon_sasl == 'yes' { + include postfix::anonsasl + } + # this global variable needs to get parameterized as well + if $::header_checks == 'yes' { + include postfix::header_checks + } + if $manage_tls_policy == 'yes' { + class { 'postfix::tlspolicy': + fingerprint_digest => $tls_fingerprint_digest, + } + } + if $use_amavisd == 'yes' { + include postfix::amavis + } + if $manage_transport_regexp == 'yes' { + include postfix::transport_regexp + } + if $manage_virtual_regexp == 'yes' { + include postfix::virtual_regexp + } + + package { 'mailx': + ensure => installed + } + + if ( $preseed ) { + apt::preseeded_package { 'postfix': + ensure => installed, + } + } else { + package { 'postfix': + ensure => installed + } + } + + if $::operatingsystem == 'debian' { + Package[mailx] { name => 'bsd-mailx' } + } + + service { 'postfix': + ensure => running, + require => Package['postfix'], + } + + file { '/etc/mailname': + ensure => present, + content => "${::fqdn}\n", + seltype => $postfix_seltype, + } + + # Aliases + file { '/etc/aliases': + ensure => present, + content => "# file managed by puppet\n", + replace => false, + seltype => $postfix_seltype, + notify => Exec['newaliases'], + } + + # Aliases + exec { 'newaliases': + command => '/usr/bin/newaliases', + refreshonly => true, + require => Package['postfix'], + subscribe => File['/etc/aliases'], + } + + # Config files + file { '/etc/postfix/master.cf': + ensure => present, + owner => 'root', + group => 'root', + mode => '0644', + content => template($master_cf_template), + seltype => $postfix_seltype, + notify => Service['postfix'], + require => Package['postfix'], + } + + # Config files + file { '/etc/postfix/main.cf': + ensure => present, + owner => 'root', + group => 'root', + mode => '0644', + source => 'puppet:///modules/postfix/main.cf', + replace => false, + seltype => $postfix_seltype, + notify => Service['postfix'], + require => Package['postfix'], + } + + # Default configuration parameters + if $default_alias_maps { + postfix::config { + 'alias_maps': value => 'hash:/etc/aliases'; + } + } + postfix::config { + 'myorigin': value => $myorigin; + 'inet_interfaces': value => $inet_interfaces; + } + + postfix::mailalias {'root': + recipient => $root_mail_recipient, + } +} diff --git a/puppet/modules/postfix/manifests/mailalias.pp b/puppet/modules/postfix/manifests/mailalias.pp new file mode 100644 index 00000000..2f239ac3 --- /dev/null +++ b/puppet/modules/postfix/manifests/mailalias.pp @@ -0,0 +1,32 @@ +/* +== Definition: postfix::mailalias + +Wrapper around Puppet mailalias resource, provides newaliases executable. + +Parameters: +- *name*: the name of the alias. +- *ensure*: present/absent, defaults to present. +- *recipient*: recipient of the alias. + +Requires: +- Class["postfix"] + +Example usage: + + node "toto.example.com" { + + class { 'postfix': } + + postfix::mailalias { "postmaster": + ensure => present, + recipient => 'foo' + } + +*/ +define postfix::mailalias ($ensure = 'present', $recipient) { + mailalias { "${name}": + ensure => $ensure, + recipient => $recipient, + notify => Exec['newaliases'] + } +} diff --git a/puppet/modules/postfix/manifests/mailman.pp b/puppet/modules/postfix/manifests/mailman.pp new file mode 100644 index 00000000..8c6ee32c --- /dev/null +++ b/puppet/modules/postfix/manifests/mailman.pp @@ -0,0 +1,34 @@ +# +# == Class: postfix::mailman +# +# Configures a basic smtp server, able to work for the mailman mailing-list +# manager. +# +# Example usage: +# +# node "toto.example.com" { +# include mailman +# class { 'postfix::mailman': } +# } +# +class postfix::mailman { + class { 'postfix': + smtp_listen => "0.0.0.0", + } + + postfix::config { + "mydestination": value => ""; + "virtual_alias_maps": value => "hash:/etc/postfix/virtual"; + "transport_maps": value => "hash:/etc/postfix/transport"; + "mailman_destination_recipient_limit": value => "1", nonstandard => true; + } + + postfix::hash { "/etc/postfix/virtual": + ensure => present, + } + + postfix::hash { "/etc/postfix/transport": + ensure => present, + } + +} diff --git a/puppet/modules/postfix/manifests/mta.pp b/puppet/modules/postfix/manifests/mta.pp new file mode 100644 index 00000000..f7a865db --- /dev/null +++ b/puppet/modules/postfix/manifests/mta.pp @@ -0,0 +1,70 @@ +# +# == Class: postfix::mta +# +# This class configures a minimal MTA, listening on +# $postfix_smtp_listen (default to localhost) and delivering mail to +# $postfix_mydestination (default to $fqdn). +# +# A valid relay host is required ($postfix_relayhost) for outbound email. +# +# transport & virtual maps get configured and can be populated with +# postfix::transport and postfix::virtual +# +# Parameters: +# - *$postfix_relayhost* +# - *$postfix_mydestination* +# - every global variable which works for class "postfix" will work here. +# +# Requires: +# - Class["postfix"] +# +# Example usage: +# +# node "toto.example.com" { +# +# class { 'postfix': +# smtp_listen => "0.0.0.0", +# } +# +# class { 'postfix::mta': +# relayhost => "mail.example.com", +# mydestination => "\$myorigin, myapp.example.com", +# } +# +# postfix::transport { "myapp.example.com": +# ensure => present, +# destination => "local:", +# } +# } +# +class postfix::mta( + $mydestination = '', + $relayhost = '' +) { + + #case $relayhost { + # "": { fail("Required relayhost parameter is not defined.") } + #} + + case $mydestination { + "": { $postfix_mydestination = "\$myorigin" } + default: { $postfix_mydestination = "$mydestination" } + } + + postfix::config { + "mydestination": value => $postfix_mydestination; + "mynetworks": value => "127.0.0.0/8"; + "relayhost": value => $relayhost; + "virtual_alias_maps": value => "hash:/etc/postfix/virtual"; + "transport_maps": value => "hash:/etc/postfix/transport"; + } + + postfix::hash { "/etc/postfix/virtual": + ensure => present, + } + + postfix::hash { "/etc/postfix/transport": + ensure => present, + } + +} diff --git a/puppet/modules/postfix/manifests/satellite.pp b/puppet/modules/postfix/manifests/satellite.pp new file mode 100644 index 00000000..c6c1a0e4 --- /dev/null +++ b/puppet/modules/postfix/manifests/satellite.pp @@ -0,0 +1,49 @@ +# +# == Class: postfix::satellite +# +# This class configures all local email (cron, mdadm, etc) to be forwarded +# to $root_mail_recipient, using $postfix_relayhost as a relay. +# +# $valid_fqdn can be set to override $fqdn in the case where the FQDN is +# not recognized as valid by the destination server. +# +# Parameters: +# - *valid_fqdn* +# - every global variable which works for class "postfix" will work here. +# +# Example usage: +# +# node "toto.local.lan" { +# class { 'postfix::satellite': +# relayhost => "mail.example.com" +# valid_fqdn => "toto.example.com" +# root_mail_recipient => "the.sysadmin@example.com" +# } +# } +# +class postfix::satellite( + $relayhost = '', + $valid_fqdn = $::fqdn, + $root_mail_recipient = '' +) { + + # If $valid_fqdn is provided, use it to override $fqdn + if $valid_fqdn != $::fdqn { + $fqdn = $valid_fqdn + } + + class { 'postfix': + root_mail_recipient => $root_mail_recipient, + myorigin => $valid_fqdn, + mailname => $valid_fqdn + } + + class { 'postfix::mta': + relayhost => $relayhost, + } + + postfix::virtual {"@${valid_fqdn}": + ensure => present, + destination => "root", + } +} diff --git a/puppet/modules/postfix/manifests/smtp_auth.pp b/puppet/modules/postfix/manifests/smtp_auth.pp new file mode 100644 index 00000000..b553fb5b --- /dev/null +++ b/puppet/modules/postfix/manifests/smtp_auth.pp @@ -0,0 +1,37 @@ +# == Definition: postfix::smtp_auth +# +# Manages content of the /etc/postfix/smtp_auth map. +# +# Requires: +# - Class["postfix"] +# - Postfix::Hash["/etc/postfix/smtp_auth"] +# - file_line (from puppetlab's stdlib module) +# +# Example usage: +# +# node 'toto.example.com' { +# +# include postfix +# +# postfix::hash { '/etc/postfix/smtp_auth': +# ensure => present, +# } +# postfix::config { 'smtp_auth_maps': +# value => 'hash:/etc/postfix/smtp_auth' +# } +# postfix::smtp_auth { 'gmail.com': +# ensure => present, +# user => 'USER', +# password => 'PW', +# } +# } + +define postfix::smtp_auth ($user, $password, $ensure=present) { + file_line { $name: + ensure => $ensure, + path => '/etc/postfix/smtp_auth', + line => "${name} ${user}:${password}", + notify => Exec['generate /etc/postfix/smtp_auth.db'], + require => Package['postfix'], + } +} diff --git a/puppet/modules/postfix/manifests/tlspolicy.pp b/puppet/modules/postfix/manifests/tlspolicy.pp new file mode 100644 index 00000000..d9017108 --- /dev/null +++ b/puppet/modules/postfix/manifests/tlspolicy.pp @@ -0,0 +1,55 @@ +# +# == Class: postfix::tlspolicy +# +# Manages Postfix TLS policy by merging policy snippets configured +# via postfix::tlspolicy_snippet defines +# +# Parameters: +# - $fingerprint_digest (defaults to sha1) +# +# Note that this class is useless when used directly. +# The postfix::tlspolicy_snippet defines takes care of importing +# it anyway. +# +class postfix::tlspolicy( + $fingerprint_digest = 'sha1' +) { + + include common::moduledir + common::module_dir{'postfix/tls_policy': } + + $postfix_tlspolicy_dir = "${common::moduledir::module_dir_path}/postfix/tls_policy" + $postfix_merged_tlspolicy = "${postfix_tlspolicy_dir}/merged_tls_policy" + + concat { "$postfix_merged_tlspolicy": + require => File[$postfix_tlspolicy_dir], + owner => root, + group => root, + mode => '0600', + } + + postfix::hash { '/etc/postfix/tls_policy': + source => "$postfix_merged_tlspolicy", + subscribe => File["$postfix_merged_tlspolicy"], + } + + postfix::config { + 'smtp_tls_fingerprint_digest': value => "$fingerprint_digest"; + } + + postfix::config { 'smtp_tls_policy_maps': + value => 'hash:/etc/postfix/tls_policy', + require => [ + Postfix::Hash['/etc/postfix/tls_policy'], + Postfix::Config['smtp_tls_fingerprint_digest'], + ], + } + + # Cleanup previous implementation's internal files + file { "${postfix_tlspolicy_dir}/tls_policy.d": + ensure => absent, + recurse => true, + force => true, + } + +} diff --git a/puppet/modules/postfix/manifests/tlspolicy_snippet.pp b/puppet/modules/postfix/manifests/tlspolicy_snippet.pp new file mode 100644 index 00000000..b63f812c --- /dev/null +++ b/puppet/modules/postfix/manifests/tlspolicy_snippet.pp @@ -0,0 +1,45 @@ +/* +== Definition: postfix::tlspolicy_snippet + +Adds a TLS policy snippets to /etc/postfix/tls_policy. +See the postfix::tlspolicy class for details. + +Parameters: +- *name*: name of destination domain Postfix will lookup. See TLS_README. +- *value*: right-hand part of the tls_policy map +- *ensure*: present/absent, defaults to present. + +Requires: +- Class["postfix"] +- Class["postfix::tlspolicy"] + +Example usage: + + node "toto.example.com" { + class { 'postfix': + manage_tls_policy => 'yes', + } + postfix::tlspolicy_snippet { + 'example.com': value => 'encrypt'; + '.example.com': value => 'encrypt'; + 'nothing.com': value => 'fingerprint match=2A:FF:F0:EC:52:04:99:45:73:1B:C2:22:7F:FD:31:6B:8F:07:43:29'; + } + } + +*/ + +define postfix::tlspolicy_snippet ($ensure="present", $value = false) { + + if ($value == false) and ($ensure == "present") { + fail("The value parameter must be set when using the postfix::tlspolicy_snippet define with ensure=present.") + } + + include postfix::tlspolicy + + concat::fragment { "postfix_tlspolicy_${name}": + ensure => "$ensure", + content => "${name} ${value}\n", + target => "$postfix::tlspolicy::postfix_merged_tlspolicy", + } + +} diff --git a/puppet/modules/postfix/manifests/transport.pp b/puppet/modules/postfix/manifests/transport.pp new file mode 100644 index 00000000..08b93e5e --- /dev/null +++ b/puppet/modules/postfix/manifests/transport.pp @@ -0,0 +1,44 @@ +/* +== Definition: postfix::transport + +Manages content of the /etc/postfix/transport map. + +Parameters: +- *name*: name of address postfix will lookup. See transport(5). +- *destination*: where the emails will be delivered to. See transport(5). +- *ensure*: present/absent, defaults to present. + +Requires: +- Class["postfix"] +- Postfix::Hash["/etc/postfix/transport"] +- Postfix::Config["transport_maps"] +- file_line (from module stdlib) + +Example usage: + + node "toto.example.com" { + + class { 'postfix': } + + postfix::hash { "/etc/postfix/transport": + ensure => present, + } + postfix::config { "transport_maps": + value => "hash:/etc/postfix/transport" + } + postfix::transport { "mailman.example.com": + ensure => present, + destination => "mailman", + } + } + +*/ +define postfix::transport ($ensure="present", $destination) { + file_line {"${name} ${destination}": + ensure => $ensure, + path => "/etc/postfix/transport", + line => "${name} ${destination}", + notify => Exec["generate /etc/postfix/transport.db"], + require => Package["postfix"], + } +} diff --git a/puppet/modules/postfix/manifests/transport_regexp.pp b/puppet/modules/postfix/manifests/transport_regexp.pp new file mode 100644 index 00000000..4961141e --- /dev/null +++ b/puppet/modules/postfix/manifests/transport_regexp.pp @@ -0,0 +1,56 @@ +# +# == Class: postfix::transport_regexp +# +# Manages Postfix transport_regexp by merging snippets shipped: +# - in the module's files/transport_regexp.d/ or puppet:///files/etc/postfix/transport_regexp.d +# (the latter takes precedence if present); site_postfix module is supported +# as well, see the source argument of file {"$postfix_transport_regexp_snippets_dir" +# bellow for details. +# - via postfix::transport_regexp_snippet defines +# +# Example usage: +# +# node "toto.example.com" { +# class { 'postfix': +# manage_transport_regexp => 'yes', +# } +# postfix::config { "transport_maps": +# value => "hash:/etc/postfix/transport, regexp:/etc/postfix/transport_regexp", +# } +# } +# +class postfix::transport_regexp { + + include common::moduledir + common::module_dir{'postfix/transport_regexp': } + + $postfix_transport_regexp_dir = "${common::moduledir::module_dir_path}/postfix/transport_regexp" + $postfix_transport_regexp_snippets_dir = "${postfix_transport_regexp_dir}/transport_regexp.d" + $postfix_merged_transport_regexp = "${postfix_transport_regexp_dir}/merged_transport_regexp" + + file {"$postfix_transport_regexp_snippets_dir": + ensure => 'directory', + owner => 'root', + group => '0', + mode => '700', + source => [ + "puppet:///modules/site_postfix/${fqdn}/transport_regexp.d", + "puppet:///modules/site_postfix/transport_regexp.d", + "puppet:///files/etc/postfix/transport_regexp.d", + "puppet:///modules/postfix/transport_regexp.d", + ], + recurse => true, + purge => false, + } + + concatenated_file { "$postfix_merged_transport_regexp": + dir => "${postfix_transport_regexp_snippets_dir}", + require => File["$postfix_transport_regexp_snippets_dir"], + } + + config_file { '/etc/postfix/transport_regexp': + source => "$postfix_merged_transport_regexp", + subscribe => File["$postfix_merged_transport_regexp"], + } + +} diff --git a/puppet/modules/postfix/manifests/transport_regexp_snippet.pp b/puppet/modules/postfix/manifests/transport_regexp_snippet.pp new file mode 100644 index 00000000..2b13ed14 --- /dev/null +++ b/puppet/modules/postfix/manifests/transport_regexp_snippet.pp @@ -0,0 +1,67 @@ +/* +== Definition: postfix::transport_regexp_snippet + +Adds a transport_regexp snippets to /etc/postfix/transport_regexp. +See the postfix::transport_regexp class for details. + +Parameters: +- *source* or *content*: source or content of the transport_regexp snippet +- *ensure*: present (default) or absent + +Requires: +- Class["postfix"] + +Example usage: + + node "toto.example.com" { + class { 'postfix': } + postfix::transport_regexp { + 'wrong_date': content => 'FIXME'; + 'bla': source => 'puppet:///files/etc/postfix/transport_regexp.d/bla'; + } + } + +*/ + +define postfix::transport_regexp_snippet ( + $ensure = "present", + $source = '', + $content = undef +) { + + if $source == '' and $content == undef { + fail("One of \$source or \$content must be specified for postfix::transport_regexp_snippet ${name}") + } + + if $source != '' and $content != undef { + fail("Only one of \$source or \$content must specified for postfix::transport_regexp_snippet ${name}") + } + + if ($value == false) and ($ensure == "present") { + fail("The value parameter must be set when using the postfix::transport_regexp_snippet define with ensure=present.") + } + + include postfix::transport_regexp + + $snippetfile = "${postfix::transport_regexp::postfix_transport_regexp_snippets_dir}/${name}" + + file { "$snippetfile": + ensure => "$ensure", + mode => 600, + owner => root, + group => 0, + notify => Exec["concat_${postfix::transport_regexp::postfix_merged_transport_regexp}"], + } + + if $source { + File["$snippetfile"] { + source => $source, + } + } + else { + File["$snippetfile"] { + content => $content, + } + } + +} diff --git a/puppet/modules/postfix/manifests/virtual.pp b/puppet/modules/postfix/manifests/virtual.pp new file mode 100644 index 00000000..06df32ad --- /dev/null +++ b/puppet/modules/postfix/manifests/virtual.pp @@ -0,0 +1,44 @@ +/* +== Definition: postfix::virtual + +Manages content of the /etc/postfix/virtual map. + +Parameters: +- *name*: name of address postfix will lookup. See virtual(8). +- *destination*: where the emails will be delivered to. See virtual(8). +- *ensure*: present/absent, defaults to present. + +Requires: +- Class["postfix"] +- Postfix::Hash["/etc/postfix/virtual"] +- Postfix::Config["virtual_alias_maps"] +- file_line (from module stdlib) + +Example usage: + + node "toto.example.com" { + + class { 'postfix': } + + postfix::hash { "/etc/postfix/virtual": + ensure => present, + } + postfix::config { "virtual_alias_maps": + value => "hash:/etc/postfix/virtual" + } + postfix::virtual { "user@example.com": + ensure => present, + destination => "root", + } + } + +*/ +define postfix::virtual ($ensure="present", $destination) { + file_line {"${name} ${destination}": + ensure => $ensure, + path => "/etc/postfix/virtual", + line => "${name} ${destination}", + notify => Exec["generate /etc/postfix/virtual.db"], + require => Package["postfix"], + } +} diff --git a/puppet/modules/postfix/manifests/virtual_regexp.pp b/puppet/modules/postfix/manifests/virtual_regexp.pp new file mode 100644 index 00000000..18bbd8ce --- /dev/null +++ b/puppet/modules/postfix/manifests/virtual_regexp.pp @@ -0,0 +1,56 @@ +# +# == Class: postfix::virtual_regexp +# +# Manages Postfix virtual_regexp by merging snippets shipped: +# - in the module's files/virtual_regexp.d/ or puppet:///files/etc/postfix/virtual_regexp.d +# (the latter takes precedence if present); site_postfix module is supported +# as well, see the source argument of file {"$postfix_virtual_regexp_snippets_dir" +# bellow for details. +# - via postfix::virtual_regexp_snippet defines +# +# Example usage: +# +# node "toto.example.com" { +# class { 'postfix': +# manage_virtual_regexp => 'yes', +# } +# postfix::config { "virtual_alias_maps": +# value => 'hash://postfix/virtual, regexp:/etc/postfix/virtual_regexp', +# } +# } +# +class postfix::virtual_regexp { + + include common::moduledir + common::module_dir{'postfix/virtual_regexp': } + + $postfix_virtual_regexp_dir = "${common::moduledir::module_dir_path}/postfix/virtual_regexp" + $postfix_virtual_regexp_snippets_dir = "${postfix_virtual_regexp_dir}/virtual_regexp.d" + $postfix_merged_virtual_regexp = "${postfix_virtual_regexp_dir}/merged_virtual_regexp" + + file {"$postfix_virtual_regexp_snippets_dir": + ensure => 'directory', + owner => 'root', + group => '0', + mode => '700', + source => [ + "puppet:///modules/site_postfix/${fqdn}/virtual_regexp.d", + "puppet:///modules/site_postfix/virtual_regexp.d", + "puppet:///files/etc/postfix/virtual_regexp.d", + "puppet:///modules/postfix/virtual_regexp.d", + ], + recurse => true, + purge => false, + } + + concatenated_file { "$postfix_merged_virtual_regexp": + dir => "${postfix_virtual_regexp_snippets_dir}", + require => File["$postfix_virtual_regexp_snippets_dir"], + } + + config_file { '/etc/postfix/virtual_regexp': + source => "$postfix_merged_virtual_regexp", + subscribe => File["$postfix_merged_virtual_regexp"], + } + +} diff --git a/puppet/modules/postfix/manifests/virtual_regexp_snippet.pp b/puppet/modules/postfix/manifests/virtual_regexp_snippet.pp new file mode 100644 index 00000000..bd9a982d --- /dev/null +++ b/puppet/modules/postfix/manifests/virtual_regexp_snippet.pp @@ -0,0 +1,67 @@ +/* +== Definition: postfix::virtual_regexp_snippet + +Adds a virtual_regexp snippets to /etc/postfix/virtual_regexp. +See the postfix::virtual_regexp class for details. + +Parameters: +- *source* or *content*: source or content of the virtual_regexp snippet +- *ensure*: present (default) or absent + +Requires: +- Class["postfix"] + +Example usage: + + node "toto.example.com" { + class { 'postfix': } + postfix::virtual_regexp { + 'wrong_date': content => 'FIXME'; + 'bla': source => 'puppet:///files/etc/postfix/virtual_regexp.d/bla'; + } + } + +*/ + +define postfix::virtual_regexp_snippet ( + $ensure = "present", + $source = '', + $content = undef +) { + + if $source == '' and $content == undef { + fail("One of \$source or \$content must be specified for postfix::virtual_regexp_snippet ${name}") + } + + if $source != '' and $content != undef { + fail("Only one of \$source or \$content must specified for postfix::virtual_regexp_snippet ${name}") + } + + if ($value == false) and ($ensure == "present") { + fail("The value parameter must be set when using the postfix::virtual_regexp_snippet define with ensure=present.") + } + + include postfix::virtual_regexp + + $snippetfile = "${postfix::virtual_regexp::postfix_virtual_regexp_snippets_dir}/${name}" + + file { "$snippetfile": + ensure => "$ensure", + mode => 600, + owner => root, + group => 0, + notify => Exec["concat_${postfix::virtual_regexp::postfix_merged_virtual_regexp}"], + } + + if $source { + File["$snippetfile"] { + source => $source, + } + } + else { + File["$snippetfile"] { + content => $content, + } + } + +} diff --git a/puppet/modules/postfix/templates/anonsasl_header_checks.erb b/puppet/modules/postfix/templates/anonsasl_header_checks.erb new file mode 100644 index 00000000..bca59146 --- /dev/null +++ b/puppet/modules/postfix/templates/anonsasl_header_checks.erb @@ -0,0 +1,2 @@ +/^Received: from (.* \([-._[:alnum:]]+ \[[.[:digit:]]{7,15}\]\)).*?([[:space:]]+).*\(Authenticated sender: ([^)]+)\).*by (<%= fqdn.gsub(/\./, '\.') %>) \(([^)]+)\) with (E?SMTPS?A?) id ([A-F[:digit:]]+).*/ + REPLACE Received: from [127.0.0.1] (localhost [127.0.0.1])$2(Authenticated sender: $3)${2}with $6 id $7 diff --git a/puppet/modules/postfix/templates/master.cf.debian-5.erb b/puppet/modules/postfix/templates/master.cf.debian-5.erb new file mode 100644 index 00000000..50241b8b --- /dev/null +++ b/puppet/modules/postfix/templates/master.cf.debian-5.erb @@ -0,0 +1,126 @@ +# file managed by puppet +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master"). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== +<% if smtp_listen == 'all' %>smtp inet n - - - - smtpd +<% else %><%= smtp_listen %>:smtp inet n - - - - smtpd<% end %> +<% if use_submission == 'yes' %>submission inet n - - - - smtpd + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +<% end %> +<% if use_smtps == 'yes' %>smtps inet n - - - - smtpd + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +<% end %> +#628 inet n - - - - qmqpd +pickup fifo n - - 60 1 pickup +cleanup unix n - - - 0 cleanup +qmgr fifo n - n 300 1 qmgr +#qmgr fifo n - - 300 1 oqmgr +tlsmgr unix - - - 1000? 1 tlsmgr +rewrite unix - - - - - trivial-rewrite +bounce unix - - - - 0 bounce +defer unix - - - - 0 bounce +trace unix - - - - 0 bounce +verify unix - - - - 1 verify +flush unix n - - 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - - - - smtp +# When relaying mail as backup MX, disable fallback_relay to avoid MX loops +relay unix - - - - - smtp + -o smtp_fallback_relay= +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - - - - showq +error unix - - - - - error +retry unix - - - - - error +discard unix - - - - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - - - - lmtp +anvil unix - - - - 1 anvil +scache unix - - - - 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/bin/maildrop -d ${recipient} +# +# 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=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $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} +<% if use_amavisd == 'yes' %> +amavis unix - - - - 2 smtp + -o smtp_data_done_timeout=1200 + -o smtp_send_xforward_command=yes + +127.0.0.1:10025 inet n - - - - smtpd + -o content_filter= + -o local_recipient_maps= + -o relay_recipient_maps= + -o smtpd_restriction_classes= + -o smtpd_client_restrictions= + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o mynetworks=127.0.0.0/8 + -o strict_rfc821_envelopes=yes + -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks + -o smtpd_bind_address=127.0.0.1 +<% end %> +<% if use_dovecot_lda == 'yes' %> +dovecot unix - n n - - pipe + flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop} -n -m ${extension} +<% end %> +<% if use_schleuder == 'yes' %> +schleuder unix - n n - - pipe + flags=DRhu user=schleuder argv=/usr/bin/schleuder ${user} +<% end %> +<% if use_sympa == 'yes' %> +sympa unix - n n - - pipe + flags=R user=sympa argv=/usr/lib/sympa/bin/queue ${recipient} +sympabounce unix - n n - - pipe + flags=R user=sympa argv=/usr/lib/sympa/bin/bouncequeue ${user} +<% end %> +<% if use_mlmmj == 'yes' %> +mlmmj unix - n n - - pipe + flags=DORhu user=mlmmj argv=/usr/bin/mlmmj-recieve -F -L /var/spool/mlmmj/$nexthop/ +<%- end -%> + +<%- unless mastercf_tail.to_s.empty? then -%> +<%= mastercf_tail %> +<%- end -%> diff --git a/puppet/modules/postfix/templates/master.cf.debian-6.erb b/puppet/modules/postfix/templates/master.cf.debian-6.erb new file mode 100644 index 00000000..9ce32647 --- /dev/null +++ b/puppet/modules/postfix/templates/master.cf.debian-6.erb @@ -0,0 +1,158 @@ +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master"). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== +<% if smtp_listen == 'all' %>smtp inet n - - - - smtpd +<% else %><%= smtp_listen %>:smtp inet n - - - - smtpd<% end %> +<% if use_submission == 'yes' %>submission inet n - - - - smtpd + -o smtpd_enforce_tls=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject +<% end %> +#smtp inet n - - - 1 postscreen +#smtpd pass - - - - - smtpd +#dnsblog unix - - - - 0 dnsblog +# -o smtpd_tls_security_level=encrypt +# -o smtpd_sasl_auth_enable=yes +# -o smtpd_client_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING +<% if use_smtps == 'yes' %>smtps inet n - - - - smtpd + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +<% end %> +#628 inet n - - - - qmqpd +pickup fifo n - - 60 1 pickup +cleanup unix n - - - 0 cleanup +qmgr fifo n - n 300 1 qmgr +#qmgr fifo n - - 300 1 oqmgr +tlsmgr unix - - - 1000? 1 tlsmgr +rewrite unix - - - - - trivial-rewrite +bounce unix - - - - 0 bounce +defer unix - - - - 0 bounce +trace unix - - - - 0 bounce +verify unix - - - - 1 verify +flush unix n - - 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - - - - smtp +# When relaying mail as backup MX, disable fallback_relay to avoid MX loops +relay unix - - - - - smtp + -o smtp_fallback_relay= +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - - - - showq +error unix - - - - - error +retry unix - - - - - error +discard unix - - - - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - - - - lmtp +anvil unix - - - - 1 anvil +scache unix - - - - 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/bin/maildrop -d ${recipient} +# +# ==================================================================== +# +# Recent Cyrus versions can use the existing "lmtp" master.cf entry. +# +# Specify in cyrus.conf: +# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 +# +# Specify in main.cf one or more of the following: +# mailbox_transport = lmtp:inet:localhost +# virtual_transport = lmtp:inet:localhost +# +# ==================================================================== +# +# Cyrus 2.1.5 (Amos Gouaux) +# Also specify in main.cf: cyrus_destination_recipient_limit=1 +# +#cyrus unix - n n - - pipe +# user=cyrus argv=/cyrus/bin/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=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $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} +<% if use_amavisd == 'yes' %> +amavis unix - - - - 2 smtp + -o smtp_data_done_timeout=1200 + -o smtp_send_xforward_command=yes + +127.0.0.1:10025 inet n - - - - smtpd + -o content_filter= + -o local_recipient_maps= + -o relay_recipient_maps= + -o smtpd_restriction_classes= + -o smtpd_client_restrictions= + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o mynetworks=127.0.0.0/8 + -o strict_rfc821_envelopes=yes + -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks + -o smtpd_bind_address=127.0.0.1 +<% end %> +<% if use_dovecot_lda == 'yes' %> +dovecot unix - n n - - pipe + flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop} -n -m ${extension} +<% end %> +<% if use_schleuder == 'yes' %> +schleuder unix - n n - - pipe + flags=DRhu user=schleuder argv=/usr/bin/schleuder ${user} +<% end %> +<% if use_sympa == 'yes' %> +sympa unix - n n - - pipe + flags=R user=sympa argv=/usr/lib/sympa/bin/queue ${recipient} +sympabounce unix - n n - - pipe + flags=R user=sympa argv=/usr/lib/sympa/bin/bouncequeue ${user} +<% end %> +<% if use_mlmmj == 'yes' %> +mlmmj unix - n n - - pipe + flags=DORhu user=mlmmj argv=/usr/bin/mlmmj-recieve -F -L /var/spool/mlmmj/$nexthop/ +<%- end -%> +<% if use_firma == 'yes' %> +firma unix - n n - - pipe + flags=DRhu user=firma argv=/var/lib/firma/firma -p ${user} +firmarequest unix - n n - - pipe + flags=DRhu user=firma argv=/var/lib/firma/firma -e ${user} +<% end %> + +<%- unless mastercf_tail.to_s.empty? then -%> +<%= mastercf_tail %> +<%- end -%> diff --git a/puppet/modules/postfix/templates/master.cf.debian-7.erb b/puppet/modules/postfix/templates/master.cf.debian-7.erb new file mode 100644 index 00000000..d243a93e --- /dev/null +++ b/puppet/modules/postfix/templates/master.cf.debian-7.erb @@ -0,0 +1,161 @@ +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master"). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== +# +<% if @use_postscreen == 'yes' and @smtp_listen == 'all' %>smtpd pass - - n - - smtpd +smtp inet n - n - 1 postscreen +tlsproxy unix - - n - 0 tlsproxy +<% elsif @use_postscreen == 'no' and @smtp_listen == 'all' %>smtp inet n - - - - smtpd +<% else %><%= @smtp_listen %>:smtp inet n - - - - smtpd<% end %> +#smtp inet n - - - 1 postscreen +#smtpd pass - - - - - smtpd +#dnsblog unix - - - - 0 dnsblog +#tlsproxy unix - - - - 0 tlsproxy +<% if @use_submission == 'yes' %>submission inet n - - - - smtpd + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +<% end %> +<% if @use_smtps == 'yes' %>smtps inet n - - - - smtpd + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +<% end %> +#628 inet n - - - - qmqpd +pickup fifo n - - 60 1 pickup +cleanup unix n - - - 0 cleanup +qmgr fifo n - n 300 1 qmgr +#qmgr fifo n - - 300 1 oqmgr +tlsmgr unix - - - 1000? 1 tlsmgr +rewrite unix - - - - - trivial-rewrite +bounce unix - - - - 0 bounce +defer unix - - - - 0 bounce +trace unix - - - - 0 bounce +verify unix - - - - 1 verify +flush unix n - - 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - - - - smtp +# When relaying mail as backup MX, disable fallback_relay to avoid MX loops +relay unix - - - - - smtp + -o smtp_fallback_relay= +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - - - - showq +error unix - - - - - error +retry unix - - - - - error +discard unix - - - - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - - - - lmtp +anvil unix - - - - 1 anvil +scache unix - - - - 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/bin/maildrop -d ${recipient} +# +# ==================================================================== +# +# Recent Cyrus versions can use the existing "lmtp" master.cf entry. +# +# Specify in cyrus.conf: +# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 +# +# Specify in main.cf one or more of the following: +# mailbox_transport = lmtp:inet:localhost +# virtual_transport = lmtp:inet:localhost +# +# ==================================================================== +# +# Cyrus 2.1.5 (Amos Gouaux) +# Also specify in main.cf: cyrus_destination_recipient_limit=1 +# +#cyrus unix - n n - - pipe +# user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} +# +# ==================================================================== +# Old example of delivery via Cyrus. +# +#old-cyrus unix - n n - - pipe +# flags=R user=cyrus argv=/cyrus/bin/deliver -e -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=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $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} + +<% if @use_amavisd == 'yes' %> +amavis unix - - - - 2 smtp + -o smtp_data_done_timeout=1200 + -o smtp_send_xforward_command=yes + +127.0.0.1:10025 inet n - - - - smtpd + -o content_filter= + -o local_recipient_maps= + -o relay_recipient_maps= + -o smtpd_restriction_classes= + -o smtpd_client_restrictions= + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o mynetworks=127.0.0.0/8 + -o strict_rfc821_envelopes=yes + -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks + -o smtpd_bind_address=127.0.0.1 +<% end %> +<% if @use_dovecot_lda == 'yes' %> +dovecot unix - n n - - pipe + flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop} -n -m ${extension} +<% end %> +<% if @use_schleuder == 'yes' %> +schleuder unix - n n - - pipe + flags=DRhu user=schleuder argv=/usr/bin/schleuder ${user} +<% end %> +<% if @use_sympa == 'yes' %> +sympa unix - n n - - pipe + flags=R user=sympa argv=/usr/lib/sympa/bin/queue ${recipient} +sympabounce unix - n n - - pipe + flags=R user=sympa argv=/usr/lib/sympa/bin/bouncequeue ${user} +<% end %> +<% if @use_mlmmj == 'yes' %> +mlmmj unix - n n - - pipe + flags=DORhu user=mlmmj argv=/usr/bin/mlmmj-recieve -F -L /var/spool/mlmmj/$nexthop/ +<%- end -%> + +<%- unless @mastercf_tail.to_s.empty? then -%> +<%= @mastercf_tail %> +<%- end -%> diff --git a/puppet/modules/postfix/templates/master.cf.debian-8.erb b/puppet/modules/postfix/templates/master.cf.debian-8.erb new file mode 100644 index 00000000..e613ac1f --- /dev/null +++ b/puppet/modules/postfix/templates/master.cf.debian-8.erb @@ -0,0 +1,160 @@ +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master"). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) + # ========================================================================== +<% if @use_postscreen == 'yes' and @smtp_listen == 'all' %>smtpd pass - - n - - smtpd +smtp inet n - n - 1 postscreen +tlsproxy unix - - n - 0 tlsproxy +<% elsif @use_postscreen == 'no' and @smtp_listen == 'all' %>smtp inet n - - - - smtpd +<% else %><%= @smtp_listen %>:smtp inet n - - - - smtpd<% end %> +#smtp inet n - - - 1 postscreen +#smtpd pass - - - - - smtpd +#dnsblog unix - - - - 0 dnsblog +#tlsproxy unix - - - - 0 tlsproxy +<% if @use_submission == 'yes' %>submission inet n - - - - smtpd + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +<% end %> +<% if @use_smtps == 'yes' %>smtps inet n - - - - smtpd + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +<% end %> +#628 inet n - - - - qmqpd +pickup fifo n - - 60 1 pickup +cleanup unix n - - - 0 cleanup +qmgr fifo n - n 300 1 qmgr +#qmgr fifo n - - 300 1 oqmgr +tlsmgr unix - - - 1000? 1 tlsmgr +rewrite unix - - - - - trivial-rewrite +bounce unix - - - - 0 bounce +defer unix - - - - 0 bounce +trace unix - - - - 0 bounce +verify unix - - - - 1 verify +flush unix n - - 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - - - - smtp +# When relaying mail as backup MX, disable fallback_relay to avoid MX loops +relay unix - - - - - smtp + -o smtp_fallback_relay= +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - - - - showq +error unix - - - - - error +retry unix - - - - - error +discard unix - - - - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - - - - lmtp +anvil unix - - - - 1 anvil +scache unix - - - - 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/bin/maildrop -d ${recipient} +# +# ==================================================================== +# +# Recent Cyrus versions can use the existing "lmtp" master.cf entry. +# +# Specify in cyrus.conf: +# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 +# +# Specify in main.cf one or more of the following: +# mailbox_transport = lmtp:inet:localhost +# virtual_transport = lmtp:inet:localhost +# +# ==================================================================== +# +# Cyrus 2.1.5 (Amos Gouaux) +# Also specify in main.cf: cyrus_destination_recipient_limit=1 +# +#cyrus unix - n n - - pipe +# user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} +# +# ==================================================================== +# Old example of delivery via Cyrus. +# +#old-cyrus unix - n n - - pipe +# flags=R user=cyrus argv=/cyrus/bin/deliver -e -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=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $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} + +<% if @use_amavisd == 'yes' %> +amavis unix - - - - 2 smtp + -o smtp_data_done_timeout=1200 + -o smtp_send_xforward_command=yes + +127.0.0.1:10025 inet n - - - - smtpd + -o content_filter= + -o local_recipient_maps= + -o relay_recipient_maps= + -o smtpd_restriction_classes= + -o smtpd_client_restrictions= + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o mynetworks=127.0.0.0/8 + -o strict_rfc821_envelopes=yes + -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks + -o smtpd_bind_address=127.0.0.1 +<% end %> +<% if @use_dovecot_lda == 'yes' %> +dovecot unix - n n - - pipe + flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop} -n -m ${extension} +<% end %> +<% if @use_schleuder == 'yes' %> +schleuder unix - n n - - pipe + flags=DRhu user=schleuder argv=/usr/bin/schleuder ${user} +<% end %> +<% if @use_sympa == 'yes' %> +sympa unix - n n - - pipe + flags=R user=sympa argv=/usr/lib/sympa/bin/queue ${recipient} +sympabounce unix - n n - - pipe + flags=R user=sympa argv=/usr/lib/sympa/bin/bouncequeue ${user} +<% end %> +<% if @use_mlmmj == 'yes' %> +mlmmj unix - n n - - pipe + flags=DORhu user=mlmmj argv=/usr/bin/mlmmj-recieve -F -L /var/spool/mlmmj/$nexthop/ +<%- end -%> + +<%- unless @mastercf_tail.to_s.empty? then -%> +<%= @mastercf_tail %> +<%- end -%> diff --git a/puppet/modules/postfix/templates/master.cf.debian-sid.erb b/puppet/modules/postfix/templates/master.cf.debian-sid.erb new file mode 100644 index 00000000..7b653fb3 --- /dev/null +++ b/puppet/modules/postfix/templates/master.cf.debian-sid.erb @@ -0,0 +1,157 @@ +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master"). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== +<% if @smtp_listen == 'all' %>smtp inet n - - - - smtpd +<% else %><%= @smtp_listen %>:smtp inet n - - - - smtpd<% end %> +#smtp inet n - - - 1 postscreen +#smtpd pass - - - - - smtpd +#dnsblog unix - - - - 0 dnsblog +#tlsproxy unix - - - - 0 tlsproxy +<% if @use_submission == 'yes' %>submission inet n - - - - smtpd + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +<% end %> +<% if @use_smtps == 'yes' %>smtps inet n - - - - smtpd + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +<% end %> +#628 inet n - - - - qmqpd +pickup fifo n - - 60 1 pickup +cleanup unix n - - - 0 cleanup +qmgr fifo n - n 300 1 qmgr +#qmgr fifo n - - 300 1 oqmgr +tlsmgr unix - - - 1000? 1 tlsmgr +rewrite unix - - - - - trivial-rewrite +bounce unix - - - - 0 bounce +defer unix - - - - 0 bounce +trace unix - - - - 0 bounce +verify unix - - - - 1 verify +flush unix n - - 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - - - - smtp +# When relaying mail as backup MX, disable fallback_relay to avoid MX loops +relay unix - - - - - smtp + -o smtp_fallback_relay= +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - - - - showq +error unix - - - - - error +retry unix - - - - - error +discard unix - - - - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - - - - lmtp +anvil unix - - - - 1 anvil +scache unix - - - - 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/bin/maildrop -d ${recipient} +# +# ==================================================================== +# +# Recent Cyrus versions can use the existing "lmtp" master.cf entry. +# +# Specify in cyrus.conf: +# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 +# +# Specify in main.cf one or more of the following: +# mailbox_transport = lmtp:inet:localhost +# virtual_transport = lmtp:inet:localhost +# +# ==================================================================== +# +# Cyrus 2.1.5 (Amos Gouaux) +# Also specify in main.cf: cyrus_destination_recipient_limit=1 +# +#cyrus unix - n n - - pipe +# user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} +# +# ==================================================================== +# Old example of delivery via Cyrus. +# +#old-cyrus unix - n n - - pipe +# flags=R user=cyrus argv=/cyrus/bin/deliver -e -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=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $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} + +<% if @use_amavisd == 'yes' %> +amavis unix - - - - 2 smtp + -o smtp_data_done_timeout=1200 + -o smtp_send_xforward_command=yes + +127.0.0.1:10025 inet n - - - - smtpd + -o content_filter= + -o local_recipient_maps= + -o relay_recipient_maps= + -o smtpd_restriction_classes= + -o smtpd_client_restrictions= + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o mynetworks=127.0.0.0/8 + -o strict_rfc821_envelopes=yes + -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks + -o smtpd_bind_address=127.0.0.1 +<% end %> +<% if @use_dovecot_lda == 'yes' %> +dovecot unix - n n - - pipe + flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop} -n -m ${extension} +<% end %> +<% if @use_schleuder == 'yes' %> +schleuder unix - n n - - pipe + flags=DRhu user=schleuder argv=/usr/bin/schleuder ${user} +<% end %> +<% if @use_sympa == 'yes' %> +sympa unix - n n - - pipe + flags=R user=sympa argv=/usr/lib/sympa/bin/queue ${recipient} +sympabounce unix - n n - - pipe + flags=R user=sympa argv=/usr/lib/sympa/bin/bouncequeue ${user} +<% end %> +<% if @use_mlmmj == 'yes' %> +mlmmj unix - n n - - pipe + flags=DORhu user=mlmmj argv=/usr/bin/mlmmj-recieve -F -L /var/spool/mlmmj/$nexthop/ +<%- end -%> + +<%- unless @mastercf_tail.to_s.empty? then -%> +<%= @mastercf_tail %> +<%- end -%> diff --git a/puppet/modules/postfix/templates/master.cf.redhat5.erb b/puppet/modules/postfix/templates/master.cf.redhat5.erb new file mode 100644 index 00000000..01741e4e --- /dev/null +++ b/puppet/modules/postfix/templates/master.cf.redhat5.erb @@ -0,0 +1,87 @@ +# file managed by puppet +# +# 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_listen %>:smtp inet n - n - - smtpd +#smtp inet n - n - - smtpd +<% if use_submission == 'yes' %>submission inet n - n - - smtpd + -o smtpd_enforce_tls=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject +<% end %> +<% if use_smtps == 'yes' %>smtps inet n - n - - smtpd + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject +<% end %> +#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 +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 + +<%- unless mastercf_tail.to_s.empty? then -%> +<%= mastercf_tail %> +<%- end -%> -- cgit v1.2.3 From 850a14b59444737f703686d0d1996bf09ab08e2b Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:46:26 -0400 Subject: git subrepo clone https://leap.se/git/puppet_vcsrepo puppet/modules/vcsrepo subrepo: subdir: "puppet/modules/vcsrepo" merged: "4e23209" upstream: origin: "https://leap.se/git/puppet_vcsrepo" branch: "master" commit: "4e23209" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I72f8ecdef4855ef9da6e1486453b1cdf01bb54a3 --- puppet/modules/vcsrepo/.gitattributes | 5 + puppet/modules/vcsrepo/.gitignore | 11 + puppet/modules/vcsrepo/.gitrepo | 11 + puppet/modules/vcsrepo/.rspec | 2 + puppet/modules/vcsrepo/.sync.yml | 3 + puppet/modules/vcsrepo/.travis.yml | 20 + puppet/modules/vcsrepo/CHANGELOG.md | 150 ++++ puppet/modules/vcsrepo/CONTRIBUTING.md | 220 ++++++ puppet/modules/vcsrepo/Gemfile | 39 ++ puppet/modules/vcsrepo/LICENSE | 339 +++++++++ puppet/modules/vcsrepo/NOTICE | 20 + puppet/modules/vcsrepo/README.markdown | 758 +++++++++++++++++++++ puppet/modules/vcsrepo/Rakefile | 42 ++ puppet/modules/vcsrepo/examples/bzr/branch.pp | 6 + puppet/modules/vcsrepo/examples/bzr/init_repo.pp | 4 + puppet/modules/vcsrepo/examples/cvs/local.pp | 11 + puppet/modules/vcsrepo/examples/cvs/remote.pp | 5 + puppet/modules/vcsrepo/examples/git/bare_init.pp | 4 + puppet/modules/vcsrepo/examples/git/clone.pp | 5 + .../git/shallow-clone-with-just-one-commit.pp | 7 + .../vcsrepo/examples/git/working_copy_init.pp | 4 + puppet/modules/vcsrepo/examples/hg/clone.pp | 6 + .../vcsrepo/examples/hg/clone_basic_auth.pp | 7 + puppet/modules/vcsrepo/examples/hg/init_repo.pp | 4 + .../modules/vcsrepo/examples/p4/create_client.pp | 4 + .../modules/vcsrepo/examples/p4/delete_client.pp | 4 + .../modules/vcsrepo/examples/p4/latest_client.pp | 5 + puppet/modules/vcsrepo/examples/p4/sync_client.pp | 6 + puppet/modules/vcsrepo/examples/svn/checkout.pp | 5 + puppet/modules/vcsrepo/examples/svn/server.pp | 4 + .../modules/vcsrepo/lib/puppet/provider/vcsrepo.rb | 42 ++ .../vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb | 93 +++ .../vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb | 135 ++++ .../vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb | 12 + .../vcsrepo/lib/puppet/provider/vcsrepo/git.rb | 483 +++++++++++++ .../vcsrepo/lib/puppet/provider/vcsrepo/hg.rb | 130 ++++ .../vcsrepo/lib/puppet/provider/vcsrepo/p4.rb | 278 ++++++++ .../vcsrepo/lib/puppet/provider/vcsrepo/svn.rb | 139 ++++ puppet/modules/vcsrepo/lib/puppet/type/vcsrepo.rb | 248 +++++++ puppet/modules/vcsrepo/metadata.json | 81 +++ .../git/basic_auth/basic_auth_checkout_http.rb | 69 ++ .../git/basic_auth/basic_auth_checkout_https.rb | 77 +++ .../basic_auth/negative/basic_auth_checkout_git.rb | 53 ++ .../git/branch_checkout/branch_checkout_file.rb | 48 ++ .../branch_checkout/branch_checkout_file_path.rb | 48 ++ .../git/branch_checkout/branch_checkout_git.rb | 53 ++ .../git/branch_checkout/branch_checkout_http.rb | 61 ++ .../git/branch_checkout/branch_checkout_https.rb | 68 ++ .../git/branch_checkout/branch_checkout_scp.rb | 59 ++ .../git/branch_checkout/branch_checkout_ssh.rb | 59 ++ .../negative/branch_checkout_not_exists.rb | 46 ++ .../spec/acceptance/beaker/git/clone/clone_file.rb | 46 ++ .../acceptance/beaker/git/clone/clone_file_path.rb | 46 ++ .../spec/acceptance/beaker/git/clone/clone_git.rb | 51 ++ .../spec/acceptance/beaker/git/clone/clone_http.rb | 59 ++ .../acceptance/beaker/git/clone/clone_https.rb | 66 ++ ...clone_over_different_exiting_repo_with_force.rb | 49 ++ .../git/clone/clone_repo_with_excludes_in_repo.rb | 46 ++ .../clone/clone_repo_with_excludes_not_in_repo.rb | 46 ++ .../spec/acceptance/beaker/git/clone/clone_scp.rb | 57 ++ .../spec/acceptance/beaker/git/clone/clone_ssh.rb | 57 ++ .../negative/clone_over_different_exiting_repo.rb | 47 ++ .../negative/clone_repo_with_exec_excludes.rb | 45 ++ .../git/compression/compression_0_checkout.rb | 43 ++ .../git/compression/compression_1_checkout.rb | 43 ++ .../git/compression/compression_2_checkout.rb | 43 ++ .../git/compression/compression_3_checkout.rb | 43 ++ .../git/compression/compression_4_checkout.rb | 43 ++ .../git/compression/compression_5_checkout.rb | 43 ++ .../git/compression/compression_6_checkout.rb | 43 ++ .../compression/negative/compression_7_checkout.rb | 43 ++ .../negative/compression_alpha_checkout.rb | 43 ++ .../negative/compression_eval_checkout.rb | 43 ++ .../negative/compression_exec_checkout.rb | 43 ++ .../negative/compression_negative_checkout.rb | 43 ++ .../create/create_bare_repo_that_already_exists.rb | 40 ++ .../git/create/create_repo_that_already_exists.rb | 42 ++ .../create_bare_repo_specifying_revision.rb | 38 ++ .../git/group_checkout/group_checkout_file.rb | 53 ++ .../git/group_checkout/group_checkout_file_path.rb | 53 ++ .../git/group_checkout/group_checkout_git.rb | 58 ++ .../git/group_checkout/group_checkout_http.rb | 66 ++ .../git/group_checkout/group_checkout_https.rb | 73 ++ .../git/group_checkout/group_checkout_scp.rb | 64 ++ .../git/group_checkout/group_checkout_ssh.rb | 64 ++ .../group_checkout_file_non_existent_group.rb | 51 ++ .../negative/revision_checkout_not_exists.rb | 46 ++ .../revision_checkout/revision_checkout_file.rb | 53 ++ .../revision_checkout_file_path.rb | 53 ++ .../git/revision_checkout/revision_checkout_git.rb | 58 ++ .../revision_checkout/revision_checkout_http.rb | 66 ++ .../revision_checkout/revision_checkout_https.rb | 74 ++ .../git/revision_checkout/revision_checkout_scp.rb | 64 ++ .../git/revision_checkout/revision_checkout_ssh.rb | 64 ++ .../negative/shallow_clone_exec_depth.rb | 43 ++ .../negative/shallow_clone_file_path.rb | 44 ++ .../shallow_clone/negative/shallow_clone_http.rb | 55 ++ .../negative/shallow_clone_negative_depth.rb | 43 ++ .../negative/shallow_clone_overflow_depth.rb | 45 ++ .../beaker/git/shallow_clone/shallow_clone_file.rb | 47 ++ .../beaker/git/shallow_clone/shallow_clone_git.rb | 52 ++ .../git/shallow_clone/shallow_clone_https.rb | 68 ++ .../beaker/git/shallow_clone/shallow_clone_scp.rb | 58 ++ .../beaker/git/shallow_clone/shallow_clone_ssh.rb | 58 ++ .../git/shallow_clone/shallow_clone_zero_depth.rb | 43 ++ .../negative/tag_checkout_not_exists.rb | 47 ++ .../beaker/git/tag_checkout/tag_checkout_file.rb | 48 ++ .../git/tag_checkout/tag_checkout_file_path.rb | 48 ++ .../beaker/git/tag_checkout/tag_checkout_git.rb | 59 ++ .../beaker/git/tag_checkout/tag_checkout_http.rb | 67 ++ .../beaker/git/tag_checkout/tag_checkout_https.rb | 74 ++ .../beaker/git/tag_checkout/tag_checkout_scp.rb | 65 ++ .../beaker/git/tag_checkout/tag_checkout_ssh.rb | 65 ++ .../user_checkout_file_non_existent_user.rb | 51 ++ .../beaker/git/user_checkout/user_checkout_file.rb | 53 ++ .../git/user_checkout/user_checkout_file_path.rb | 53 ++ .../beaker/git/user_checkout/user_checkout_git.rb | 58 ++ .../beaker/git/user_checkout/user_checkout_http.rb | 66 ++ .../git/user_checkout/user_checkout_https.rb | 73 ++ .../beaker/git/user_checkout/user_checkout_scp.rb | 64 ++ .../beaker/git/user_checkout/user_checkout_ssh.rb | 64 ++ .../vcsrepo/spec/acceptance/beaker_helper.rb | 51 ++ .../vcsrepo/spec/acceptance/clone_repo_spec.rb | 534 +++++++++++++++ .../vcsrepo/spec/acceptance/create_repo_spec.rb | 89 +++ .../spec/acceptance/files/create_git_repo.sh | 39 ++ .../vcsrepo/spec/acceptance/files/server.crt | 13 + .../vcsrepo/spec/acceptance/files/server.key | 15 + .../vcsrepo/spec/acceptance/modules_1596_spec.rb | 72 ++ .../vcsrepo/spec/acceptance/modules_1800_spec.rb | 41 ++ .../vcsrepo/spec/acceptance/modules_2326_spec.rb | 69 ++ .../vcsrepo/spec/acceptance/modules_660_spec.rb | 89 +++ .../vcsrepo/spec/acceptance/modules_753_spec.rb | 68 ++ .../spec/acceptance/nodesets/centos-59-x64.yml | 10 + .../spec/acceptance/nodesets/centos-64-x64-pe.yml | 12 + .../spec/acceptance/nodesets/centos-64-x64.yml | 10 + .../spec/acceptance/nodesets/centos-65-x64.yml | 10 + .../spec/acceptance/nodesets/debian-607-x64.yml | 10 + .../spec/acceptance/nodesets/debian-73-x64.yml | 10 + .../vcsrepo/spec/acceptance/nodesets/default.yml | 10 + .../nodesets/ubuntu-server-10044-x64.yml | 10 + .../nodesets/ubuntu-server-12042-x64.yml | 10 + .../acceptance/nodesets/ubuntu-server-1404-x64.yml | 11 + .../vcsrepo/spec/acceptance/remove_repo_spec.rb | 30 + .../spec/acceptance/remove_repo_spec_noop.rb | 31 + .../vcsrepo/spec/fixtures/bzr_version_info.txt | 5 + .../modules/vcsrepo/spec/fixtures/git_branch_a.txt | 14 + .../spec/fixtures/git_branch_feature_bar.txt | 14 + .../vcsrepo/spec/fixtures/git_branch_none.txt | 15 + .../modules/vcsrepo/spec/fixtures/hg_parents.txt | 6 + puppet/modules/vcsrepo/spec/fixtures/hg_tags.txt | 18 + puppet/modules/vcsrepo/spec/fixtures/svn_info.txt | 10 + puppet/modules/vcsrepo/spec/spec.opts | 6 + puppet/modules/vcsrepo/spec/spec_helper.rb | 8 + .../modules/vcsrepo/spec/spec_helper_acceptance.rb | 46 ++ puppet/modules/vcsrepo/spec/spec_helper_local.rb | 7 + .../vcsrepo/spec/support/filesystem_helpers.rb | 18 + .../vcsrepo/spec/support/fixture_helpers.rb | 7 + .../spec/unit/puppet/provider/vcsrepo/bzr_spec.rb | 109 +++ .../spec/unit/puppet/provider/vcsrepo/cvs_spec.rb | 124 ++++ .../spec/unit/puppet/provider/vcsrepo/git_spec.rb | 401 +++++++++++ .../spec/unit/puppet/provider/vcsrepo/hg_spec.rb | 138 ++++ .../spec/unit/puppet/provider/vcsrepo/p4_spec.rb | 82 +++ .../spec/unit/puppet/provider/vcsrepo/svn_spec.rb | 160 +++++ .../vcsrepo/spec/unit/puppet/type/README.markdown | 4 + 164 files changed, 10151 insertions(+) create mode 100644 puppet/modules/vcsrepo/.gitattributes create mode 100644 puppet/modules/vcsrepo/.gitignore create mode 100644 puppet/modules/vcsrepo/.gitrepo create mode 100644 puppet/modules/vcsrepo/.rspec create mode 100644 puppet/modules/vcsrepo/.sync.yml create mode 100644 puppet/modules/vcsrepo/.travis.yml create mode 100644 puppet/modules/vcsrepo/CHANGELOG.md create mode 100644 puppet/modules/vcsrepo/CONTRIBUTING.md create mode 100644 puppet/modules/vcsrepo/Gemfile create mode 100644 puppet/modules/vcsrepo/LICENSE create mode 100644 puppet/modules/vcsrepo/NOTICE create mode 100644 puppet/modules/vcsrepo/README.markdown create mode 100755 puppet/modules/vcsrepo/Rakefile create mode 100644 puppet/modules/vcsrepo/examples/bzr/branch.pp create mode 100644 puppet/modules/vcsrepo/examples/bzr/init_repo.pp create mode 100644 puppet/modules/vcsrepo/examples/cvs/local.pp create mode 100644 puppet/modules/vcsrepo/examples/cvs/remote.pp create mode 100644 puppet/modules/vcsrepo/examples/git/bare_init.pp create mode 100644 puppet/modules/vcsrepo/examples/git/clone.pp create mode 100644 puppet/modules/vcsrepo/examples/git/shallow-clone-with-just-one-commit.pp create mode 100644 puppet/modules/vcsrepo/examples/git/working_copy_init.pp create mode 100644 puppet/modules/vcsrepo/examples/hg/clone.pp create mode 100644 puppet/modules/vcsrepo/examples/hg/clone_basic_auth.pp create mode 100644 puppet/modules/vcsrepo/examples/hg/init_repo.pp create mode 100644 puppet/modules/vcsrepo/examples/p4/create_client.pp create mode 100644 puppet/modules/vcsrepo/examples/p4/delete_client.pp create mode 100644 puppet/modules/vcsrepo/examples/p4/latest_client.pp create mode 100644 puppet/modules/vcsrepo/examples/p4/sync_client.pp create mode 100644 puppet/modules/vcsrepo/examples/svn/checkout.pp create mode 100644 puppet/modules/vcsrepo/examples/svn/server.pp create mode 100644 puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo.rb create mode 100644 puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb create mode 100644 puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb create mode 100644 puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb create mode 100644 puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/git.rb create mode 100644 puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb create mode 100644 puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/p4.rb create mode 100644 puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb create mode 100644 puppet/modules/vcsrepo/lib/puppet/type/vcsrepo.rb create mode 100644 puppet/modules/vcsrepo/metadata.json create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file_path.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_git.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_http.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_https.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_scp.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_ssh.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_0_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_1_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_2_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_3_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_4_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_5_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_6_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/beaker_helper.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/clone_repo_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/create_repo_spec.rb create mode 100755 puppet/modules/vcsrepo/spec/acceptance/files/create_git_repo.sh create mode 100644 puppet/modules/vcsrepo/spec/acceptance/files/server.crt create mode 100644 puppet/modules/vcsrepo/spec/acceptance/files/server.key create mode 100644 puppet/modules/vcsrepo/spec/acceptance/modules_1596_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/modules_1800_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/modules_2326_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/modules_660_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/modules_753_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-59-x64.yml create mode 100644 puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-64-x64-pe.yml create mode 100644 puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-64-x64.yml create mode 100644 puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-65-x64.yml create mode 100644 puppet/modules/vcsrepo/spec/acceptance/nodesets/debian-607-x64.yml create mode 100644 puppet/modules/vcsrepo/spec/acceptance/nodesets/debian-73-x64.yml create mode 100644 puppet/modules/vcsrepo/spec/acceptance/nodesets/default.yml create mode 100644 puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml create mode 100644 puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml create mode 100644 puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml create mode 100644 puppet/modules/vcsrepo/spec/acceptance/remove_repo_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/acceptance/remove_repo_spec_noop.rb create mode 100644 puppet/modules/vcsrepo/spec/fixtures/bzr_version_info.txt create mode 100644 puppet/modules/vcsrepo/spec/fixtures/git_branch_a.txt create mode 100644 puppet/modules/vcsrepo/spec/fixtures/git_branch_feature_bar.txt create mode 100644 puppet/modules/vcsrepo/spec/fixtures/git_branch_none.txt create mode 100644 puppet/modules/vcsrepo/spec/fixtures/hg_parents.txt create mode 100644 puppet/modules/vcsrepo/spec/fixtures/hg_tags.txt create mode 100644 puppet/modules/vcsrepo/spec/fixtures/svn_info.txt create mode 100644 puppet/modules/vcsrepo/spec/spec.opts create mode 100644 puppet/modules/vcsrepo/spec/spec_helper.rb create mode 100644 puppet/modules/vcsrepo/spec/spec_helper_acceptance.rb create mode 100644 puppet/modules/vcsrepo/spec/spec_helper_local.rb create mode 100644 puppet/modules/vcsrepo/spec/support/filesystem_helpers.rb create mode 100644 puppet/modules/vcsrepo/spec/support/fixture_helpers.rb create mode 100644 puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/p4_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb create mode 100644 puppet/modules/vcsrepo/spec/unit/puppet/type/README.markdown (limited to 'puppet/modules') diff --git a/puppet/modules/vcsrepo/.gitattributes b/puppet/modules/vcsrepo/.gitattributes new file mode 100644 index 00000000..900ea0cb --- /dev/null +++ b/puppet/modules/vcsrepo/.gitattributes @@ -0,0 +1,5 @@ +#This file is generated by ModuleSync, do not edit. +*.rb eol=lf +*.erb eol=lf +*.pp eol=lf +*.sh eol=lf diff --git a/puppet/modules/vcsrepo/.gitignore b/puppet/modules/vcsrepo/.gitignore new file mode 100644 index 00000000..dd126f2f --- /dev/null +++ b/puppet/modules/vcsrepo/.gitignore @@ -0,0 +1,11 @@ +#This file is generated by ModuleSync, do not edit. +pkg/ +Gemfile.lock +vendor/ +spec/fixtures/ +.vagrant/ +.bundle/ +coverage/ +log/ +.idea/ +*.iml diff --git a/puppet/modules/vcsrepo/.gitrepo b/puppet/modules/vcsrepo/.gitrepo new file mode 100644 index 00000000..d4a41d8a --- /dev/null +++ b/puppet/modules/vcsrepo/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_vcsrepo + branch = master + commit = 4e23209eaccf1ab504d35158f4141b3053327c2f + parent = 5247b7ccf5b5889ee16262dd976b03047e34e32c + cmdver = 0.3.0 diff --git a/puppet/modules/vcsrepo/.rspec b/puppet/modules/vcsrepo/.rspec new file mode 100644 index 00000000..16f9cdb0 --- /dev/null +++ b/puppet/modules/vcsrepo/.rspec @@ -0,0 +1,2 @@ +--color +--format documentation diff --git a/puppet/modules/vcsrepo/.sync.yml b/puppet/modules/vcsrepo/.sync.yml new file mode 100644 index 00000000..02e21731 --- /dev/null +++ b/puppet/modules/vcsrepo/.sync.yml @@ -0,0 +1,3 @@ +--- +LICENSE: + unmanaged: true diff --git a/puppet/modules/vcsrepo/.travis.yml b/puppet/modules/vcsrepo/.travis.yml new file mode 100644 index 00000000..588fb5b0 --- /dev/null +++ b/puppet/modules/vcsrepo/.travis.yml @@ -0,0 +1,20 @@ +#This file is generated by ModuleSync, do not edit. +--- +sudo: false +language: ruby +cache: bundler +bundler_args: --without system_tests +script: "bundle exec rake validate lint spec" +matrix: + fast_finish: true + include: + - rvm: 2.1.6 + env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" + - rvm: 2.1.5 + env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" + - rvm: 2.1.5 + env: PUPPET_GEM_VERSION="~> 3.0" + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 3.0" +notifications: + email: false diff --git a/puppet/modules/vcsrepo/CHANGELOG.md b/puppet/modules/vcsrepo/CHANGELOG.md new file mode 100644 index 00000000..9aac1e52 --- /dev/null +++ b/puppet/modules/vcsrepo/CHANGELOG.md @@ -0,0 +1,150 @@ +# Change Log +All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). + +## [1.3.2] - Supported Release +###Summary + +Small release for support of newer PE versions. This increments the version of PE in the metadata.json file. + +## [1.3.1] - 2015-07-28 Supported Release +###Summary +This release includes a number of bugfixes along with some test updates. + +### Fixed +- Fix for detached HEAD on git 2.4+ +- Git provider doesn't ignore revision property when depth is used (MODULES-2131) +- Test fixes +- Check if submodules == true before calling update_submodules + +## [1.3.0] - 2015-05-19 Supported Release +### Summary +This release adds git provider remote handling, svn conflict resolution, and fixes the git provider when /tmp is mounted noexec. + +### Added +- `source` property now takes a hash of sources for the git provider's remotes +- Add `submodules` parameter to skip submodule initialization for git provider +- Add `conflict` to svn provider to resolve conflicts +- Add `branch` parameter to specify clone branch +- Readme rewrite + +### Fixed +- The git provider now works even if `/tmp` is noexec + +## [1.2.0] - 2014-11-04 Supported Release +### Summary +This release includes some improvements for git, mercurial, and cvs providers, and fixes the bug where there were warnings about multiple default providers. + +### Added +- Update git and mercurial providers to set UID with `Puppet::Util::Execution.execute` instead of `su` +- Allow git excludes to be string or array +- Add `user` feature to cvs provider + +### Fixed +- No more warnings about multiple default providers! (MODULES-428) + +## [1.1.0] - 2014-07-14 Supported Release +### Summary +This release adds a Perforce provider\* and corrects the git provider behavior +when using `ensure => latest`. + +\*(Only git provider is currently supported.) + +### Added +- New Perforce provider + +### Fixed +- (MODULES-660) Fix behavior with `ensure => latest` and detached HEAD +- Spec test fixes + +## [1.0.2] - 2014-06-30 Supported Release +### Summary +This supported release adds SLES 11 to the list of compatible OSs and +documentation updates for support. + +## [1.0.1] - 2014-06-17 Supported Release +### Summary +This release is the first supported release of vcsrepo. The readme has been +greatly improved. + +### Added +- Updated and expanded readme to follow readme template + +### Fixed +- Remove SLES from compatability metadata +- Unpin rspec development dependencies +- Update acceptance level testing + +## [1.0.0] - 2014-06-04 +### Summary + +This release focuses on a number of bugfixes, and also has some +new features for Bzr and Git. + +### Added +- Bzr: + - Call set_ownership +- Git: + - Add ability for shallow clones + - Use -a and desired for HARD resets + - Use rev-parse to get tag canonical revision + +### Fixed +- HG: + - Only add ssh options when it's talking to the network +- Git: + - Fix for issue with detached HEAD + - force => true will now destroy and recreate repo + - Actually use the remote parameter + - Use origin/master instead of origin/HEAD when on master +- SVN: + - Fix svnlook behavior with plain directories + +## 0.2.0 - 2013-11-13 +### Summary + +This release mainly focuses on a number of bugfixes, which should +significantly improve the reliability of Git and SVN. Thanks to +our many contributors for all of these fixes! + +### Added +- Git: + - Add autorequire for Package['git'] +- HG: + - Allow user and identity properties. +- Bzr: + - "ensure => latest" support. +- SVN: + - Added configuration parameter. + - Add support for master svn repositories. +- CVS: + - Allow for setting the CVS_RSH environment variable. + +### Fixed +- Handle Puppet::Util[::Execution].withenv for 2.x and 3.x properly. +- Change path_empty? to not do full directory listing. +- Overhaul spec tests to work with rspec2. +- Git: + - Improve Git SSH usage documentation. + - Add ssh session timeouts to prevent network issues from blocking runs. + - Fix git provider checkout of a remote ref on an existing repo. + - Allow unlimited submodules (thanks to --recursive). + - Use git checkout --force instead of short -f everywhere. + - Update git provider to handle checking out into an existing (empty) dir. +- SVN: + - Handle force property. for svn. + - Adds support for changing upstream repo url. + - Check that the URL of the WC matches the URL from the manifest. + - Changed from using "update" to "switch". + - Handle revision update without source switch. + - Fix svn provider to look for '^Revision:' instead of '^Last Changed Rev:'. +- CVS: + - Documented the "module" attribute. + +[1.3.2]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.3.1...1.3.2 +[1.3.1]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.3.0...1.3.1 +[1.3.0]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.2.0...1.3.0 +[1.2.0]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.1.0...1.2.0 +[1.1.0]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.0.2...1.1.0 +[1.0.2]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.0.1...1.0.2 +[1.0.1]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.0.0...1.0.1 +[1.0.0]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/0.2.0...1.0.0 diff --git a/puppet/modules/vcsrepo/CONTRIBUTING.md b/puppet/modules/vcsrepo/CONTRIBUTING.md new file mode 100644 index 00000000..bfeaa701 --- /dev/null +++ b/puppet/modules/vcsrepo/CONTRIBUTING.md @@ -0,0 +1,220 @@ +Checklist (and a short version for the impatient) +================================================= + + * Commits: + + - Make commits of logical units. + + - Check for unnecessary whitespace with "git diff --check" before + committing. + + - Commit using Unix line endings (check the settings around "crlf" in + git-config(1)). + + - Do not check in commented out code or unneeded files. + + - The first line of the commit message should be a short + description (50 characters is the soft limit, excluding ticket + number(s)), and should skip the full stop. + + - Associate the issue in the message. The first line should include + the issue number in the form "(#XXXX) Rest of message". + + - The body should provide a meaningful commit message, which: + + - uses the imperative, present tense: "change", not "changed" or + "changes". + + - includes motivation for the change, and contrasts its + implementation with the previous behavior. + + - Make sure that you have tests for the bug you are fixing, or + feature you are adding. + + - Make sure the test suites passes after your commit: + `bundle exec rspec spec/acceptance` More information on [testing](#Testing) below + + - When introducing a new feature, make sure it is properly + documented in the README.md + + * Submission: + + * Pre-requisites: + + - Make sure you have a [GitHub account](https://github.com/join) + + - [Create a ticket](https://tickets.puppetlabs.com/secure/CreateIssue!default.jspa), or [watch the ticket](https://tickets.puppetlabs.com/browse/) you are patching for. + + * Preferred method: + + - Fork the repository on GitHub. + + - Push your changes to a topic branch in your fork of the + repository. (the format ticket/1234-short_description_of_change is + usually preferred for this project). + + - Submit a pull request to the repository in the puppetlabs + organization. + +The long version +================ + + 1. Make separate commits for logically separate changes. + + Please break your commits down into logically consistent units + which include new or changed tests relevant to the rest of the + change. The goal of doing this is to make the diff easier to + read for whoever is reviewing your code. In general, the easier + your diff is to read, the more likely someone will be happy to + review it and get it into the code base. + + If you are going to refactor a piece of code, please do so as a + separate commit from your feature or bug fix changes. + + We also really appreciate changes that include tests to make + sure the bug is not re-introduced, and that the feature is not + accidentally broken. + + Describe the technical detail of the change(s). If your + description starts to get too long, that is a good sign that you + probably need to split up your commit into more finely grained + pieces. + + Commits which plainly describe the things which help + reviewers check the patch and future developers understand the + code are much more likely to be merged in with a minimum of + bike-shedding or requested changes. Ideally, the commit message + would include information, and be in a form suitable for + inclusion in the release notes for the version of Puppet that + includes them. + + Please also check that you are not introducing any trailing + whitespace or other "whitespace errors". You can do this by + running "git diff --check" on your changes before you commit. + + 2. Sending your patches + + To submit your changes via a GitHub pull request, we _highly_ + recommend that you have them on a topic branch, instead of + directly on "master". + It makes things much easier to keep track of, especially if + you decide to work on another thing before your first change + is merged in. + + GitHub has some pretty good + [general documentation](http://help.github.com/) on using + their site. They also have documentation on + [creating pull requests](http://help.github.com/send-pull-requests/). + + In general, after pushing your topic branch up to your + repository on GitHub, you can switch to the branch in the + GitHub UI and click "Pull Request" towards the top of the page + in order to open a pull request. + + + 3. Update the related GitHub issue. + + If there is a GitHub issue associated with the change you + submitted, then you should update the ticket to include the + location of your branch, along with any other commentary you + may wish to make. + +Testing +======= + +Getting Started +--------------- + +Our puppet modules provide [`Gemfile`](./Gemfile)s which can tell a ruby +package manager such as [bundler](http://bundler.io/) what Ruby packages, +or Gems, are required to build, develop, and test this software. + +Please make sure you have [bundler installed](http://bundler.io/#getting-started) +on your system, then use it to install all dependencies needed for this project, +by running + +```shell +% bundle install +Fetching gem metadata from https://rubygems.org/........ +Fetching gem metadata from https://rubygems.org/.. +Using rake (10.1.0) +Using builder (3.2.2) +-- 8><-- many more --><8 -- +Using rspec-system-puppet (2.2.0) +Using serverspec (0.6.3) +Using rspec-system-serverspec (1.0.0) +Using bundler (1.3.5) +Your bundle is complete! +Use `bundle show [gemname]` to see where a bundled gem is installed. +``` + +NOTE some systems may require you to run this command with sudo. + +If you already have those gems installed, make sure they are up-to-date: + +```shell +% bundle update +``` + +With all dependencies in place and up-to-date we can now run the tests: + +```shell +% bundle exec rake spec +``` + +This will execute all the [rspec tests](http://rspec-puppet.com/) tests +under [spec/defines](./spec/defines), [spec/classes](./spec/classes), +and so on. rspec tests may have the same kind of dependencies as the +module they are testing. While the module defines in its [Modulefile](./Modulefile), +rspec tests define them in [.fixtures.yml](./fixtures.yml). + +Some puppet modules also come with [beaker](https://github.com/puppetlabs/beaker) +tests. These tests spin up a virtual machine under +[VirtualBox](https://www.virtualbox.org/)) with, controlling it with +[Vagrant](http://www.vagrantup.com/) to actually simulate scripted test +scenarios. In order to run these, you will need both of those tools +installed on your system. + +You can run them by issuing the following command + +```shell +% bundle exec rake spec_clean +% bundle exec rspec spec/acceptance +``` + +This will now download a pre-fabricated image configured in the [default node-set](./spec/acceptance/nodesets/default.yml), +install puppet, copy this module and install its dependencies per [spec/spec_helper_acceptance.rb](./spec/spec_helper_acceptance.rb) +and then run all the tests under [spec/acceptance](./spec/acceptance). + +Writing Tests +------------- + +XXX getting started writing tests. + +If you have commit access to the repository +=========================================== + +Even if you have commit access to the repository, you will still need to +go through the process above, and have someone else review and merge +in your changes. The rule is that all changes must be reviewed by a +developer on the project (that did not write the code) to ensure that +all changes go through a code review process. + +Having someone other than the author of the topic branch recorded as +performing the merge is the record that they performed the code +review. + + +Additional Resources +==================== + +* [Getting additional help](http://puppetlabs.com/community/get-help) + +* [Writing tests](http://projects.puppetlabs.com/projects/puppet/wiki/Development_Writing_Tests) + +* [Patchwork](https://patchwork.puppetlabs.com) + +* [General GitHub documentation](http://help.github.com/) + +* [GitHub pull request documentation](http://help.github.com/send-pull-requests/) + diff --git a/puppet/modules/vcsrepo/Gemfile b/puppet/modules/vcsrepo/Gemfile new file mode 100644 index 00000000..e490bc9b --- /dev/null +++ b/puppet/modules/vcsrepo/Gemfile @@ -0,0 +1,39 @@ +#This file is generated by ModuleSync, do not edit. + +source ENV['GEM_SOURCE'] || "https://rubygems.org" + +def location_for(place, version = nil) + if place =~ /^(git[:@][^#]*)#(.*)/ + [version, { :git => $1, :branch => $2, :require => false}].compact + elsif place =~ /^file:\/\/(.*)/ + ['>= 0', { :path => File.expand_path($1), :require => false}] + else + [place, version, { :require => false}].compact + end +end + +group :development, :unit_tests do + gem 'json', :require => false + gem 'metadata-json-lint', :require => false + gem 'puppet_facts', :require => false + gem 'puppet-blacksmith', :require => false + gem 'puppetlabs_spec_helper', :require => false + gem 'rspec-puppet', '>= 2.3.2', :require => false + gem 'simplecov', :require => false +end +group :system_tests do + gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION'] || '>= 3.4') + gem 'beaker', *location_for(ENV['BEAKER_VERSION']) + gem 'serverspec', :require => false + gem 'beaker-puppet_install_helper', :require => false + gem 'master_manipulator', :require => false + gem 'beaker-hostgenerator', *location_for(ENV['BEAKER_HOSTGENERATOR_VERSION']) +end + +gem 'facter', *location_for(ENV['FACTER_GEM_VERSION']) +gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION']) + + +if File.exists? "#{__FILE__}.local" + eval(File.read("#{__FILE__}.local"), binding) +end diff --git a/puppet/modules/vcsrepo/LICENSE b/puppet/modules/vcsrepo/LICENSE new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/puppet/modules/vcsrepo/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/puppet/modules/vcsrepo/NOTICE b/puppet/modules/vcsrepo/NOTICE new file mode 100644 index 00000000..7eab165b --- /dev/null +++ b/puppet/modules/vcsrepo/NOTICE @@ -0,0 +1,20 @@ +vcsrepo puppet module + +Copyright (C) 2010-2012 Puppet Labs Inc. + +Puppet Labs can be contacted at: info@puppetlabs.com + + +This program and entire repository is free software; you can +redistribute it and/or modify it under the terms of the GNU +General Public License as published by the Free Software +Foundation; either version 2 of the License, or any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/puppet/modules/vcsrepo/README.markdown b/puppet/modules/vcsrepo/README.markdown new file mode 100644 index 00000000..ffc2d7e0 --- /dev/null +++ b/puppet/modules/vcsrepo/README.markdown @@ -0,0 +1,758 @@ +#vcsrepo + +####Table of Contents + +1. [Overview](#overview) +2. [Module Description - What the module does and why it is useful](#module-description) +3. [Setup - The basics of getting started with vcsrepo](#setup) + * [Setup requirements](#setup-requirements) + * [Beginning with vcsrepo](#beginning-with-vcsrepo) +4. [Usage - Configuration options and additional functionality](#usage) + * [Git](#git) + * [Bazaar](#bazaar) + * [CVS](#cvs) + * [Mercurial](#mercurial) + * [Perforce](#perforce) + * [Subversion](#subversion) +5. [Reference - An under-the-hood peek at what the module is doing and how](#reference) + * [Type: vcsrepo](#type-vcsrepo) + * [Providers](#providers) + * [Features](#features) + * [Parameters](#parameters) +5. [Limitations - OS compatibility, etc.](#limitations) +6. [Development - Guide for contributing to the module](#development) + +##Overview + +The vcsrepo module lets you use Puppet to easily deploy content from your version control system (VCS). + +##Module Description + +The vcsrepo module provides a single type with providers to support the following version control systems: + +* [Git](#git) +* [Bazaar](#bazaar) +* [CVS](#cvs) +* [Mercurial](#mercurial) +* [Perforce](#perforce) +* [Subversion](#subversion) + +**Note:** `git` is the only vcs provider officially [supported by Puppet Labs](https://forge.puppetlabs.com/supported). + +##Setup + +###Setup Requirements + +The `vcsrepo` module does not install any VCS software for you. You must install a VCS before you can use this module. + +Like Puppet in general, the `vcsrepo` module does not automatically create parent directories for the files it manages. Make sure to set up any needed directory structures before you get started. + +###Beginning with vcsrepo + +To create and manage a blank repository, define the type `vcsrepo` with a path to your repository and supply the `provider` parameter based on the [VCS you're using](#usage). + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, +} +~~~ + +##Usage + +**Note:** `git` is the only vcsrepo provider officially [supported by Puppet Labs](https://forge.puppetlabs.com/supported). + +###Git + +####Create a blank repository + +To create a blank repository, suitable for use as a central repository, define `vcsrepo` without `source` or `revision`: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, +} +~~~ + +If you're managing a central or official repository, you might want to make it a bare repository. To do this, set `ensure` to 'bare': + +~~~ +vcsrepo { '/path/to/repo': + ensure => bare, + provider => git, +} +~~~ + +####Clone/pull a repository + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + source => 'git://example.com/repo.git', +} +~~~ + +If you want to clone your repository as bare or mirror, you can set `ensure` to 'bare' or 'mirror': + +~~~ +vcsrepo { '/path/to/repo': + ensure => mirror, + provider => git, + source => 'git://example.com/repo.git', +} +~~~ + +By default, `vcsrepo` will use the HEAD of the source repository's master branch. To use another branch or a specific commit, set `revision` to either a branch name or a commit SHA or tag. + +Branch name: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => 'development', +} +~~~ + +SHA: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => '0c466b8a5a45f6cd7de82c08df2fb4ce1e920a31', +} +~~~ + +Tag: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => '1.1.2rc1', +} +~~~ + +To check out a branch as a specific user, supply the `user` parameter: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => '0c466b8a5a45f6cd7de82c08df2fb4ce1e920a31', + user => 'someUser', +} +~~~ + +To keep the repository at the latest revision, set `ensure` to 'latest'. + +**WARNING:** this overwrites any local changes to the repository: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => git, + source => 'git://example.com/repo.git', + revision => 'master', +} +~~~ + +To clone the repository but skip initializing submodules, set `submodules` to 'false': + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => git, + source => 'git://example.com/repo.git', + submodules => false, +} +~~~ + +####Use multiple remotes with a repository +In place of a single string, you can set `source` to a hash of one or more name => URL pairs: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + remote => 'origin' + source => { + 'origin' => 'https://github.com/puppetlabs/puppetlabs-vcsrepo.git', + 'other_remote' => 'https://github.com/other_user/puppetlabs-vcsrepo.git' + }, +} +~~~ + +**Note:** if you set `source` to a hash, one of the names you specify must match the value of the `remote` parameter. That remote serves as the upstream of your managed repository. + +####Connect via SSH + +To connect to your source repository via SSH (e.g., 'username@server:…'), we recommend managing your SSH keys with Puppet and using the [`require`](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) metaparameter to make sure they are present before the `vcsrepo` resource is applied. + +To use SSH keys associated with a user, specify the username in the `user` parameter: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => git, + source => 'git://username@example.com/repo.git', + user => 'toto', #uses toto's $HOME/.ssh setup + require => File['/home/toto/.ssh/id_rsa'], +} +~~~ + +###Bazaar + +####Create a blank repository + +To create a blank repository, suitable for use as a central repository, define `vcsrepo` without `source` or `revision`: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => bzr, +} +~~~ + +####Branch from an existing repository + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => bzr, + source => '/some/path', +} +~~~ + +To branch from a specific revision, set `revision` to a valid [Bazaar revision spec](http://wiki.bazaar.canonical.com/BzrRevisionSpec): + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => bzr, + source => '/some/path', + revision => 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x', +} +~~~ + +####Connect via SSH + +To connect to your source repository via SSH (e.g., `'bzr+ssh://...'` or `'sftp://...,'`), we recommend using the [`require`](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) metaparameter to make sure your SSH keys are present before the `vcsrepo` resource is applied: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => bzr, + source => 'bzr+ssh://bzr.example.com/some/path', + user => 'toto', #uses toto's $HOME/.ssh setup + require => File['/home/toto/.ssh/id_rsa'], +} +~~~ + +###CVS + +####Create a blank repository + +To create a blank repository, suitable for use as a central repository, define `vcsrepo` without `source` or `revision`: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => cvs, +} +~~~ + +####Checkout/update from a repository + +~~~ +vcsrepo { '/path/to/workspace': + ensure => present, + provider => cvs, + source => ':pserver:anonymous@example.com:/sources/myproj', +} +~~~ + +To get a specific module on the current mainline, supply the `module` parameter: + +~~~ +vcsrepo {'/vagrant/lockss-daemon-source': + ensure => present, + provider => cvs, + source => ':pserver:anonymous@lockss.cvs.sourceforge.net:/cvsroot/lockss', + module => 'lockss-daemon', +} +~~~ + +To set the GZIP compression levels for your repository history, use the `compression` parameter: + +~~~ +vcsrepo { '/path/to/workspace': + ensure => present, + provider => cvs, + compression => 3, + source => ':pserver:anonymous@example.com:/sources/myproj', +} +~~~ + +To get a specific revision, set `revision` to the revision number. + +~~~ +vcsrepo { '/path/to/workspace': + ensure => present, + provider => cvs, + compression => 3, + source => ':pserver:anonymous@example.com:/sources/myproj', + revision => '1.2', +} +~~~ + +You can also set `revision` to a tag: + +~~~ +vcsrepo { '/path/to/workspace': + ensure => present, + provider => cvs, + compression => 3, + source => ':pserver:anonymous@example.com:/sources/myproj', + revision => 'SOMETAG', +} +~~~ + +####Connect via SSH + +To connect to your source repository via SSH, we recommend using the [`require`](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) metaparameter to make sure your SSH keys are present before the `vcsrepo` resource is applied: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => cvs, + source => ':pserver:anonymous@example.com:/sources/myproj', + user => 'toto', #uses toto's $HOME/.ssh setup + require => File['/home/toto/.ssh/id_rsa'], +} +~~~ + +###Mercurial + +####Create a blank repository + +To create a blank repository, suitable for use as a central repository, define `vcsrepo` without `source` or `revision`: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, +} +~~~ + +####Clone/pull & update a repository + +To get the default branch tip: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, + source => 'http://hg.example.com/myrepo', +} +~~~ + +For a specific changeset, use `revision`: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, + source => 'http://hg.example.com/myrepo', + revision => '21ea4598c962', +} +~~~ + +You can also set `revision` to a tag: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, + source => 'http://hg.example.com/myrepo', + revision => '1.1.2', +} +~~~ + +To check out as a specific user: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, + source => 'http://hg.example.com/myrepo', + user => 'user', +} +~~~ + +To specify an SSH identity key: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, + source => 'ssh://hg@hg.example.com/myrepo', + identity => '/home/user/.ssh/id_dsa1, +} +~~~ + +To specify a username and password for HTTP Basic authentication: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => hg, + source => 'http://hg.example.com/myrepo', + basic_auth_username => 'hgusername', + basic_auth_password => 'hgpassword', +} +~~~ + +####Connect via SSH + +To connect to your source repository via SSH (e.g., `'ssh://...'`), we recommend using the [`require` metaparameter](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) to make sure your SSH keys are present before the `vcsrepo` resource is applied: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => hg, + source => 'ssh://hg.example.com//path/to/myrepo', + user => 'toto', #uses toto's $HOME/.ssh setup + require => File['/home/toto/.ssh/id_rsa'], +} +~~~ + +###Perforce + +####Create an empty workspace + +To set up the connection to your Perforce service, set `p4config` to the location of a valid Perforce [config file](http://www.perforce.com/perforce/doc.current/manuals/p4guide/chapter.configuration.html#configuration.settings.configfiles) stored on the node: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => p4, + p4config => '/root/.p4config' +} +~~~ + +**Note:** If you don't include the `P4CLIENT` setting in your config file, the provider generates a workspace name based on the digest of `path` and the node's hostname (e.g., `puppet-91bc00640c4e5a17787286acbe2c021c`): + +####Create/update and sync a Perforce workspace + +To sync a depot path to head, set `ensure` to 'latest': + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => p4, + source => '//depot/branch/...' +} +~~~ + +To sync to a specific changelist, specify its revision number with the `revision` parameter: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => p4, + source => '//depot/branch/...', + revision => '2341' +} +~~~ + +You can also set `revision` to a label: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => p4, + source => '//depot/branch/...', + revision => 'my_label' +} +~~~ + +###Subversion + +####Create a blank repository + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => svn, +} +~~~ + +####Check out from an existing repository + +Provide a `source` pointing to the branch or tag you want to check out: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => svn, + source => 'svn://svnrepo/hello/branches/foo', +} +~~~ + +You can also designate a specific revision: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => svn, + source => 'svn://svnrepo/hello/branches/foo', + revision => '1234', +} +~~~ + +####Use a specific Subversion configuration directory + +Use the `configuration` parameter to designate the directory that contains your Subversion configuration files (typically, '/path/to/.subversion'): + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => svn, + source => 'svn://svnrepo/hello/branches/foo', + configuration => '/path/to/.subversion', +} +~~~ + +####Connect via SSH + +To connect to your source repository via SSH (e.g., `'svn+ssh://...'`), we recommend using the [`require` metaparameter](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) to make sure your SSH keys are present before the `vcsrepo` resource is applied: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => svn, + source => 'svn+ssh://svnrepo/hello/branches/foo', + user => 'toto', #uses toto's $HOME/.ssh setup + require => File['/home/toto/.ssh/id_rsa'], +} +~~~ + +##Reference + +###Type: vcsrepo + +The vcsrepo module adds only one type with several providers. Each provider abstracts a different VCS, and each provider includes a set of features according to its needs. + +####Providers + +**Note:** Not all features are available with all providers. + +#####`git` - Supports the Git VCS. + +Features: `bare_repositories`, `depth`, `multiple_remotes`, `reference_tracking`, `ssh_identity`, `submodules`, `user` + +Parameters: `depth`, `ensure`, `excludes`, `force`, `group`, `identity`, `owner`, `path`, `provider`, `remote`, `revision`, `source`, `user` + +#####`bzr` - Supports the Bazaar VCS. + +Features: `reference_tracking` + +Parameters: `ensure`, `excludes`, `force`, `group`, `owner`, `path`, `provider`, `revision`, `source` + +#####`cvs` - Supports the CVS VCS. + +Features: `cvs_rsh`, `gzip_compression`, `modules`, `reference_tracking`, `user` + +Parameters: `compression`, `cvs_rsh`, `ensure`, `excludes`, `force`, `group`, `module`, `owner`, `path`, `provider` + +#####`hg` - Supports the Mercurial VCS. + +Features: `reference_tracking`, `ssh_identity`, `user` + +Parameters: `ensure`, `excludes`, `force`, `group`, `identity`, `owner`, `path`, `provider`, `revision`, `source`, `user` + +#####`p4` - Supports the Perforce VCS. + +Features: `p4config`, `reference_tracking` + +Parameters: `ensure`, `excludes`, `force`, `group`, `owner`, `p4config`, `path`, `provider`, `revision`, `source` + +#####`svn` - Supports the Subversion VCS. + +Features: `basic_auth`, `configuration`, `conflict`, `depth`, `filesystem_types`, `reference_tracking` + +Parameters: `basic_auth_password`, `basic_auth_username`, `configuration`, `conflict`, `ensure`, `excludes`, `force`, `fstype`, `group`, `owner`, `path`, `provider`, `revision`, `source`, `trust_server_cert` + +####Features + +**Note:** Not all features are available with all providers. + +* `bare_repositories` - Differentiates between bare repositories and those with working copies. (Available with `git`.) +* `basic_auth` - Supports HTTP Basic authentication. (Available with `svn`.) +* `conflict` - Lets you decide how to resolve any conflicts between the source repository and your working copy. (Available with `svn`.) +* `configuration` - Lets you specify the location of your configuration files. (Available with `svn`.) +* `cvs_rsh` - Understands the `CVS_RSH` environment variable. (Available with `cvs`.) +* `depth` - Supports shallow clones in `git` or sets scope limit in `svn`. (Available with `git` and `svn`.) +* `filesystem_types` - Supports multiple types of filesystem. (Available with `svn`.) +* `gzip_compression` - Supports explicit GZip compression levels. (Available with `cvs`.) +* `modules` - Lets you choose a specific repository module. (Available with `cvs`.) +* `multiple_remotes` - Tracks multiple remote repositories. (Available with `git`.) +* `reference_tracking` - Lets you track revision references that can change over time (e.g., some VCS tags and branch names). (Available with all providers) +* `ssh_identity` - Lets you specify an SSH identity file. (Available with `git` and `hg`.) +* `user` - Can run as a different user. (Available with `git`, `hg` and `cvs`.) +* `p4config` - Supports setting the `P4CONFIG` environment. (Available with `p4`.) +* `submodules` - Supports repository submodules which can be optionally initialized. (Available with `git`.) + +####Parameters + +All parameters are optional, except where specified otherwise. + +##### `basic_auth_password` + +Specifies the password for HTTP Basic authentication. (Requires the `basic_auth` feature.) Valid options: a string. Default: none. + +##### `basic_auth_username` + +Specifies the username for HTTP Basic authentication. (Requires the `basic_auth` feature.) Valid options: a string. Default: none. + +##### `compression` + +Sets the GZIP compression level for the repository history. (Requires the `gzip_compression` feature.) Valid options: an integer between 0 and 6. Default: none. + +##### `configuration` + +Sets the configuration directory to use. (Requires the `configuration` feature.) Valid options: a string containing an absolute path. Default: none. + +##### `conflict` + +Tells Subversion how to resolve any conflicts between the source repository and your working copy. (Requires the `conflict` feature.) Valid options: 'base', 'mine-full', 'theirs-full', and 'working'. Default: none. + +##### `cvs_rsh` + +Provides a value for the `CVS_RSH` environment variable. (Requires the `cvs_rsh` feature.) Valid options: a string. Default: none. + +##### `depth` + +In `git` sets the number of commits to include when creating a shallow clone. (Requires the `depth` feature.) Valid options: an integer. Default: none. + +In `svn` instructs Subversion to limit the scope of an operation to a particular tree depth. (Requires the `depth` feature.) Valid options: 'empty', 'files', 'immediates', 'infinity'. Default: none. + +##### `ensure` + +Specifies whether the repository should exist. Valid options: 'present', 'bare', 'absent', and 'latest'. Default: 'present'. + +##### `excludes` + +Lists any files the repository shouldn't track (similar to .gitignore). Valid options: a string (separate multiple values with the newline character). Default: none. + +##### `force` + +Specifies whether to delete any existing files in the repository path if creating a new repository. **Use with care.** Valid options: 'true' and 'false'. Default: 'false'. + +##### `fstype` + +Sets the filesystem type. (Requires the `filesystem_types` feature.) Valid options: 'fsfs' or 'bdb'. Default: none. + +##### `group` + +Specifies a group to own the repository files. Valid options: a string containing a group name or GID. Default: none. + +##### `identity` + +Specifies an identity file to use for SSH authentication. (Requires the `ssh_identity` feature.) Valid options: a string containing an absolute path. Default: none. + +##### `module` + +Specifies the repository module to manage. (Requires the `modules` feature.) Valid options: a string containing the name of a CVS module. Default: none. + +##### `owner` + +Specifies a user to own the repository files. Valid options: a string containing a username or UID. Default: none. + +##### `p4config` + +Specifies a config file that contains settings for connecting to the Perforce service. (Requires the `p4config` feature.) Valid options: a string containing the absolute path to a valid [Perforce config file](http://www.perforce.com/perforce/doc.current/manuals/p4guide/chapter.configuration.html#configuration.settings.configfiles). Default: none. + +##### `path` + +Specifies a location for the managed repository. Valid options: a string containing an absolute path. Default: the title of your declared resource. + +##### `provider` + +*Required.* Specifies the backend to use for this vcsrepo resource. Valid options: 'bzr', 'cvs', 'git', 'hg', 'p4', and 'svn'. + +##### `remote` + +Specifies the remote repository to track. (Requires the `multiple_remotes` feature.) Valid options: a string containing one of the remote names specified in `source`. Default: 'origin'. + +##### `revision` + +Sets the revision of the repository. Valid options vary by provider: + +* `git` - a string containing a Git branch name, or a commit SHA or tag +* `bzr` - a string containing a Bazaar [revision spec](http://wiki.bazaar.canonical.com/BzrRevisionSpec) +* `cvs` - a string containing a CVS [tag or revision number](http://www.thathost.com/wincvs-howto/cvsdoc/cvs_4.html) +* `hg` - a string containing a Mercurial [changeset ID](http://mercurial.selenic.com/wiki/ChangeSetID) or [tag](http://mercurial.selenic.com/wiki/Tag) +* `p4` - a string containing a Perforce [change number, label name, client name, or date spec](http://www.perforce.com/perforce/r12.1/manuals/cmdref/o.fspecs.html) +* `svn` - a string containing a Subversion [revision number](http://svnbook.red-bean.com/en/1.7/svn.basic.in-action.html#svn.basic.in-action.revs), [revision keyword, or revision date](http://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html) + +Default: none. + +##### `source` + +Specifies a source repository to serve as the upstream for your managed repository. Default: none. Valid options vary by provider: + +* `git` - a string containing a [Git repository URL](https://www.kernel.org/pub/software/scm/git/docs/git-clone.html#_git_urls_a_id_urls_a) or a hash of name => URL mappings. See also [`remote`](#remote). +* `bzr` - a string containing a Bazaar branch location +* `cvs` - a string containing a CVS root +* `hg` - a string containing the local path or URL of a Mercurial repository +* `p4` - a string containing a Perforce depot path +* `svn` - a string containing a Subversion repository URL + +Default: none. + +##### `submodules` + +Specifies whether to initialize and update each submodule in the repository. (Requires the `submodules` feature.) Valid options: 'true' and 'false'. Default: 'true'. + +##### `trust_server_cert` + +Instructs Subversion to accept SSL server certificates issued by unknown certificate authorities. Valid options: 'true' and 'false'. Default: 'false'. + +##### `user` + +Specifies the user to run as for repository operations. (Requires the `user` feature.) Valid options: a string containing a username or UID. Default: none. + +##Limitations + +Git is the only VCS provider officially [supported](https://forge.puppetlabs.com/supported) by Puppet Labs. + +This module has been tested with Puppet 2.7 and higher. + +The module has been tested on: + +* CentOS 5/6/7 +* Debian 6/7 +* Oracle 5/6/7 +* Red Hat Enterprise Linux 5/6/7 +* Scientific Linux 5/6/7 +* SLES 10/11/12 +* Ubuntu 10.04/12.04/14.04 + +Testing on other platforms has been light and cannot be guaranteed. + +##Development + +Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can't access the huge number of platforms and myriad of hardware, software, and deployment configurations that Puppet is intended to serve. + +We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. + +You can read the complete module contribution guide [on the Puppet Labs wiki.](http://projects.puppetlabs.com/projects/module-site/wiki/Module_contributing) diff --git a/puppet/modules/vcsrepo/Rakefile b/puppet/modules/vcsrepo/Rakefile new file mode 100755 index 00000000..7e9a13d5 --- /dev/null +++ b/puppet/modules/vcsrepo/Rakefile @@ -0,0 +1,42 @@ +require 'puppet_blacksmith/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' +require 'puppetlabs_spec_helper/rake_tasks' + +PuppetLint.configuration.fail_on_warnings = true +PuppetLint.configuration.send('relative') +PuppetLint.configuration.send('disable_80chars') +PuppetLint.configuration.send('disable_class_inherits_from_params_class') +PuppetLint.configuration.send('disable_documentation') +PuppetLint.configuration.send('disable_single_quote_string_with_variables') +PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"] + +desc 'Generate pooler nodesets' +task :gen_nodeset do + require 'beaker-hostgenerator' + require 'securerandom' + require 'fileutils' + + agent_target = ENV['TEST_TARGET'] + if ! agent_target + STDERR.puts 'TEST_TARGET environment variable is not set' + STDERR.puts 'setting to default value of "redhat-64default."' + agent_target = 'redhat-64default.' + end + + master_target = ENV['MASTER_TEST_TARGET'] + if ! master_target + STDERR.puts 'MASTER_TEST_TARGET environment variable is not set' + STDERR.puts 'setting to default value of "redhat7-64mdcl"' + master_target = 'redhat7-64mdcl' + end + + targets = "#{master_target}-#{agent_target}" + cli = BeakerHostGenerator::CLI.new([targets]) + nodeset_dir = "tmp/nodesets" + nodeset = "#{nodeset_dir}/#{targets}-#{SecureRandom.uuid}.yaml" + FileUtils.mkdir_p(nodeset_dir) + File.open(nodeset, 'w') do |fh| + fh.print(cli.execute) + end + puts nodeset +end diff --git a/puppet/modules/vcsrepo/examples/bzr/branch.pp b/puppet/modules/vcsrepo/examples/bzr/branch.pp new file mode 100644 index 00000000..0ed0705e --- /dev/null +++ b/puppet/modules/vcsrepo/examples/bzr/branch.pp @@ -0,0 +1,6 @@ +vcsrepo { '/tmp/vcstest-bzr-branch': + ensure => present, + provider => bzr, + source => 'lp:do', + revision => '1312', +} diff --git a/puppet/modules/vcsrepo/examples/bzr/init_repo.pp b/puppet/modules/vcsrepo/examples/bzr/init_repo.pp new file mode 100644 index 00000000..1129dd7d --- /dev/null +++ b/puppet/modules/vcsrepo/examples/bzr/init_repo.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest-bzr-init': + ensure => present, + provider => bzr, +} diff --git a/puppet/modules/vcsrepo/examples/cvs/local.pp b/puppet/modules/vcsrepo/examples/cvs/local.pp new file mode 100644 index 00000000..155742e3 --- /dev/null +++ b/puppet/modules/vcsrepo/examples/cvs/local.pp @@ -0,0 +1,11 @@ +vcsrepo { '/tmp/vcstest-cvs-repo': + ensure => present, + provider => cvs, +} + +vcsrepo { '/tmp/vcstest-cvs-workspace-local': + ensure => present, + provider => cvs, + source => '/tmp/vcstest-cvs-repo', + require => Vcsrepo['/tmp/vcstest-cvs-repo'], +} diff --git a/puppet/modules/vcsrepo/examples/cvs/remote.pp b/puppet/modules/vcsrepo/examples/cvs/remote.pp new file mode 100644 index 00000000..eb9665a9 --- /dev/null +++ b/puppet/modules/vcsrepo/examples/cvs/remote.pp @@ -0,0 +1,5 @@ +vcsrepo { '/tmp/vcstest-cvs-workspace-remote': + ensure => present, + provider => cvs, + source => ':pserver:anonymous@cvs.sv.gnu.org:/sources/leetcvrt', +} diff --git a/puppet/modules/vcsrepo/examples/git/bare_init.pp b/puppet/modules/vcsrepo/examples/git/bare_init.pp new file mode 100644 index 00000000..4166f6e6 --- /dev/null +++ b/puppet/modules/vcsrepo/examples/git/bare_init.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest-git-bare': + ensure => bare, + provider => git, +} diff --git a/puppet/modules/vcsrepo/examples/git/clone.pp b/puppet/modules/vcsrepo/examples/git/clone.pp new file mode 100644 index 00000000..b29a4fdb --- /dev/null +++ b/puppet/modules/vcsrepo/examples/git/clone.pp @@ -0,0 +1,5 @@ +vcsrepo { '/tmp/vcstest-git-clone': + ensure => present, + provider => git, + source => 'git://github.com/bruce/rtex.git', +} diff --git a/puppet/modules/vcsrepo/examples/git/shallow-clone-with-just-one-commit.pp b/puppet/modules/vcsrepo/examples/git/shallow-clone-with-just-one-commit.pp new file mode 100644 index 00000000..cd5a05db --- /dev/null +++ b/puppet/modules/vcsrepo/examples/git/shallow-clone-with-just-one-commit.pp @@ -0,0 +1,7 @@ +vcsrepo { '/tmp/git': + ensure => 'present', + provider => 'git', + source => 'https://github.com/git/git.git', + branch => 'v2.2.0', + depth => 1, +} diff --git a/puppet/modules/vcsrepo/examples/git/working_copy_init.pp b/puppet/modules/vcsrepo/examples/git/working_copy_init.pp new file mode 100644 index 00000000..e3352eb7 --- /dev/null +++ b/puppet/modules/vcsrepo/examples/git/working_copy_init.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest-git-wc': + ensure => present, + provider => git, +} diff --git a/puppet/modules/vcsrepo/examples/hg/clone.pp b/puppet/modules/vcsrepo/examples/hg/clone.pp new file mode 100644 index 00000000..be2d955d --- /dev/null +++ b/puppet/modules/vcsrepo/examples/hg/clone.pp @@ -0,0 +1,6 @@ +vcsrepo { '/tmp/vcstest-hg-clone': + ensure => present, + provider => hg, + source => 'http://hg.basho.com/riak', + revision => 'riak-0.5.3', +} diff --git a/puppet/modules/vcsrepo/examples/hg/clone_basic_auth.pp b/puppet/modules/vcsrepo/examples/hg/clone_basic_auth.pp new file mode 100644 index 00000000..984f8eaf --- /dev/null +++ b/puppet/modules/vcsrepo/examples/hg/clone_basic_auth.pp @@ -0,0 +1,7 @@ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => 'hg', + source => 'http://hg.example.com/myrepo', + basic_auth_username => 'hgusername', + basic_auth_password => 'hgpassword', +} diff --git a/puppet/modules/vcsrepo/examples/hg/init_repo.pp b/puppet/modules/vcsrepo/examples/hg/init_repo.pp new file mode 100644 index 00000000..a8908040 --- /dev/null +++ b/puppet/modules/vcsrepo/examples/hg/init_repo.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest-hg-init': + ensure => present, + provider => hg, +} diff --git a/puppet/modules/vcsrepo/examples/p4/create_client.pp b/puppet/modules/vcsrepo/examples/p4/create_client.pp new file mode 100644 index 00000000..3cf91602 --- /dev/null +++ b/puppet/modules/vcsrepo/examples/p4/create_client.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => present, + provider => 'p4', +} diff --git a/puppet/modules/vcsrepo/examples/p4/delete_client.pp b/puppet/modules/vcsrepo/examples/p4/delete_client.pp new file mode 100644 index 00000000..82c9c952 --- /dev/null +++ b/puppet/modules/vcsrepo/examples/p4/delete_client.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => absent, + provider => 'p4', +} diff --git a/puppet/modules/vcsrepo/examples/p4/latest_client.pp b/puppet/modules/vcsrepo/examples/p4/latest_client.pp new file mode 100644 index 00000000..106ef9e9 --- /dev/null +++ b/puppet/modules/vcsrepo/examples/p4/latest_client.pp @@ -0,0 +1,5 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => latest, + provider => 'p4', + source => '//depot/...', +} diff --git a/puppet/modules/vcsrepo/examples/p4/sync_client.pp b/puppet/modules/vcsrepo/examples/p4/sync_client.pp new file mode 100644 index 00000000..33e47317 --- /dev/null +++ b/puppet/modules/vcsrepo/examples/p4/sync_client.pp @@ -0,0 +1,6 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => present, + provider => 'p4', + source => '//depot/...', + revision => '30', +} diff --git a/puppet/modules/vcsrepo/examples/svn/checkout.pp b/puppet/modules/vcsrepo/examples/svn/checkout.pp new file mode 100644 index 00000000..f9fc2730 --- /dev/null +++ b/puppet/modules/vcsrepo/examples/svn/checkout.pp @@ -0,0 +1,5 @@ +vcsrepo { '/tmp/vcstest-svn-checkout': + ensure => present, + provider => svn, + source => 'http://svn.edgewall.org/repos/babel/trunk', +} diff --git a/puppet/modules/vcsrepo/examples/svn/server.pp b/puppet/modules/vcsrepo/examples/svn/server.pp new file mode 100644 index 00000000..de7c390f --- /dev/null +++ b/puppet/modules/vcsrepo/examples/svn/server.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest-svn-server': + ensure => present, + provider => svn, +} diff --git a/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo.rb b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo.rb new file mode 100644 index 00000000..8793e632 --- /dev/null +++ b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo.rb @@ -0,0 +1,42 @@ +require 'tmpdir' +require 'digest/md5' +require 'fileutils' + +# Abstract +class Puppet::Provider::Vcsrepo < Puppet::Provider + + private + + def set_ownership + owner = @resource.value(:owner) || nil + group = @resource.value(:group) || nil + FileUtils.chown_R(owner, group, @resource.value(:path)) + end + + def path_exists? + File.directory?(@resource.value(:path)) + end + + def path_empty? + # Path is empty if the only entries are '.' and '..' + d = Dir.new(@resource.value(:path)) + d.read # should return '.' + d.read # should return '..' + d.read.nil? + end + + # Note: We don't rely on Dir.chdir's behavior of automatically returning the + # value of the last statement -- for easier stubbing. + def at_path(&block) #:nodoc: + value = nil + Dir.chdir(@resource.value(:path)) do + value = yield + end + value + end + + def tempdir + @tempdir ||= File.join(Dir.tmpdir, 'vcsrepo-' + Digest::MD5.hexdigest(@resource.value(:path))) + end + +end diff --git a/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb new file mode 100644 index 00000000..797d84d2 --- /dev/null +++ b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb @@ -0,0 +1,93 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:bzr, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports Bazaar repositories" + + commands :bzr => 'bzr' + has_features :reference_tracking + + def create + if !@resource.value(:source) + create_repository(@resource.value(:path)) + else + clone_repository(@resource.value(:revision)) + end + end + + def working_copy_exists? + File.directory?(File.join(@resource.value(:path), '.bzr')) + end + + def exists? + working_copy_exists? + end + + def destroy + FileUtils.rm_rf(@resource.value(:path)) + end + + def revision + at_path do + current_revid = bzr('version-info')[/^revision-id:\s+(\S+)/, 1] + desired = @resource.value(:revision) + begin + desired_revid = bzr('revision-info', desired).strip.split(/\s+/).last + rescue Puppet::ExecutionFailure + # Possible revid available during update (but definitely not current) + desired_revid = nil + end + if current_revid == desired_revid + desired + else + current_revid + end + end + end + + def revision=(desired) + at_path do + begin + bzr('update', '-r', desired) + rescue Puppet::ExecutionFailure + bzr('update', '-r', desired, ':parent') + end + end + update_owner + end + + def latest + at_path do + bzr('version-info', ':parent')[/^revision-id:\s+(\S+)/, 1] + end + end + + def latest? + at_path do + return self.revision == self.latest + end + end + + private + + def create_repository(path) + bzr('init', path) + update_owner + end + + def clone_repository(revision) + args = ['branch'] + if revision + args.push('-r', revision) + end + args.push(@resource.value(:source), + @resource.value(:path)) + bzr(*args) + update_owner + end + + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end +end diff --git a/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb new file mode 100644 index 00000000..7a8f6ef3 --- /dev/null +++ b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb @@ -0,0 +1,135 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports CVS repositories/workspaces" + + commands :cvs => 'cvs' + has_features :gzip_compression, :reference_tracking, :modules, :cvs_rsh, :user + + def create + if !@resource.value(:source) + create_repository(@resource.value(:path)) + else + checkout_repository + end + update_owner + end + + def exists? + if @resource.value(:source) + directory = File.join(@resource.value(:path), 'CVS') + else + directory = File.join(@resource.value(:path), 'CVSROOT') + end + File.directory?(directory) + end + + def working_copy_exists? + File.directory?(File.join(@resource.value(:path), 'CVS')) + end + + def destroy + FileUtils.rm_rf(@resource.value(:path)) + end + + def latest? + Puppet.debug "Checking for updates because 'ensure => latest'" + at_path do + # We cannot use -P to prune empty dirs, otherwise + # CVS would report those as "missing", regardless + # if they have contents or updates. + is_current = (runcvs('-nq', 'update', '-d').strip == "") + if (!is_current) then Puppet.debug "There are updates available on the checkout's current branch/tag." end + return is_current + end + end + + def latest + # CVS does not have a conecpt like commit-IDs or change + # sets, so we can only have the current branch name (or the + # requested one, if that differs) as the "latest" revision. + should = @resource.value(:revision) + current = self.revision + return should != current ? should : current + end + + def revision + if !@rev + if File.exist?(tag_file) + contents = File.read(tag_file).strip + # Note: Doesn't differentiate between N and T entries + @rev = contents[1..-1] + else + @rev = 'HEAD' + end + Puppet.debug "Checkout is on branch/tag '#{@rev}'" + end + return @rev + end + + def revision=(desired) + at_path do + runcvs('update', '-dr', desired, '.') + update_owner + @rev = desired + end + end + + private + + def tag_file + File.join(@resource.value(:path), 'CVS', 'Tag') + end + + def checkout_repository + dirname, basename = File.split(@resource.value(:path)) + Dir.chdir(dirname) do + args = ['-d', @resource.value(:source)] + if @resource.value(:compression) + args.push('-z', @resource.value(:compression)) + end + args.push('checkout') + if @resource.value(:revision) + args.push('-r', @resource.value(:revision)) + end + args.push('-d', basename, module_name) + runcvs(*args) + end + end + + # When the source: + # * Starts with ':' (eg, :pserver:...) + def module_name + if (m = @resource.value(:module)) + m + elsif (source = @resource.value(:source)) + source[0, 1] == ':' ? File.basename(source) : '.' + end + end + + def create_repository(path) + runcvs('-d', path, 'init') + end + + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end + + def runcvs(*args) + if @resource.value(:cvs_rsh) + Puppet.debug "Using CVS_RSH = " + @resource.value(:cvs_rsh) + e = { :CVS_RSH => @resource.value(:cvs_rsh) } + else + e = {} + end + + if @resource.value(:user) and @resource.value(:user) != Facter['id'].value + Puppet.debug "Running as user " + @resource.value(:user) + Puppet::Util::Execution.execute([:cvs, *args], :uid => @resource.value(:user), :custom_environment => e) + else + Puppet::Util::Execution.execute([:cvs, *args], :custom_environment => e) + end + end +end diff --git a/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb new file mode 100644 index 00000000..27bfbbed --- /dev/null +++ b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb @@ -0,0 +1,12 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:dummy, :parent => Puppet::Provider::Vcsrepo) do + desc "Dummy default provider" + + defaultfor :feature => :posix + + def working_copy_exists? + providers = @resource.class.providers.map{|x| x.to_s}.sort.reject{|x| x == "dummy"}.join(", ") rescue "none" + raise("vcsrepo resource must have a provider, available: #{providers}") + end +end diff --git a/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/git.rb b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/git.rb new file mode 100644 index 00000000..9d18b474 --- /dev/null +++ b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/git.rb @@ -0,0 +1,483 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports Git repositories" + + has_command(:git, 'git') do + environment({ 'HOME' => ENV['HOME'] }) + end + + has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth, :branch, :submodules + + def create + if @resource.value(:revision) and ensure_bare_or_mirror? + fail("Cannot set a revision (#{@resource.value(:revision)}) on a bare repository") + end + if !@resource.value(:source) + if @resource.value(:ensure) == :mirror + fail("Cannot init repository with mirror option, try bare instead") + end + + init_repository(@resource.value(:path)) + else + clone_repository(default_url, @resource.value(:path)) + update_remotes + + if @resource.value(:revision) + checkout + end + if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true + update_submodules + end + + end + update_owner_and_excludes + end + + def destroy + FileUtils.rm_rf(@resource.value(:path)) + end + + # Checks to see if the current revision is equal to the revision on the + # remote (whether on a branch, tag, or reference) + # + # @return [Boolean] Returns true if the repo is on the latest revision + def latest? + return revision == latest_revision + end + + # Just gives the `should` value that we should be setting the repo to if + # latest? returns false + # + # @return [String] Returns the target sha/tag/branch + def latest + if not @resource.value(:revision) and branch = on_branch? + return branch + else + return @resource.value(:revision) + end + end + + # Get the current revision of the repo (tag/branch/sha) + # + # @return [String] Returns the branch/tag if the current sha matches the + # remote; otherwise returns the current sha. + def revision + #HEAD is the default, but lets just be explicit here. + get_revision('HEAD') + end + + # Is passed the desired reference, whether a tag, rev, or branch. Should + # handle transitions from a rev/branch/tag to a rev/branch/tag. Detached + # heads should be treated like bare revisions. + # + # @param [String] desired The desired revision to which the repo should be + # set. + def revision=(desired) + #just checkout tags and shas; fetch has already happened so they should be updated. + checkout(desired) + #branches require more work. + if local_branch_revision?(desired) + #reset instead of pull to avoid merge conflicts. assuming remote is + #updated and authoritative. + #TODO might be worthwhile to have an allow_local_changes param to decide + #whether to reset or pull when we're ensuring latest. + if @resource.value(:source) + at_path { git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{desired}") } + else + at_path { git_with_identity('reset', '--hard', "#{desired}") } + end + end + #TODO Would this ever reach here if it is bare? + if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true + update_submodules + end + update_owner_and_excludes + end + + def bare_exists? + bare_git_config_exists? && !working_copy_exists? + end + + def ensure_bare_or_mirror? + [:bare, :mirror].include? @resource.value(:ensure) + end + + # If :source is set to a hash (for supporting multiple remotes), + # we search for the URL for :remote. If it doesn't exist, + # we throw an error. If :source is just a string, we use that + # value for the default URL. + def default_url + if @resource.value(:source).is_a?(Hash) + if @resource.value(:source).has_key?(@resource.value(:remote)) + @resource.value(:source)[@resource.value(:remote)] + else + fail("You must specify the URL for #{@resource.value(:remote)} in the :source hash") + end + else + @resource.value(:source) + end + end + + def working_copy_exists? + if @resource.value(:source) and File.exists?(File.join(@resource.value(:path), '.git', 'config')) + File.readlines(File.join(@resource.value(:path), '.git', 'config')).grep(/#{Regexp.escape(default_url)}/).any? + else + File.directory?(File.join(@resource.value(:path), '.git')) + end + end + + def exists? + working_copy_exists? || bare_exists? + end + + def update_remote_url(remote_name, remote_url) + do_update = false + current = git_with_identity('config', '-l') + + unless remote_url.nil? + # Check if remote exists at all, regardless of URL. + # If remote doesn't exist, add it + if not current.include? "remote.#{remote_name}.url" + git_with_identity('remote','add', remote_name, remote_url) + return true + + # If remote exists, but URL doesn't match, update URL + elsif not current.include? "remote.#{remote_name}.url=#{remote_url}" + git_with_identity('remote','set-url', remote_name, remote_url) + return true + else + return false + end + end + + end + + def update_remotes + do_update = false + + # If supplied source is a hash of remote name and remote url pairs, then + # we loop around the hash. Otherwise, we assume single url specified + # in source property + if @resource.value(:source).is_a?(Hash) + @resource.value(:source).keys.sort.each do |remote_name| + remote_url = @resource.value(:source)[remote_name] + at_path { do_update |= update_remote_url(remote_name, remote_url) } + end + else + at_path { do_update |= update_remote_url(@resource.value(:remote), @resource.value(:source)) } + end + + # If at least one remote was added or updated, then we must + # call the 'git remote update' command + if do_update == true + at_path { git_with_identity('remote','update') } + end + + end + + def update_references + at_path do + update_remotes + git_with_identity('fetch', @resource.value(:remote)) + git_with_identity('fetch', '--tags', @resource.value(:remote)) + update_owner_and_excludes + end + end + + private + + def valid_repo? + Dir.chdir(@resource.value(:path)){ system('git rev-parse > /dev/null 2>&1')} + end + + def bare_git_config_exists? + File.exist?(File.join(@resource.value(:path), 'config')) && valid_repo? + end + + # @!visibility private + def clone_repository(source, path) + check_force + args = ['clone'] + if @resource.value(:depth) and @resource.value(:depth).to_i > 0 + args.push('--depth', @resource.value(:depth).to_s) + if @resource.value(:revision) + args.push('--branch', @resource.value(:revision).to_s) + end + end + if @resource.value(:branch) + args.push('--branch', @resource.value(:branch).to_s) + end + + case @resource.value(:ensure) + when :bare then args << '--bare' + when :mirror then args << '--mirror' + end + + if @resource.value(:remote) != 'origin' + args.push('--origin', @resource.value(:remote)) + end + if !working_copy_exists? + args.push(source, path) + Dir.chdir("/") do + git_with_identity(*args) + end + else + notice "Repo has already been cloned" + end + end + + # @!visibility private + def check_force + if path_exists? and not path_empty? + if @resource.value(:force) && !valid_repo? + notice "Removing %s to replace with vcsrepo." % @resource.value(:path) + destroy + else + raise Puppet::Error, "Could not create repository (non-repository at path)" + end + end + end + + # @!visibility private + def init_repository(path) + check_force + if @resource.value(:ensure) == :bare && working_copy_exists? + convert_working_copy_to_bare + elsif @resource.value(:ensure) == :present && bare_exists? + convert_bare_to_working_copy + else + # normal init + FileUtils.mkdir(@resource.value(:path)) + FileUtils.chown(@resource.value(:user), nil, @resource.value(:path)) if @resource.value(:user) + args = ['init'] + if @resource.value(:ensure) == :bare + args << '--bare' + end + at_path do + git_with_identity(*args) + end + end + end + + # Convert working copy to bare + # + # Moves: + # /.git + # to: + # / + # @!visibility private + def convert_working_copy_to_bare + notice "Converting working copy repository to bare repository" + FileUtils.mv(File.join(@resource.value(:path), '.git'), tempdir) + FileUtils.rm_rf(@resource.value(:path)) + FileUtils.mv(tempdir, @resource.value(:path)) + end + + # Convert bare to working copy + # + # Moves: + # / + # to: + # /.git + # @!visibility private + def convert_bare_to_working_copy + notice "Converting bare repository to working copy repository" + FileUtils.mv(@resource.value(:path), tempdir) + FileUtils.mkdir(@resource.value(:path)) + FileUtils.mv(tempdir, File.join(@resource.value(:path), '.git')) + if commits_in?(File.join(@resource.value(:path), '.git')) + reset('HEAD') + git_with_identity('checkout', '--force') + update_owner_and_excludes + end + end + + # @!visibility private + def commits_in?(dot_git) + Dir.glob(File.join(dot_git, 'objects/info/*'), File::FNM_DOTMATCH) do |e| + return true unless %w(. ..).include?(File::basename(e)) + end + false + end + + # Will checkout a rev/branch/tag using the locally cached versions. Does not + # handle upstream branch changes + # @!visibility private + def checkout(revision = @resource.value(:revision)) + if !local_branch_revision?(revision) && remote_branch_revision?(revision) + #non-locally existant branches (perhaps switching to a branch that has never been checked out) + at_path { git_with_identity('checkout', '--force', '-b', revision, '--track', "#{@resource.value(:remote)}/#{revision}") } + else + #tags, locally existant branches (perhaps outdated), and shas + at_path { git_with_identity('checkout', '--force', revision) } + end + end + + # @!visibility private + def reset(desired) + at_path do + git_with_identity('reset', '--hard', desired) + end + end + + # @!visibility private + def update_submodules + at_path do + git_with_identity('submodule', 'update', '--init', '--recursive') + end + end + + # Determins if the branch exists at the upstream but has not yet been locally committed + # @!visibility private + def remote_branch_revision?(revision = @resource.value(:revision)) + # git < 1.6 returns '#{@resource.value(:remote)}/#{revision}' + # git 1.6+ returns 'remotes/#{@resource.value(:remote)}/#{revision}' + branch = at_path { branches.grep /(remotes\/)?#{@resource.value(:remote)}\/#{revision}$/ } + branch unless branch.empty? + end + + # Determins if the branch is already cached locally + # @!visibility private + def local_branch_revision?(revision = @resource.value(:revision)) + at_path { branches.include?(revision) } + end + + # @!visibility private + def tag_revision?(revision = @resource.value(:revision)) + at_path { tags.include?(revision) } + end + + # @!visibility private + def branches + at_path { git_with_identity('branch', '-a') }.gsub('*', ' ').split(/\n/).map { |line| line.strip } + end + + # git < 2.4 returns 'detached from' + # git 2.4+ returns 'HEAD detached at' + # @!visibility private + def on_branch? + at_path { + matches = git_with_identity('branch', '-a').match /\*\s+(.*)/ + matches[1] unless matches[1].match /(\(detached from|\(HEAD detached at|\(no branch)/ + } + end + + # @!visibility private + def tags + at_path { git_with_identity('tag', '-l') }.split(/\n/).map { |line| line.strip } + end + + # @!visibility private + def set_excludes + # Excludes may be an Array or a String. + at_path do + open('.git/info/exclude', 'w') do |f| + if @resource.value(:excludes).respond_to?(:each) + @resource.value(:excludes).each { |ex| f.puts ex } + else + f.puts @resource.value(:excludes) + end + end + end + end + + # Finds the latest revision or sha of the current branch if on a branch, or + # of HEAD otherwise. + # @note Calls create which can forcibly destroy and re-clone the repo if + # force => true + # @see get_revision + # + # @!visibility private + # @return [String] Returns the output of get_revision + def latest_revision + #TODO Why is create called here anyway? + create if @resource.value(:force) && working_copy_exists? + create if !working_copy_exists? + + if branch = on_branch? + return get_revision("#{@resource.value(:remote)}/#{branch}") + else + return get_revision + end + end + + # Returns the current revision given if the revision is a tag or branch and + # matches the current sha. If the current sha does not match the sha of a tag + # or branch, then it will just return the sha (ie, is not in sync) + # + # @!visibility private + # + # @param [String] rev The revision of which to check if it is current + # @return [String] Returns the tag/branch of the current repo if it's up to + # date; otherwise returns the sha of the requested revision. + def get_revision(rev = 'HEAD') + if @resource.value(:source) + update_references + else + status = at_path { git_with_identity('status')} + is_it_new = status =~ /Initial commit/ + if is_it_new + status =~ /On branch (.*)/ + branch = $1 + return branch + end + end + current = at_path { git_with_identity('rev-parse', rev).strip } + if @resource.value(:revision) + if tag_revision? + # git-rev-parse will give you the hash of the tag object itself rather + # than the commit it points to by default. Using tag^0 will return the + # actual commit. + canonical = at_path { git_with_identity('rev-parse', "#{@resource.value(:revision)}^0").strip } + elsif local_branch_revision? + canonical = at_path { git_with_identity('rev-parse', @resource.value(:revision)).strip } + elsif remote_branch_revision? + canonical = at_path { git_with_identity('rev-parse', "#{@resource.value(:remote)}/#{@resource.value(:revision)}").strip } + else + #look for a sha (could match invalid shas) + canonical = at_path { git_with_identity('rev-parse', '--revs-only', @resource.value(:revision)).strip } + end + fail("#{@resource.value(:revision)} is not a local or remote ref") if canonical.nil? or canonical.empty? + current = @resource.value(:revision) if current == canonical + end + return current + end + + # @!visibility private + def update_owner_and_excludes + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + if @resource.value(:excludes) + set_excludes + end + end + + # @!visibility private + def git_with_identity(*args) + if @resource.value(:identity) + Tempfile.open('git-helper', Puppet[:statedir]) do |f| + f.puts '#!/bin/sh' + f.puts 'export SSH_AUTH_SOCKET=' + f.puts "exec ssh -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oChallengeResponseAuthentication=no -oConnectTimeout=120 -i #{@resource.value(:identity)} $*" + f.close + + FileUtils.chmod(0755, f.path) + env_save = ENV['GIT_SSH'] + ENV['GIT_SSH'] = f.path + + ret = git(*args) + + ENV['GIT_SSH'] = env_save + + return ret + end + elsif @resource.value(:user) and @resource.value(:user) != Facter['id'].value + env = Etc.getpwnam(@resource.value(:user)) + Puppet::Util::Execution.execute("git #{args.join(' ')}", :uid => @resource.value(:user), :failonfail => true, :custom_environment => {'HOME' => env['dir']}) + else + git(*args) + end + end +end diff --git a/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb new file mode 100644 index 00000000..294c2a97 --- /dev/null +++ b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb @@ -0,0 +1,130 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports Mercurial repositories" + + commands :hg => 'hg' + + has_features :reference_tracking, :ssh_identity, :user, :basic_auth + + def create + if !@resource.value(:source) + create_repository(@resource.value(:path)) + else + clone_repository(@resource.value(:revision)) + end + update_owner + end + + def working_copy_exists? + File.directory?(File.join(@resource.value(:path), '.hg')) + end + + def exists? + working_copy_exists? + end + + def destroy + FileUtils.rm_rf(@resource.value(:path)) + end + + def latest? + at_path do + return self.revision == self.latest + end + end + + def latest + at_path do + begin + hg_wrapper('incoming', '--branch', '.', '--newest-first', '--limit', '1', { :remote => true })[/^changeset:\s+(?:-?\d+):(\S+)/m, 1] + rescue Puppet::ExecutionFailure + # If there are no new changesets, return the current nodeid + self.revision + end + end + end + + def revision + at_path do + current = hg_wrapper('parents')[/^changeset:\s+(?:-?\d+):(\S+)/m, 1] + desired = @resource.value(:revision) + if desired + # Return the tag name if it maps to the current nodeid + mapped = hg_wrapper('tags')[/^#{Regexp.quote(desired)}\s+\d+:(\S+)/m, 1] + if current == mapped + desired + else + current + end + else + current + end + end + end + + def revision=(desired) + at_path do + begin + hg_wrapper('pull', { :remote => true }) + rescue + end + begin + hg_wrapper('merge') + rescue Puppet::ExecutionFailure + # If there's nothing to merge, just skip + end + hg_wrapper('update', '--clean', '-r', desired) + end + update_owner + end + + private + + def create_repository(path) + hg_wrapper('init', path) + end + + def clone_repository(revision) + args = ['clone'] + if revision + args.push('-u', revision) + end + args.push(@resource.value(:source), + @resource.value(:path)) + args.push({ :remote => true }) + hg_wrapper(*args) + end + + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end + + def hg_wrapper(*args) + options = { :remote => false } + if args.length > 0 and args[-1].is_a? Hash + options.merge!(args.pop) + end + + if @resource.value(:basic_auth_username) && @resource.value(:basic_auth_password) + args += [ + "--config", "\"auth.x.prefix=#{@resource.value(:source)}\"", + "--config", "\"auth.x.username=#{@resource.value(:basic_auth_username)}\"", + "--config", "\"auth.x.password=#{@resource.value(:basic_auth_password)}\"", + "--config", "\"auth.x.schemes=http https\"" + ] + end + + if options[:remote] and @resource.value(:identity) + args += ["--ssh", "ssh -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oChallengeResponseAuthentication=no -i #{@resource.value(:identity)}"] + end + if @resource.value(:user) and @resource.value(:user) != Facter['id'].value + args.map! { |a| if a =~ /\s/ then "'#{a}'" else a end } # Adds quotes to arguments with whitespaces. + Puppet::Util::Execution.execute("hg #{args.join(' ')}", :uid => @resource.value(:user), :failonfail => true) + else + hg(*args) + end + end +end diff --git a/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/p4.rb b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/p4.rb new file mode 100644 index 00000000..b429bcbb --- /dev/null +++ b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/p4.rb @@ -0,0 +1,278 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports Perforce depots" + + has_features :filesystem_types, :reference_tracking, :p4config + + def create + # create or update client + create_client(client_name) + + # if source provided, sync client + source = @resource.value(:source) + if source + revision = @resource.value(:revision) + sync_client(source, revision) + end + + update_owner + end + + def working_copy_exists? + # Check if the server is there, or raise error + p4(['info'], {:marshal => false}) + + # Check if workspace is setup + args = ['where'] + args.push(@resource.value(:path) + "...") + hash = p4(args, {:raise => false}) + + return (hash['code'] != "error") + end + + def exists? + working_copy_exists? + end + + def destroy + args = ['client'] + args.push('-d', '-f') + args.push(client_name) + p4(args) + FileUtils.rm_rf(@resource.value(:path)) + end + + def latest? + rev = self.revision + if rev + (rev >= self.latest) + else + true + end + end + + def latest + args = ['changes'] + args.push('-m1', @resource.value(:source)) + hash = p4(args) + + return hash['change'].to_i + end + + def revision + args = ['cstat'] + args.push(@resource.value(:source)) + hash = p4(args, {:marshal => false}) + hash = marshal_cstat(hash) + + revision = 0 + if hash && hash['code'] != 'error' + hash['data'].each do |c| + if c['status'] == 'have' + change = c['change'].to_i + revision = change if change > revision + end + end + end + return revision + end + + def revision=(desired) + sync_client(@resource.value(:source), desired) + update_owner + end + + private + + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end + + # Sync the client workspace files to head or specified revision. + # Params: + # +source+:: Depot path to sync + # +revision+:: Perforce change list to sync to (optional) + def sync_client(source, revision) + Puppet.debug "Syncing: #{source}" + args = ['sync'] + if revision + args.push(source + "@#{revision}") + else + args.push(source) + end + p4(args) + end + + # Returns the name of the Perforce client workspace + def client_name + p4config = @resource.value(:p4config) + + # default (generated) client name + path = @resource.value(:path) + host = Facter.value('hostname') + default = "puppet-" + Digest::MD5.hexdigest(path + host) + + # check config for client name + set_client = nil + if p4config && File.file?(p4config) + open(p4config) do |f| + m = f.grep(/^P4CLIENT=/).pop + p = /^P4CLIENT=(.*)$/ + set_client = p.match(m)[1] if m + end + end + + return set_client || ENV['P4CLIENT'] || default + end + + # Create (or update) a client workspace spec. + # If a client name is not provided then a hash based on the path is used. + # Params: + # +client+:: Name of client workspace + # +path+:: The Root location of the Perforce client workspace + def create_client(client) + Puppet.debug "Creating client: #{client}" + + # fetch client spec + hash = parse_client(client) + hash['Root'] = @resource.value(:path) + hash['Description'] = "Generated by Puppet VCSrepo" + + # check is source is a Stream + source = @resource.value(:source) + if source + parts = source.split(/\//) + if parts && parts.length >= 4 + source = "//" + parts[2] + "/" + parts[3] + streams = p4(['streams', source], {:raise => false}) + if streams['code'] == "stat" + hash['Stream'] = streams['Stream'] + notice "Streams" + streams['Stream'].inspect + end + end + end + + # save client spec + save_client(hash) + end + + + # Fetches a client workspace spec from Perforce and returns a hash map representation. + # Params: + # +client+:: name of the client workspace + def parse_client(client) + args = ['client'] + args.push('-o', client) + hash = p4(args) + + return hash + end + + + # Saves the client workspace spec from the given hash + # Params: + # +hash+:: hash map of client spec + def save_client(hash) + spec = String.new + view = "\nView:\n" + + hash.keys.sort.each do |k| + v = hash[k] + next if( k == "code" ) + if(k.to_s =~ /View/ ) + view += "\t#{v}\n" + else + spec += "#{k.to_s}: #{v.to_s}\n" + end + end + spec += view + + args = ['client'] + args.push('-i') + p4(args, {:input => spec, :marshal => false}) + end + + # Sets Perforce Configuration environment. + # P4CLIENT generated, but overwitten if defined in config. + def config + p4config = @resource.value(:p4config) + + cfg = Hash.new + cfg.store 'P4CONFIG', p4config if p4config + cfg.store 'P4CLIENT', client_name + return cfg + end + + def p4(args, options = {}) + # Merge custom options with defaults + opts = { + :raise => true, # Raise errors + :marshal => true, # Marshal output + }.merge(options) + + cmd = ['p4'] + cmd.push '-R' if opts[:marshal] + cmd.push args + cmd_str = cmd.respond_to?(:join) ? cmd.join(' ') : cmd + + Puppet.debug "environment: #{config}" + Puppet.debug "command: #{cmd_str}" + + hash = Hash.new + Open3.popen3(config, cmd_str) do |i, o, e, t| + # Send input stream if provided + if(opts[:input]) + Puppet.debug "input:\n" + opts[:input] + i.write opts[:input] + i.close + end + + if(opts[:marshal]) + hash = Marshal.load(o) + else + hash['data'] = o.read + end + + # Raise errors, Perforce or Exec + if(opts[:raise] && !e.eof && t.value != 0) + raise Puppet::Error, "\nP4: #{e.read}" + end + if(opts[:raise] && hash['code'] == 'error' && t.value != 0) + raise Puppet::Error, "\nP4: #{hash['data']}" + end + end + + Puppet.debug "hash: #{hash}\n" + return hash + end + + # helper method as cstat does not Marshal + def marshal_cstat(hash) + data = hash['data'] + code = 'error' + + list = Array.new + change = Hash.new + data.each_line do |l| + p = /^\.\.\. (.*) (.*)$/ + m = p.match(l) + if m + change[m[1]] = m[2] + if m[1] == 'status' + code = 'stat' + list.push change + change = Hash.new + end + end + end + + hash = Hash.new + hash.store 'code', code + hash.store 'data', list + return hash + end + +end diff --git a/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb new file mode 100644 index 00000000..fccfaa5a --- /dev/null +++ b/puppet/modules/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb @@ -0,0 +1,139 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports Subversion repositories" + + commands :svn => 'svn', + :svnadmin => 'svnadmin', + :svnlook => 'svnlook' + + has_features :filesystem_types, :reference_tracking, :basic_auth, :configuration, :conflict, :depth + + def create + if !@resource.value(:source) + create_repository(@resource.value(:path)) + else + checkout_repository(@resource.value(:source), + @resource.value(:path), + @resource.value(:revision), + @resource.value(:depth)) + end + update_owner + end + + def working_copy_exists? + if File.directory?(@resource.value(:path)) + # :path is an svn checkout + return true if File.directory?(File.join(@resource.value(:path), '.svn')) + if File.file?(File.join(@resource.value(:path), 'format')) + # :path is an svn server + return true if svnlook('uuid', @resource.value(:path)) + end + end + false + end + + def exists? + working_copy_exists? + end + + def destroy + FileUtils.rm_rf(@resource.value(:path)) + end + + def latest? + at_path do + (self.revision >= self.latest) and (@resource.value(:source) == self.sourceurl) + end + end + + def buildargs + args = ['--non-interactive'] + if @resource.value(:basic_auth_username) && @resource.value(:basic_auth_password) + args.push('--username', @resource.value(:basic_auth_username)) + args.push('--password', @resource.value(:basic_auth_password)) + args.push('--no-auth-cache') + end + + if @resource.value(:force) + args.push('--force') + end + + if @resource.value(:configuration) + args.push('--config-dir', @resource.value(:configuration)) + end + + if @resource.value(:trust_server_cert) != :false + args.push('--trust-server-cert') + end + + args + end + + def latest + args = buildargs.push('info', '-r', 'HEAD') + at_path do + svn(*args)[/^Revision:\s+(\d+)/m, 1] + end + end + + def sourceurl + args = buildargs.push('info') + at_path do + svn(*args)[/^URL:\s+(\S+)/m, 1] + end + end + + def revision + args = buildargs.push('info') + at_path do + svn(*args)[/^Revision:\s+(\d+)/m, 1] + end + end + + def revision=(desired) + args = if @resource.value(:source) + buildargs.push('switch', '-r', desired, @resource.value(:source)) + else + buildargs.push('update', '-r', desired) + end + + if @resource.value(:conflict) + args.push('--accept', @resource.value(:conflict)) + end + + at_path do + svn(*args) + end + update_owner + end + + private + + def checkout_repository(source, path, revision, depth) + args = buildargs.push('checkout') + if revision + args.push('-r', revision) + end + if depth + args.push('--depth', depth) + end + args.push(source, path) + svn(*args) + end + + def create_repository(path) + args = ['create'] + if @resource.value(:fstype) + args.push('--fs-type', @resource.value(:fstype)) + end + args << path + svnadmin(*args) + end + + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end +end diff --git a/puppet/modules/vcsrepo/lib/puppet/type/vcsrepo.rb b/puppet/modules/vcsrepo/lib/puppet/type/vcsrepo.rb new file mode 100644 index 00000000..e2ef0b7e --- /dev/null +++ b/puppet/modules/vcsrepo/lib/puppet/type/vcsrepo.rb @@ -0,0 +1,248 @@ +require 'pathname' + +Puppet::Type.newtype(:vcsrepo) do + desc "A local version control repository" + + feature :gzip_compression, + "The provider supports explicit GZip compression levels" + feature :basic_auth, + "The provider supports HTTP Basic Authentication" + feature :bare_repositories, + "The provider differentiates between bare repositories + and those with working copies", + :methods => [:bare_exists?, :working_copy_exists?] + + feature :filesystem_types, + "The provider supports different filesystem types" + + feature :reference_tracking, + "The provider supports tracking revision references that can change + over time (eg, some VCS tags and branch names)" + + feature :ssh_identity, + "The provider supports a configurable SSH identity file" + + feature :user, + "The provider can run as a different user" + + feature :modules, + "The repository contains modules that can be chosen of" + + feature :multiple_remotes, + "The repository tracks multiple remote repositories" + + feature :configuration, + "The configuration directory to use" + + feature :cvs_rsh, + "The provider understands the CVS_RSH environment variable" + + feature :depth, + "The provider can do shallow clones or set scope limit" + + feature :branch, + "The name of the branch" + + feature :p4config, + "The provider understands Perforce Configuration" + + feature :submodules, + "The repository contains submodules which can be optionally initialized" + + feature :conflict, + "The provider supports automatic conflict resolution" + + ensurable do + attr_accessor :latest + + def insync?(is) + @should ||= [] + + case should + when :present + return true unless [:absent, :purged, :held].include?(is) + when :latest + if is == :latest + return true + else + return false + end + when :bare + return is == :bare + when :mirror + return is == :mirror + end + end + + newvalue :present do + notice "Creating repository from present" + provider.create + end + + newvalue :bare, :required_features => [:bare_repositories] do + if !provider.exists? + provider.create + end + end + + newvalue :mirror, :required_features => [:bare_repositories] do + if !provider.exists? + provider.create + end + end + + newvalue :absent do + provider.destroy + end + + newvalue :latest, :required_features => [:reference_tracking] do + if provider.exists? && !@resource.value(:force) + if provider.respond_to?(:update_references) + provider.update_references + end + if provider.respond_to?(:latest?) + reference = provider.latest || provider.revision + else + reference = resource.value(:revision) || provider.revision + end + notice "Updating to latest '#{reference}' revision" + provider.revision = reference + else + notice "Creating repository from latest" + provider.create + end + end + + def retrieve + prov = @resource.provider + if prov + if prov.working_copy_exists? + (@should.include?(:latest) && prov.latest?) ? :latest : :present + elsif prov.class.feature?(:bare_repositories) and prov.bare_exists? + :bare + else + :absent + end + else + raise Puppet::Error, "Could not find provider" + end + end + + end + + newparam :path do + desc "Absolute path to repository" + isnamevar + validate do |value| + path = Pathname.new(value) + unless path.absolute? + raise ArgumentError, "Path must be absolute: #{path}" + end + end + end + + newparam :source do + desc "The source URI for the repository" + end + + newparam :fstype, :required_features => [:filesystem_types] do + desc "Filesystem type" + end + + newproperty :revision do + desc "The revision of the repository" + newvalue(/^\S+$/) + end + + newparam :owner do + desc "The user/uid that owns the repository files" + end + + newparam :group do + desc "The group/gid that owns the repository files" + end + + newparam :user do + desc "The user to run for repository operations" + end + + newparam :excludes do + desc "Files to be excluded from the repository" + end + + newparam :force do + desc "Force repository creation, destroying any files on the path in the process." + newvalues(:true, :false) + defaultto false + end + + newparam :compression, :required_features => [:gzip_compression] do + desc "Compression level" + validate do |amount| + unless Integer(amount).between?(0, 6) + raise ArgumentError, "Unsupported compression level: #{amount} (expected 0-6)" + end + end + end + + newparam :basic_auth_username, :required_features => [:basic_auth] do + desc "HTTP Basic Auth username" + end + + newparam :basic_auth_password, :required_features => [:basic_auth] do + desc "HTTP Basic Auth password" + end + + newparam :identity, :required_features => [:ssh_identity] do + desc "SSH identity file" + end + + newparam :module, :required_features => [:modules] do + desc "The repository module to manage" + end + + newparam :remote, :required_features => [:multiple_remotes] do + desc "The remote repository to track" + defaultto "origin" + end + + newparam :configuration, :required_features => [:configuration] do + desc "The configuration directory to use" + end + + newparam :cvs_rsh, :required_features => [:cvs_rsh] do + desc "The value to be used for the CVS_RSH environment variable." + end + + newparam :depth, :required_features => [:depth] do + desc "The value to be used to do a shallow clone." + end + + newparam :branch, :required_features => [:branch] do + desc "The name of the branch to clone." + end + + newparam :p4config, :required_features => [:p4config] do + desc "The Perforce P4CONFIG environment." + end + + newparam :submodules, :required_features => [:submodules] do + desc "Initialize and update each submodule in the repository." + newvalues(:true, :false) + defaultto true + end + + newparam :conflict do + desc "The action to take if conflicts exist between repository and working copy" + end + + newparam :trust_server_cert do + desc "Trust server certificate" + newvalues(:true, :false) + defaultto :false + end + + autorequire(:package) do + ['git', 'git-core', 'mercurial'] + end +end diff --git a/puppet/modules/vcsrepo/metadata.json b/puppet/modules/vcsrepo/metadata.json new file mode 100644 index 00000000..c505faac --- /dev/null +++ b/puppet/modules/vcsrepo/metadata.json @@ -0,0 +1,81 @@ +{ + "name": "puppetlabs-vcsrepo", + "version": "1.3.2", + "author": "Puppet Labs", + "summary": "Puppet module providing a type to manage repositories from various version control systems", + "license": "GPL-2.0+", + "source": "https://github.com/puppetlabs/puppetlabs-vcsrepo", + "project_page": "https://github.com/puppetlabs/puppetlabs-vcsrepo", + "issues_url": "https://tickets.puppetlabs.com/browse/MODULES", + "dependencies": [ + + ], + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "CentOS", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "OracleLinux", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "Scientific", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "SLES", + "operatingsystemrelease": [ + "10 SP4", + "11 SP1", + "12" + ] + }, + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "6", + "7", + "8" + ] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "10.04", + "12.04", + "14.04" + ] + } + ], + "requirements": [ + { + "name": "pe", + "version_requirement": ">= 3.0.0 < 2015.4.0" + }, + { + "name": "puppet", + "version_requirement": ">= 3.0.0 < 5.0.0" + } + ] +} diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb new file mode 100644 index 00000000..421c5f06 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb @@ -0,0 +1,69 @@ +test_name 'C3492 - checkout with basic auth (http protocol)' +skip_test 'HTTP not supported yet for basic auth using git. See FM-1331' + +# Globals +repo_name = 'testrepo_checkout' +user = 'foo' +password = 'bar' +http_server_script = 'basic_auth_http_daemon.rb' + +hosts.each do |host| + ruby = '/opt/puppet/bin/ruby' if host.is_pe? || 'ruby' + gem = '/opt/puppet/bin/gem' if host.is_pe? || 'gem' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + script =<<-EOF + require 'sinatra' + + set :bind, '0.0.0.0' + set :static, true + set :public_folder, '#{tmpdir}' + + + use Rack::Auth::Basic do |username, password| + username == '#{user}' && password == '#{password}' + end + EOF + create_remote_file(host, "#{tmpdir}/#{http_server_script}", script) + on(host, "#{gem} install sinatra") + on(host, "#{ruby} #{tmpdir}/#{http_server_script} &") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} #{tmpdir}/#{http_server_script}' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout with puppet using basic auth' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:4567/testrepo.git", + provider => git, + basic_auth_username => '#{user}', + basic_auth_password => '#{password}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb new file mode 100644 index 00000000..753e50ca --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb @@ -0,0 +1,77 @@ +test_name 'C3493 - checkout with basic auth (https protocol)' +skip_test 'waiting for CA trust solution' + +# Globals +repo_name = 'testrepo_checkout' +user = 'foo' +password = 'bar' +http_server_script = 'basic_auth_https_daemon.rb' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start https server' do + script =<<-EOF + require 'webrick' + require 'webrick/https' + + authenticate = Proc.new do |req, res| + WEBrick::HTTPAuth.basic_auth(req, res, '') do |user, password| + user == '#{user}' && password == '#{password}' + end + end + + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :DocumentRootOptions=> {:HandlerCallback => authenticate}, + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, "#{tmpdir}/#{http_server_script}", script) + on(host, "#{ruby} #{tmpdir}/#{http_server_script}") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} #{tmpdir}/#{http_server_script}' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout with puppet using basic auth' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8443/testrepo.git", + provider => git, + basic_auth_username => '#{user}', + basic_auth_password => '#{password}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb new file mode 100644 index 00000000..3b47c485 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb @@ -0,0 +1,53 @@ +test_name 'C3494 - checkout with basic auth (git protocol)' + +# Globals +repo_name = 'testrepo_checkout' +user = 'foo' +password = 'bar' +http_server_script = 'basic_auth_http_daemon.rb' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'checkout with puppet using basic auth' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + basic_auth_username => '#{user}', + basic_auth_password => '#{password}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout (silent error for basic auth using git protocol)" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb new file mode 100644 index 00000000..3d2131c2 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb @@ -0,0 +1,48 @@ +test_name 'C3438 - checkout a branch (file protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb new file mode 100644 index 00000000..49b034e3 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb @@ -0,0 +1,48 @@ +test_name 'C3437 - checkout a branch (file path)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb new file mode 100644 index 00000000..9557de85 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb @@ -0,0 +1,53 @@ +test_name 'C3436 - checkout a branch (git protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb new file mode 100644 index 00000000..fec60e2a --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb @@ -0,0 +1,61 @@ +test_name 'C3441 - checkout a branch (http protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb new file mode 100644 index 00000000..3474c73d --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb @@ -0,0 +1,68 @@ +test_name 'C3442 - checkout a branch (https protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb new file mode 100644 index 00000000..493b3f49 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb @@ -0,0 +1,59 @@ +test_name 'C3439 - checkout a branch (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb new file mode 100644 index 00000000..5195ab8c --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb @@ -0,0 +1,59 @@ +test_name 'C3440 - checkout a branch (ssh protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb new file mode 100644 index 00000000..7b9e64d7 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb @@ -0,0 +1,46 @@ +test_name 'C3609 - checkout a branch that does not exist' + +# Globals +repo_name = 'testrepo_branch_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout branch that does not exist with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => 'non_existent_branch', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify that master branch is checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file.rb new file mode 100644 index 00000000..45413a96 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file.rb @@ -0,0 +1,46 @@ +test_name 'C3427 - clone (file protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file_path.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file_path.rb new file mode 100644 index 00000000..a57e05a4 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file_path.rb @@ -0,0 +1,46 @@ +test_name 'C3426 - clone (file path)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_git.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_git.rb new file mode 100644 index 00000000..3bceb5dd --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_git.rb @@ -0,0 +1,51 @@ +test_name 'C3425 - clone (git protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_http.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_http.rb new file mode 100644 index 00000000..f545dab3 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_http.rb @@ -0,0 +1,59 @@ +test_name 'C3430 - clone (http protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_https.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_https.rb new file mode 100644 index 00000000..8758435a --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_https.rb @@ -0,0 +1,66 @@ +test_name 'C3431 - clone (https protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb new file mode 100644 index 00000000..3bc3e304 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb @@ -0,0 +1,49 @@ +test_name 'C3511 - clone over an existing repo with force' + +# Globals +repo_name = 'testrepo_already_exists' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + on(host, "mkdir #{tmpdir}/#{repo_name}") + on(host, "cd #{tmpdir}/#{repo_name} && git init") + on(host, "cd #{tmpdir}/#{repo_name} && touch a && git add a && git commit -m 'a'") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone over existing repo with force using puppet' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + @existing_sha = res.stdout + end + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + force => true, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify new repo has replaced old one' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + fail_test('original repo not replaced by force') if res.stdout.include? "#{@existing_sha}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb new file mode 100644 index 00000000..dec275fa --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb @@ -0,0 +1,46 @@ +test_name 'C3507 - clone repo with excludes in repo' + +# Globals +repo_name = 'testrepo_with_excludes_in_repo' +exclude1 = 'file1.txt' +exclude2 ='file2.txt' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone repo with excludes in repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + excludes => [ '#{exclude1}', '#{exclude2}' ], + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify exludes are known to git' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/info/exclude") do |res| + fail_test('exclude not found') unless res.stdout.include? "#{exclude1}" + fail_test('exclude not found') unless res.stdout.include? "#{exclude2}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb new file mode 100644 index 00000000..ba379309 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb @@ -0,0 +1,46 @@ +test_name 'C3508 - clone repo with excludes not in repo' + +# Globals +repo_name = 'testrepo_with_excludes_not_in_repo' +exclude1 = 'worh02o' +exclude2 ='ho398b' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone repo with excludes not in repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + excludes => [ '#{exclude1}', '#{exclude2}' ], + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify exludes are known to git' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/info/exclude") do |res| + fail_test('exclude not found') unless res.stdout.include? "#{exclude1}" + fail_test('exclude not found') unless res.stdout.include? "#{exclude2}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_scp.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_scp.rb new file mode 100644 index 00000000..59370ebd --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_scp.rb @@ -0,0 +1,57 @@ +test_name 'C3428 - clone (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_ssh.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_ssh.rb new file mode 100644 index 00000000..5bc06ec8 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_ssh.rb @@ -0,0 +1,57 @@ +test_name 'C3429 - clone (ssh protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb new file mode 100644 index 00000000..1e3b4bb5 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb @@ -0,0 +1,47 @@ +test_name 'C3482 - clone over an existing repo' + +# Globals +repo_name = 'testrepo_already_exists' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + on(host, "mkdir #{tmpdir}/#{repo_name}") + on(host, "cd #{tmpdir}/#{repo_name} && git init") + on(host, "cd #{tmpdir}/#{repo_name} && touch a && git add a && git commit -m 'a'") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone over existing repo using puppet' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + @existing_sha = res.stdout + end + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify original repo was not replaced' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + fail_test('original repo was replaced without force') unless res.stdout.include? "#{@existing_sha}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb new file mode 100644 index 00000000..98053555 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb @@ -0,0 +1,45 @@ +test_name 'C3509 - clone repo with excludes not in repo' +skip_test 'expectations not defined' + +# Globals +repo_name = 'testrepo_with_excludes_not_in_repo' +exclude1 = "`exec \"rm -rf /tmp\"`" + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone repo with excludes not in repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + excludes => [ '#{exclude1}' ], + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify excludes are known to git' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/info/exclude") do |res| + fail_test('exclude not found') unless res.stdout.include? "#{exclude1}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_0_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_0_checkout.rb new file mode 100644 index 00000000..7ac4c4a0 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_0_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3495 - checkout with compression 0' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 0 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 0, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_1_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_1_checkout.rb new file mode 100644 index 00000000..8b7455d8 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_1_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3496 - checkout with compression 1' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 1 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_2_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_2_checkout.rb new file mode 100644 index 00000000..81d32c3f --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_2_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3497 - checkout with compression 2' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 2 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 2, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_3_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_3_checkout.rb new file mode 100644 index 00000000..12b60a37 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_3_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3498 - checkout with compression 3' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 3 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 3, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_4_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_4_checkout.rb new file mode 100644 index 00000000..66d2d5eb --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_4_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3499 - checkout with compression 4' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 4 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 4, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_5_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_5_checkout.rb new file mode 100644 index 00000000..b60a9f7f --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_5_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3500 - checkout with compression 5' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 5 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 5, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_6_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_6_checkout.rb new file mode 100644 index 00000000..2f6b075a --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_6_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3501 - checkout with compression 6' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 6 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 6, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb new file mode 100644 index 00000000..e74cca92 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3503 - checkout with compression 7' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 7 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 7, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb new file mode 100644 index 00000000..59aaf219 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3505 - checkout with compression alpha' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression alpha with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => abcde, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb new file mode 100644 index 00000000..b989e586 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3504 - checkout with compression 10-5' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 10-5 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 10-5, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb new file mode 100644 index 00000000..e1373afb --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3506 - checkout with compression exec' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression exec with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => "exec 'rm -rf /tmp'", + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb new file mode 100644 index 00000000..1253db1d --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3502 - checkout with compression -1' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression -1 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => -1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb new file mode 100644 index 00000000..ccb8a707 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb @@ -0,0 +1,40 @@ +test_name 'C3472 - create bare repo that already exists' + +# Globals +repo_name = 'testrepo_bare_repo_already_exists.git' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create bare repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + on(host, "mkdir #{tmpdir}/#{repo_name}") + on(host, "cd #{tmpdir}/#{repo_name} && git --bare init") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'create bare repo that already exists using puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => bare, + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify repo does not contain .git directory' do + on(host, "ls -al #{tmpdir}/#{repo_name}") do |res| + fail_test "found .git for #{repo_name}" if res.stdout.include? ".git" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb new file mode 100644 index 00000000..8fb85435 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb @@ -0,0 +1,42 @@ +test_name 'C3470 - create repo that already exists' + +# Globals +repo_name = 'testrepo_already_exists' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + on(host, "cd #{tmpdir} && git clone file://#{tmpdir}/testrepo.git #{repo_name}") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'create repo that already exists using puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify repo is on master branch' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + assert_match(/ref: refs\/heads\/master/, stdout, "Git checkout not on master on #{host}") + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb new file mode 100644 index 00000000..5b789df1 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb @@ -0,0 +1,38 @@ +test_name 'C3473 - create bare repo specifying revision' + +# Globals +repo_name = 'testrepo_bare.git' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'create bare repo specifying revision using puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => bare, + revision => master, + provider => git, + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify repo does not contain .git directory' do + on(host, "ls -al #{tmpdir}") do |res| + fail_test "found repo for #{repo_name}" if res.stdout.include? repo_name + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb new file mode 100644 index 00000000..beea7b80 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb @@ -0,0 +1,53 @@ +test_name 'C3487 - checkout as a group (file protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb new file mode 100644 index 00000000..319a8e74 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb @@ -0,0 +1,53 @@ +test_name 'C3486 - checkout as a group (file path)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb new file mode 100644 index 00000000..e5b9cf29 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb @@ -0,0 +1,58 @@ +test_name 'C3485 - checkout as a group (git protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb new file mode 100644 index 00000000..bf86f2eb --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb @@ -0,0 +1,66 @@ +test_name 'C3490 - checkout as a group (http protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb new file mode 100644 index 00000000..c4c645f9 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb @@ -0,0 +1,73 @@ +test_name 'C3491 - checkout as a group (https protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb new file mode 100644 index 00000000..c65acc43 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb @@ -0,0 +1,64 @@ +test_name 'C3488 - checkout as a group (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb new file mode 100644 index 00000000..cccad19c --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb @@ -0,0 +1,64 @@ +test_name 'C3489 - checkout as a group (ssh protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb new file mode 100644 index 00000000..081642d9 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb @@ -0,0 +1,51 @@ +test_name 'C3484 - checkout as a group that is not on system' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - delete group' do + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step "verify git checkout is NOT owned by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') if res.stdout.include? ":#{group}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb new file mode 100644 index 00000000..85f1fcc0 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb @@ -0,0 +1,46 @@ +test_name 'C3614 - checkout a revision that does not exist' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout revision that does not exist with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '11111111111111111', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify that master revision is checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb new file mode 100644 index 00000000..b17dc73d --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb @@ -0,0 +1,53 @@ +test_name 'C3452 - checkout a revision (file protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify repo is checked out to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb new file mode 100644 index 00000000..c80eb81b --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb @@ -0,0 +1,53 @@ +test_name 'C3451 - checkout a revision (file path)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify repo is checked out to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb new file mode 100644 index 00000000..69a7fe22 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb @@ -0,0 +1,58 @@ +test_name 'C3450 - checkout a revision (git protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb new file mode 100644 index 00000000..7cac163d --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb @@ -0,0 +1,66 @@ +test_name 'C3455 - checkout a revision (http protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb new file mode 100644 index 00000000..1c705a5e --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb @@ -0,0 +1,74 @@ +test_name 'C3456 - checkout a revision (https protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get revision sha from repo' do + on(host, "git clone https://github.com/johnduarte/testrepo.git #{tmpdir}/foo") + on(host, "git --git-dir=#{tmpdir}/foo/.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb new file mode 100644 index 00000000..b5dbd244 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb @@ -0,0 +1,64 @@ +test_name 'C3453 - checkout a revision (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb new file mode 100644 index 00000000..222653e4 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb @@ -0,0 +1,64 @@ +test_name 'C3454 - checkout a revision (ssh protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb new file mode 100644 index 00000000..f01a488e --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb @@ -0,0 +1,43 @@ +test_name 'C3608 - shallow clone repo depth hostile input' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (bad input ignored, full clone checkedout)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => "exec 'rm -rf /tmp'", + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') if res.stdout.include? "shallow" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb new file mode 100644 index 00000000..47fb338b --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb @@ -0,0 +1,44 @@ +test_name 'C3475 - shallow clone repo minimal depth = 1 (file path protocol)' +skip_test 'Not currently supported. See FM-1285' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'git does not support shallow clone via file path: verify checkout is NOT created' do + on(host, "ls #{tmpdir}") do |res| + fail_test('checkout found') if res.stdout.include? "#{repo_name}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb new file mode 100644 index 00000000..723a0b62 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb @@ -0,0 +1,55 @@ +test_name 'C3479 - shallow clone repo minimal depth = 1 (http protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'ps ax | grep "#{ruby} /tmp/http_daemon.rb" | grep -v grep | awk \'{print "kill -9 " $1}\' | sh ; sleep 1') + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'git does not support shallow clone via HTTP: verify checkout is NOT created' do + on(host, "ls #{tmpdir}") do |res| + fail_test('checkout found') if res.stdout.include? "#{repo_name}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb new file mode 100644 index 00000000..869620d2 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb @@ -0,0 +1,43 @@ +test_name 'C3607 - shallow clone repo depth = -1' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (bad input ignored, full clone checkedout)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => -1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') if res.stdout.include? "shallow" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb new file mode 100644 index 00000000..5da9fd7e --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb @@ -0,0 +1,45 @@ +test_name 'C3606 - shallow clone repo depth overflow 64bit integer' + +# Globals +repo_name = 'testrepo_shallow_clone' + +pending_test("The overflow can't be handled on some git versions") + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (bad input ignored, full clone checkedout)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => 18446744073709551616, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') if res.stdout.include? "shallow" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb new file mode 100644 index 00000000..9e2abe28 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb @@ -0,0 +1,47 @@ +test_name 'C3476 - shallow clone repo minimal depth = 1 (file protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb new file mode 100644 index 00000000..49683d24 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb @@ -0,0 +1,52 @@ +test_name 'C3474 - shallow clone repo minimal depth = 1 (git protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb new file mode 100644 index 00000000..23927287 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb @@ -0,0 +1,68 @@ +test_name 'C3480 - shallow clone repo minimal depth = 1 (https protocol)' +skip_test 'Not currently supported. See FM-1286' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'ps ax | grep "#{ruby} /tmp/https_daemon.rb" | grep -v grep | awk \'{print "kill -9 " $1}\' | sh ; sleep 1') + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb new file mode 100644 index 00000000..1d5b35a1 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb @@ -0,0 +1,58 @@ +test_name 'C3478 - shallow clone repo minimal depth = 1 (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'shallow clone repo with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb new file mode 100644 index 00000000..0f00b30e --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb @@ -0,0 +1,58 @@ +test_name 'C3477 - shallow clone repo minimal depth = 1 (ssh protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb new file mode 100644 index 00000000..34c624f7 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb @@ -0,0 +1,43 @@ +test_name 'C3404 - shallow clone repo depth = 0 non shallow' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (zero depth means not shallow)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => 0, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow found') if res.stdout.include? "shallow" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb new file mode 100644 index 00000000..1849f029 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb @@ -0,0 +1,47 @@ +test_name 'C3612 - checkout a tag that does not exist' + +# Globals +repo_name = 'testrepo_tag_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout tag that does not exist with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + tag => '11111111111111111', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify that master tag is checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb new file mode 100644 index 00000000..9c744855 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb @@ -0,0 +1,48 @@ +test_name 'C3445 - checkout a tag (file protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb new file mode 100644 index 00000000..01f319cb --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb @@ -0,0 +1,48 @@ +test_name 'C3444 - checkout a tag (file path)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb new file mode 100644 index 00000000..42e689c8 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb @@ -0,0 +1,59 @@ +test_name 'C3443 - checkout a tag (git protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb new file mode 100644 index 00000000..3ea363c4 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb @@ -0,0 +1,67 @@ +test_name 'C3448 - checkout a tag (http protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb new file mode 100644 index 00000000..d508c436 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb @@ -0,0 +1,74 @@ +test_name 'C3449 - checkout a tag (https protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb new file mode 100644 index 00000000..cb96b4e2 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb @@ -0,0 +1,65 @@ +test_name 'C3446 - checkout a tag (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb new file mode 100644 index 00000000..bc416e8e --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb @@ -0,0 +1,65 @@ +test_name 'C3447 - checkout a tag (ssh protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb new file mode 100644 index 00000000..245e1751 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb @@ -0,0 +1,51 @@ +test_name 'C3483 - checkout as a user that is not on system' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - delete user' do + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step "verify git checkout is NOT owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') if res.stdout.include? "#{user}:" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb new file mode 100644 index 00000000..ccd9ad44 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb @@ -0,0 +1,53 @@ +test_name 'C3459 - checkout as a user (file protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb new file mode 100644 index 00000000..602769de --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb @@ -0,0 +1,53 @@ +test_name 'C3458 - checkout as a user (file path)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb new file mode 100644 index 00000000..af2ffb71 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb @@ -0,0 +1,58 @@ +test_name 'C3457 - checkout as a user (git protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb new file mode 100644 index 00000000..e8713e5b --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb @@ -0,0 +1,66 @@ +test_name 'C3462 - checkout as a user (http protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb new file mode 100644 index 00000000..4e633d78 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb @@ -0,0 +1,73 @@ +test_name 'C3463 - checkout as a user (https protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb new file mode 100644 index 00000000..98efb462 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb @@ -0,0 +1,64 @@ +test_name 'C3460 - checkout as a user (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb new file mode 100644 index 00000000..cfd521ec --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb @@ -0,0 +1,64 @@ +test_name 'C3461 - checkout as a user (ssh protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/beaker_helper.rb b/puppet/modules/vcsrepo/spec/acceptance/beaker_helper.rb new file mode 100644 index 00000000..4d232047 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/beaker_helper.rb @@ -0,0 +1,51 @@ +test_name "Installing Puppet and vcsrepo module" do + step 'install puppet' do + if @options[:provision] + # This will fail if puppet is already installed, ie --no-provision + if hosts.first.is_pe? + install_pe + else + install_puppet + on hosts, "mkdir -p #{hosts.first['distmoduledir']}" + end + end + end + + step 'Ensure we can install our module' do + hosts.each do |host| + # We ask the host to interpolate it's distmoduledir because we don't + # actually know it on Windows until we've let it redirect us (depending + # on whether we're running as a 32/64 bit process on 32/64 bit Windows + moduledir = on(host, "echo #{host['distmoduledir']}").stdout.chomp + on host, "mkdir -p #{moduledir}" + end + end + + step 'install module' do + hosts.each do |host| + proj_root = File.expand_path(File.join(File.dirname(__FILE__),'..','..')) + + # This require beaker 1.15 + copy_module_to(host, :source => proj_root, :module_name => 'vcsrepo') + + case fact_on(host, 'osfamily') + when 'RedHat' + install_package(host, 'git') + when 'Debian' + install_package(host, 'git-core') + else + if !check_for_package(host, 'git') + puts "Git package is required for this module" + exit + end + end + + gitconfig = <<-EOS +[user] + email = root@localhost + name = root +EOS + create_remote_file(host, "/root/.gitconfig", gitconfig) + end + end +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/clone_repo_spec.rb b/puppet/modules/vcsrepo/spec/acceptance/clone_repo_spec.rb new file mode 100644 index 00000000..c2345502 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/clone_repo_spec.rb @@ -0,0 +1,534 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones a remote repo' do + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + scp_to(default, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + shell("cd #{tmpdir} && ./create_git_repo.sh") + end + + after(:all) do + shell("rm -rf #{tmpdir}/testrepo.git") + end + + context 'get the current master HEAD' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo/.git") do + it { is_expected.to be_directory } + end + + describe file("#{tmpdir}/testrepo/.git/HEAD") do + it { is_expected.to contain 'ref: refs/heads/master' } + end + end + + context 'using a https source on github' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/httpstestrepo": + ensure => present, + provider => git, + source => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/httpstestrepo/.git") do + it { is_expected.to be_directory } + end + + describe file("#{tmpdir}/httpstestrepo/.git/HEAD") do + it { is_expected.to contain 'ref: refs/heads/master' } + end + end + + context 'using a commit SHA' do + let (:sha) do + shell("git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1").stdout.chomp + end + + after(:all) do + shell("rm -rf #{tmpdir}/testrepo_sha") + end + + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_sha": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => "#{sha}", + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_sha/.git") do + it { is_expected.to be_directory } + end + + describe file("#{tmpdir}/testrepo_sha/.git/HEAD") do + it { is_expected.to contain sha } + end + end + + context 'using a tag' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_tag": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => '0.0.2', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_tag/.git") do + it { is_expected.to be_directory } + end + + it 'should have the tag as the HEAD' do + shell("git --git-dir=#{tmpdir}/testrepo_tag/.git name-rev HEAD | grep '0.0.2'") + end + end + + context 'using a branch name' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_branch": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => 'a_branch', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_branch/.git") do + it { is_expected.to be_directory } + end + + describe file("#{tmpdir}/testrepo_branch/.git/HEAD") do + it { is_expected.to contain 'ref: refs/heads/a_branch' } + end + end + + context 'ensure latest with branch specified' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_latest": + ensure => latest, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => 'a_branch', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'verifies the HEAD commit SHA on remote and local match' do + remote_commit = shell("git ls-remote file://#{tmpdir}/testrepo_latest HEAD | head -1").stdout + local_commit = shell("git --git-dir=#{tmpdir}/testrepo_latest/.git rev-parse HEAD").stdout.chomp + expect(remote_commit).to include(local_commit) + end + end + + context 'ensure latest with branch unspecified' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_latest": + ensure => latest, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'verifies the HEAD commit SHA on remote and local match' do + remote_commit = shell("git ls-remote file://#{tmpdir}/testrepo_latest HEAD | head -1").stdout + local_commit = shell("git --git-dir=#{tmpdir}/testrepo_latest/.git rev-parse HEAD").stdout.chomp + expect(remote_commit).to include(local_commit) + end + end + + context 'with shallow clone' do + it 'does a shallow clone' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_shallow": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + depth => '1', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_shallow/.git/shallow") do + it { is_expected.to be_file } + end + end + + context 'path is not empty and not a repository' do + before(:all) do + shell("mkdir #{tmpdir}/not_a_repo", :acceptable_exit_codes => [0,1]) + shell("touch #{tmpdir}/not_a_repo/file1.txt", :acceptable_exit_codes => [0,1]) + end + + it 'should raise an exception' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/not_a_repo": + ensure => present, + provider => git + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_failures => true) + end + end + + context 'with an owner' do + pp = <<-EOS + user { 'vagrant': + ensure => present, + } + EOS + + apply_manifest(pp, :catch_failures => true) + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_owner": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + owner => 'vagrant', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_owner") do + it { is_expected.to be_directory } + it { is_expected.to be_owned_by 'vagrant' } + end + end + + context 'with a group' do + pp = <<-EOS + group { 'vagrant': + ensure => present, + } + EOS + + apply_manifest(pp, :catch_failures => true) + + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "/#{tmpdir}/testrepo_group": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + group => 'vagrant', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_group") do + it { is_expected.to be_directory } + it { is_expected.to be_grouped_into 'vagrant' } + end + end + + context 'with excludes' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_excludes": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + excludes => ['exclude1.txt', 'exclude2.txt'], + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_excludes/.git/info/exclude") do + describe '#content' do + subject { super().content } + it { is_expected.to match /exclude1.txt/ } + end + + describe '#content' do + subject { super().content } + it { is_expected.to match /exclude2.txt/ } + end + end + end + + context 'with force' do + before(:all) do + shell("mkdir -p #{tmpdir}/testrepo_force/folder") + shell("touch #{tmpdir}/testrepo_force/temp.txt") + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_force": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + force => true, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_force/folder") do + it { is_expected.not_to be_directory } + end + + describe file("#{tmpdir}/testrepo_force/temp.txt") do + it { is_expected.not_to be_file } + end + + describe file("#{tmpdir}/testrepo_force/.git") do + it { is_expected.to be_directory } + end + + context 'and noop' do + before(:all) do + shell("mkdir #{tmpdir}/testrepo_already_exists") + shell("cd #{tmpdir}/testrepo_already_exists && git init") + shell("cd #{tmpdir}/testrepo_already_exists && touch a && git add a && git commit -m 'a'") + end + after(:all) do + shell("rm -rf #{tmpdir}/testrepo_already_exists") + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_already_exists": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + force => true, + noop => true, + } + EOS + + apply_manifest(pp, :catch_changes => true) + end + end + end + + context 'as a user' do + before(:all) do + shell("chmod 707 #{tmpdir}") + pp = <<-EOS + group { 'testuser': + ensure => present, + } + user { 'testuser': + ensure => present, + groups => 'testuser', + } + EOS + + apply_manifest(pp, :catch_failures => true) + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_user": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + user => 'testuser', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_user") do + it { is_expected.to be_directory } + it { is_expected.to be_owned_by 'testuser' } + end + + describe file("#{tmpdir}/testrepo_user") do + it { is_expected.to be_directory } + it { is_expected.to be_grouped_into 'testuser' } + end + end + + context 'non-origin remote name' do + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_remote": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + remote => 'testorigin', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'remote name is "testorigin"' do + shell("git --git-dir=#{tmpdir}/testrepo_remote/.git remote | grep 'testorigin'") + end + + after(:all) do + pp = 'user { "testuser": ensure => absent }' + apply_manifest(pp, :catch_failures => true) + end + end + + context 'as a user with ssh' do + before(:all) do + # create user + pp = <<-EOS + group { 'testuser-ssh': + ensure => present, + } + user { 'testuser-ssh': + ensure => present, + groups => 'testuser-ssh', + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + + # create ssh keys + shell('mkdir -p /home/testuser-ssh/.ssh') + shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys') + shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config') + shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh') + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_user_ssh": + ensure => present, + provider => git, + source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git", + user => 'testuser-ssh', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + after(:all) do + pp = <<-EOS + user { 'testuser-ssh': + ensure => absent, + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + end + + context 'using an identity file' do + before(:all) do + # create user + pp = <<-EOS + user { 'testuser-ssh': + ensure => present, + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + + # create ssh keys + shell('mkdir -p /home/testuser-ssh/.ssh') + shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys') + shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config') + shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh') + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_user_ssh_id": + ensure => present, + provider => git, + source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git", + identity => '/home/testuser-ssh/.ssh/id_rsa', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + end +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/create_repo_spec.rb b/puppet/modules/vcsrepo/spec/acceptance/create_repo_spec.rb new file mode 100644 index 00000000..53a93c97 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/create_repo_spec.rb @@ -0,0 +1,89 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'create a repo' do + context 'without a source' do + it 'creates a blank repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_blank_repo": + ensure => present, + provider => git, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_blank_repo/") do + it 'should have zero files' do + shell("ls -1 #{tmpdir}/testrepo_blank_repo | wc -l") do |r| + expect(r.stdout).to match(/^0\n$/) + end + end + end + + describe file("#{tmpdir}/testrepo_blank_repo/.git") do + it { is_expected.to be_directory } + end + end + + context 'no source but revision provided' do + it 'should not fail (MODULES-2125)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_blank_with_revision_repo": + ensure => present, + provider => git, + revision => 'master' + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + end + + context 'bare repo' do + it 'creates a bare repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_bare_repo": + ensure => bare, + provider => git, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_bare_repo/config") do + it { is_expected.to contain 'bare = true' } + end + + describe file("#{tmpdir}/testrepo_bare_repo/.git") do + it { is_expected.not_to be_directory } + end + end + + context 'bare repo with a revision' do + it 'does not create a bare repo when a revision is defined' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_bare_repo_rev": + ensure => bare, + provider => git, + revision => 'master', + } + EOS + + apply_manifest(pp, :expect_failures => true) + end + + describe file("#{tmpdir}/testrepo_bare_repo_rev") do + it { is_expected.not_to be_directory } + end + end +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/files/create_git_repo.sh b/puppet/modules/vcsrepo/spec/acceptance/files/create_git_repo.sh new file mode 100755 index 00000000..b5e930ca --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/files/create_git_repo.sh @@ -0,0 +1,39 @@ +#!/bin/bash +mkdir testrepo +cd testrepo + +touch file1.txt file2.txt file3.txt +git init +echo 'change 1' > file1.txt +git add file1.txt +git commit -m 'add file1' +git tag 0.0.1 +echo 'change 2' > file2.txt +git add file2.txt +git commit -m 'add file2' +git tag 0.0.2 +echo 'change 3' > file3.txt +git add file3.txt +git commit -m 'add file3' +git tag 0.0.3 + +git checkout -b a_branch +echo 'change 4' > file4.txt +git add file4.txt +git commit -m 'add file4' +echo 'change 5' > file5.txt +git add file5.txt +git commit -m 'add file5' +echo 'change 6' > file6.txt +git add file6.txt +git commit -m 'add file6' + +git checkout master +cd .. + +git --git-dir=testrepo/.git config core.bare true +cp -r testrepo/.git testrepo.git +rm -rf testrepo +cd testrepo.git +touch git-daemon-export-ok +git update-server-info diff --git a/puppet/modules/vcsrepo/spec/acceptance/files/server.crt b/puppet/modules/vcsrepo/spec/acceptance/files/server.crt new file mode 100644 index 00000000..270f65c0 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/files/server.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICATCCAWoCCQDRobnOvvkStDANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB +VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMB4XDTE1MDQwODE3MjM1NVoXDTI1MDQwNTE3MjM1NVowRTELMAkG +A1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0 +IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyRTv +uX6328aQ5Auc8PI+xNaCiE0UZNYcs+xq3AEkR/Tnz0HGXdx3+PnFG7MIRSS65hXA +VGenZk3wP4vNIe9gu+G9jtOFTJOgoOBUnJ/Hcs79Zgcmz3cAWQpqww+CZpyngUDS +msZ5HoEbNS+qaIron3IrYCgPsy1BHFs5ze7JrtcCAwEAATANBgkqhkiG9w0BAQUF +AAOBgQCaYVv8WbFbrnLMOcyjE7GjSmVh68fEN+AqntZa1Z5GOv6OQIN9mVSoNxWo +lb/9xmldfMQThgKckHHvB5Q9kf923nMQZOi8yxyaoeYWrkglkFFU/sdF6yuFBdUU +D+rXmHnS754FLTGDzESmlRVUCYuwVgrRdm+P+wu2+lZT3x85VA== +-----END CERTIFICATE----- diff --git a/puppet/modules/vcsrepo/spec/acceptance/files/server.key b/puppet/modules/vcsrepo/spec/acceptance/files/server.key new file mode 100644 index 00000000..b594f13e --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/files/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDJFO+5frfbxpDkC5zw8j7E1oKITRRk1hyz7GrcASRH9OfPQcZd +3Hf4+cUbswhFJLrmFcBUZ6dmTfA/i80h72C74b2O04VMk6Cg4FScn8dyzv1mBybP +dwBZCmrDD4JmnKeBQNKaxnkegRs1L6poiuifcitgKA+zLUEcWznN7smu1wIDAQAB +AoGAQPnD8OOyk5DZVuctwmn0wHQ0X8jQczkAs18MtKSlzZ6knUM6zy+jkM9c0vOK +E5Wn0xtqN5v66sL6g/4vvex1DA5Q6YsXvZ48VpVliZXXK/1pdTv0qwMyHdlBhmgJ +MhnZbyNy61QHdOTsWDR1YrELpDyFMJ9cZZD0NOnsuhd2DbECQQDq7W/zlJBZPWNR +ab2dP+HLpm/PiEBT13SuEEskh3GEEfZlwz/cGu0Z8DHA4E3Z60KFjwgnc92GNFMg +m0t3hHtpAkEA2x5PsDxBk9sWwdIvu57vjQLdotvAfyb+W9puIaZS1JRSVLTsUVEj +Y0KxgsPHtcjrVoN//zGymn4ePxWOzlrQPwJBAN5thEuZY7o6dyiD9zVFYKGSqdZS +aKV5H04Wuy6Q1pd28lWTMYlSLR8b3d+B//PN3SPbMps4BoukSvhaUG+OjdECQFzF +KZIBAPa7pJftCH6UHPIDy5ifF5H+DWUQRt6CT8FnBrCMZR1MkAH/g65Me6pwZYsc +Y73E6cxVJzMoSmz9r/sCQQCOhPflFCxZ23ocsuRBo9O/mMUDaLoHZXWuJ2DqAUN2 +mS6UUR/lpyc7Cmy0VOyhS8783D7MUfji5ddfVxb5tWgm +-----END RSA PRIVATE KEY----- diff --git a/puppet/modules/vcsrepo/spec/acceptance/modules_1596_spec.rb b/puppet/modules/vcsrepo/spec/acceptance/modules_1596_spec.rb new file mode 100644 index 00000000..fa36285a --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/modules_1596_spec.rb @@ -0,0 +1,72 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones a remote repo' do + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + context 'force with a remote' do + it 'clones from remote' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => 'https://github.com/puppetlabs/puppetlabs-vcsrepo', + force => true, + } + EOS + + # Run it twice to test for idempotency + apply_manifest(pp, :catch_failures => true) + # need to create a file to make sure we aren't destroying the repo + # because fun fact, if you call destroy/create in 'retrieve' puppet won't + # register that any changes happen, because that method isn't supposed to + # be making any changes. + shell("touch #{tmpdir}/vcsrepo/foo") + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/vcsrepo/foo") do + it { is_expected.to be_file } + end + end + + context 'force over an existing repo' do + it 'clones from remote' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => 'https://github.com/puppetlabs/puppetlabs-vcsrepo', + force => true, + } + EOS + + pp2 = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => 'https://github.com/puppetlabs/puppetlabs-stdlib', + force => true, + } + EOS + + + apply_manifest(pp, :catch_failures => true) + # create a file to make sure we're destroying the repo + shell("touch #{tmpdir}/vcsrepo/foo") + apply_manifest(pp2, :catch_failures => true) + end + + describe file("#{tmpdir}/vcsrepo/foo") do + it { is_expected.to_not be_file } + end + end +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/modules_1800_spec.rb b/puppet/modules/vcsrepo/spec/acceptance/modules_1800_spec.rb new file mode 100644 index 00000000..12415e80 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/modules_1800_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones a remote repo' do + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + context 'ensure latest with no revision' do + it 'clones from default remote' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", + } + EOS + + apply_manifest(pp, :catch_failures => true) + shell("cd #{tmpdir}/vcsrepo; /usr/bin/git reset --hard HEAD~2") + end + + it 'updates' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => latest, + provider => git, + source => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", + } + EOS + + apply_manifest(pp, :catch_failures => true) + end + end +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/modules_2326_spec.rb b/puppet/modules/vcsrepo/spec/acceptance/modules_2326_spec.rb new file mode 100644 index 00000000..601c6ff6 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/modules_2326_spec.rb @@ -0,0 +1,69 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones with special characters' do + + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + scp_to(default, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + shell("cd #{tmpdir} && ./create_git_repo.sh") + end + + after(:all) do + shell("rm -rf #{tmpdir}/testrepo.git") + end + + context 'as a user with ssh' do + before(:all) do + # create user + pp = <<-EOS + group { 'testuser-ssh': + ensure => present, + } + user { 'testuser-ssh': + ensure => present, + groups => 'testuser-ssh', + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + + # create ssh keys + shell('mkdir -p /home/testuser-ssh/.ssh') + shell('echo -e \'y\n\'|ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys') + shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config') + shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh') + shell("chown testuser-ssh:testuser-ssh #{tmpdir}") + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_user_ssh": + ensure => present, + provider => git, + source => "git+ssh://testuser-ssh@localhost#{tmpdir}/testrepo.git", + user => 'testuser-ssh', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + after(:all) do + pp = <<-EOS + user { 'testuser-ssh': + ensure => absent, + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + end +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/modules_660_spec.rb b/puppet/modules/vcsrepo/spec/acceptance/modules_660_spec.rb new file mode 100644 index 00000000..c45aa28b --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/modules_660_spec.rb @@ -0,0 +1,89 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'MODULES-660' do + before(:all) do + # Create testrepo.git + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + scp_to(default, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + shell("cd #{tmpdir} && ./create_git_repo.sh") + + # Configure testrepo.git as upstream of testrepo + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => present, + provider => git, + revision => 'a_branch', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + after(:all) do + shell("rm -rf #{tmpdir}/testrepo.git") + end + + shared_examples 'switch to branch/tag/sha' do + it 'pulls the new branch commits' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => latest, + provider => git, + revision => 'a_branch', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_changes => true) + apply_manifest(pp, :catch_changes => true) + end + it 'checks out the tag' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => latest, + provider => git, + revision => '0.0.3', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_changes => true) + apply_manifest(pp, :catch_changes => true) + end + it 'checks out the sha' do + sha = shell("cd #{tmpdir}/testrepo && git rev-parse origin/master").stdout.chomp + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => latest, + provider => git, + revision => '#{sha}', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_changes => true) + apply_manifest(pp, :catch_changes => true) + end + end + + context 'on branch' do + before :each do + shell("cd #{tmpdir}/testrepo && git checkout a_branch") + shell("cd #{tmpdir}/testrepo && git reset --hard 0.0.2") + end + it_behaves_like 'switch to branch/tag/sha' + end + context 'on tag' do + before :each do + shell("cd #{tmpdir}/testrepo && git checkout 0.0.1") + end + it_behaves_like 'switch to branch/tag/sha' + end + context 'on detached head' do + before :each do + shell("cd #{tmpdir}/testrepo && git checkout 0.0.2") + shell("cd #{tmpdir}/testrepo && git checkout HEAD~1") + end + it_behaves_like 'switch to branch/tag/sha' + end +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/modules_753_spec.rb b/puppet/modules/vcsrepo/spec/acceptance/modules_753_spec.rb new file mode 100644 index 00000000..e4e332bf --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/modules_753_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones a remote repo' do + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + context 'clone with single remote' do + it 'clones from default remote' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", + } + EOS + + apply_manifest(pp, :catch_failures => true) + + end + + it "git config output should contain the remote" do + shell("/usr/bin/git config -l -f #{tmpdir}/vcsrepo/.git/config") do |r| + expect(r.stdout).to match(/remote.origin.url=https:\/\/github.com\/puppetlabs\/puppetlabs-vcsrepo.git/) + end + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + end + + context 'clone with multiple remotes' do + it 'clones from default remote and adds 2 remotes to config file' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => {"origin" => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", "test1" => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git"}, + } + EOS + + apply_manifest(pp, :catch_failures => true) + + end + + it "git config output should contain the remotes" do + shell("/usr/bin/git config -l -f #{tmpdir}/vcsrepo/.git/config") do |r| + expect(r.stdout).to match(/remote.origin.url=https:\/\/github.com\/puppetlabs\/puppetlabs-vcsrepo.git/) + expect(r.stdout).to match(/remote.test1.url=https:\/\/github.com\/puppetlabs\/puppetlabs-vcsrepo.git/) + end + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + end + +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-59-x64.yml b/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-59-x64.yml new file mode 100644 index 00000000..2ad90b86 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-59-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-59-x64: + roles: + - master + platform: el-5-x86_64 + box : centos-59-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-59-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: git diff --git a/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-64-x64-pe.yml b/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-64-x64-pe.yml new file mode 100644 index 00000000..7d9242f1 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-64-x64-pe.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-64-x64: + roles: + - master + - database + - dashboard + platform: el-6-x86_64 + box : centos-64-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: pe diff --git a/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-64-x64.yml b/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-64-x64.yml new file mode 100644 index 00000000..05540ed8 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-64-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-64-x64: + roles: + - master + platform: el-6-x86_64 + box : centos-64-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-65-x64.yml b/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-65-x64.yml new file mode 100644 index 00000000..4e2cb809 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/nodesets/centos-65-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-65-x64: + roles: + - master + platform: el-6-x86_64 + box : centos-65-x64-vbox436-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/puppet/modules/vcsrepo/spec/acceptance/nodesets/debian-607-x64.yml b/puppet/modules/vcsrepo/spec/acceptance/nodesets/debian-607-x64.yml new file mode 100644 index 00000000..43df6a57 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/nodesets/debian-607-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + debian-607-x64: + roles: + - master + platform: debian-6-amd64 + box : debian-607-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-607-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/puppet/modules/vcsrepo/spec/acceptance/nodesets/debian-73-x64.yml b/puppet/modules/vcsrepo/spec/acceptance/nodesets/debian-73-x64.yml new file mode 100644 index 00000000..5b87870a --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/nodesets/debian-73-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + debian-73-x64: + roles: + - master + platform: debian-7-amd64 + box : debian-73-x64-virtualbox-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-73-x64-virtualbox-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/puppet/modules/vcsrepo/spec/acceptance/nodesets/default.yml b/puppet/modules/vcsrepo/spec/acceptance/nodesets/default.yml new file mode 100644 index 00000000..05540ed8 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/nodesets/default.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-64-x64: + roles: + - master + platform: el-6-x86_64 + box : centos-64-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml b/puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml new file mode 100644 index 00000000..5ca1514e --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + ubuntu-server-10044-x64: + roles: + - master + platform: ubuntu-10.04-amd64 + box : ubuntu-server-10044-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-10044-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml b/puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml new file mode 100644 index 00000000..d065b304 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + ubuntu-server-12042-x64: + roles: + - master + platform: ubuntu-12.04-amd64 + box : ubuntu-server-12042-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml new file mode 100644 index 00000000..cba1cd04 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml @@ -0,0 +1,11 @@ +HOSTS: + ubuntu-server-1404-x64: + roles: + - master + platform: ubuntu-14.04-amd64 + box : puppetlabs/ubuntu-14.04-64-nocm + box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm + hypervisor : vagrant +CONFIG: + log_level : debug + type: git diff --git a/puppet/modules/vcsrepo/spec/acceptance/remove_repo_spec.rb b/puppet/modules/vcsrepo/spec/acceptance/remove_repo_spec.rb new file mode 100644 index 00000000..d5646b34 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/remove_repo_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'remove a repo' do + it 'creates a blank repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_deleted": + ensure => present, + provider => git, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + it 'removes a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_deleted": + ensure => absent, + provider => git, + } + EOS + + apply_manifest(pp, :catch_failures => true) + end + + describe file("#{tmpdir}/testrepo_deleted") do + it { is_expected.not_to be_directory } + end +end diff --git a/puppet/modules/vcsrepo/spec/acceptance/remove_repo_spec_noop.rb b/puppet/modules/vcsrepo/spec/acceptance/remove_repo_spec_noop.rb new file mode 100644 index 00000000..f6bd86e9 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/acceptance/remove_repo_spec_noop.rb @@ -0,0 +1,31 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'does not remove a repo if noop' do + it 'creates a blank repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_noop_deleted": + ensure => present, + provider => git, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + it 'does not remove a repo if noop' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_noop_deleted": + ensure => absent, + provider => git, + force => true, + } + EOS + + apply_manifest(pp, :catch_failures => true, :noop => true, :verbose => false) + end + + describe file("#{tmpdir}/testrepo_noop_deleted") do + it { is_expected.to be_directory } + end +end diff --git a/puppet/modules/vcsrepo/spec/fixtures/bzr_version_info.txt b/puppet/modules/vcsrepo/spec/fixtures/bzr_version_info.txt new file mode 100644 index 00000000..88a56a1c --- /dev/null +++ b/puppet/modules/vcsrepo/spec/fixtures/bzr_version_info.txt @@ -0,0 +1,5 @@ +revision-id: menesis@pov.lt-20100309191856-4wmfqzc803fj300x +date: 2010-03-09 21:18:56 +0200 +build-date: 2010-03-14 00:42:43 -0800 +revno: 2634 +branch-nick: mytest diff --git a/puppet/modules/vcsrepo/spec/fixtures/git_branch_a.txt b/puppet/modules/vcsrepo/spec/fixtures/git_branch_a.txt new file mode 100644 index 00000000..2c99829d --- /dev/null +++ b/puppet/modules/vcsrepo/spec/fixtures/git_branch_a.txt @@ -0,0 +1,14 @@ + feature/foo + feature/bar + feature/baz + feature/quux + only/local +* master + refactor/foo + origin/HEAD + origin/feature/foo + origin/feature/bar + origin/feature/baz + origin/feature/quux + origin/only/remote + origin/master diff --git a/puppet/modules/vcsrepo/spec/fixtures/git_branch_feature_bar.txt b/puppet/modules/vcsrepo/spec/fixtures/git_branch_feature_bar.txt new file mode 100644 index 00000000..72d5e200 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/fixtures/git_branch_feature_bar.txt @@ -0,0 +1,14 @@ + feature/foo +* feature/bar + feature/baz + feature/quux + only/local + master + refactor/foo + origin/HEAD + origin/feature/foo + origin/feature/bar + origin/feature/baz + origin/feature/quux + origin/only/remote + origin/master diff --git a/puppet/modules/vcsrepo/spec/fixtures/git_branch_none.txt b/puppet/modules/vcsrepo/spec/fixtures/git_branch_none.txt new file mode 100644 index 00000000..7207c379 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/fixtures/git_branch_none.txt @@ -0,0 +1,15 @@ + feature/foo + feature/bar + feature/baz + feature/quux + only/local + master +* (no branch) + refactor/foo + origin/HEAD + origin/feature/foo + origin/feature/bar + origin/feature/baz + origin/feature/quux + origin/only/remote + origin/master diff --git a/puppet/modules/vcsrepo/spec/fixtures/hg_parents.txt b/puppet/modules/vcsrepo/spec/fixtures/hg_parents.txt new file mode 100644 index 00000000..46173df4 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/fixtures/hg_parents.txt @@ -0,0 +1,6 @@ +changeset: 3:34e6012c783a +parent: 2:21ea4598c962 +parent: 1:9d0ff0028458 +user: Test User +date: Fri Aug 07 13:13:02 2009 -0400 +summary: merge diff --git a/puppet/modules/vcsrepo/spec/fixtures/hg_tags.txt b/puppet/modules/vcsrepo/spec/fixtures/hg_tags.txt new file mode 100644 index 00000000..53792e5a --- /dev/null +++ b/puppet/modules/vcsrepo/spec/fixtures/hg_tags.txt @@ -0,0 +1,18 @@ +tip 1019:bca3f20b249b +0.9.1 1017:76ce7cca95d8 +0.9 1001:dbaa6f4ec585 +0.8 839:65b66ac0fc83 +0.7.1 702:e1357f00129f +0.7 561:7b2af3b4c968 +0.6.3 486:e38077f4e4aa +0.6.2 405:07bb099b7b10 +0.6.1 389:93750f3fbbe2 +0.6 369:34e6012c783a +0.5.3 321:5ffa6ae7e699 +0.5.2 318:fdc2c2e4cebe +0.5.1 315:33a5ea0cbe7a +0.5 313:47490716f4c9 +0.4 240:47fa3a14cc63 +0.3.1 132:bc231db18e1c +0.3 130:661615e510dd +0.2 81:f98d13b442f6 diff --git a/puppet/modules/vcsrepo/spec/fixtures/svn_info.txt b/puppet/modules/vcsrepo/spec/fixtures/svn_info.txt new file mode 100644 index 00000000..d2a975b2 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/fixtures/svn_info.txt @@ -0,0 +1,10 @@ +Path: . +URL: http://example.com/svn/trunk +Repository Root: http://example.com/svn +Repository UUID: 75246ace-e253-0410-96dd-a7613ca8dc81 +Revision: 4 +Node Kind: directory +Schedule: normal +Last Changed Author: jon +Last Changed Rev: 3 +Last Changed Date: 2008-08-07 11:34:25 -0700 (Thu, 07 Aug 2008) diff --git a/puppet/modules/vcsrepo/spec/spec.opts b/puppet/modules/vcsrepo/spec/spec.opts new file mode 100644 index 00000000..91cd6427 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/spec.opts @@ -0,0 +1,6 @@ +--format +s +--colour +--loadby +mtime +--backtrace diff --git a/puppet/modules/vcsrepo/spec/spec_helper.rb b/puppet/modules/vcsrepo/spec/spec_helper.rb new file mode 100644 index 00000000..22d5d689 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/spec_helper.rb @@ -0,0 +1,8 @@ +#This file is generated by ModuleSync, do not edit. +require 'puppetlabs_spec_helper/module_spec_helper' + +# put local configuration and setup into spec_helper_local +begin + require 'spec_helper_local' +rescue LoadError +end diff --git a/puppet/modules/vcsrepo/spec/spec_helper_acceptance.rb b/puppet/modules/vcsrepo/spec/spec_helper_acceptance.rb new file mode 100644 index 00000000..97c43e8c --- /dev/null +++ b/puppet/modules/vcsrepo/spec/spec_helper_acceptance.rb @@ -0,0 +1,46 @@ +require 'beaker-rspec' +require 'beaker/puppet_install_helper' + +run_puppet_install_helper + +RSpec.configure do |c| + # Project root + proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + # Readable test descriptions + c.formatter = :documentation + + # Configure all nodes in nodeset + c.before :suite do + + # ensure test dependencies are available on all hosts + hosts.each do |host| + copy_module_to(host, :source => proj_root, :module_name => 'vcsrepo') + case fact_on(host, 'osfamily') + when 'RedHat' + if fact_on(host, 'operatingsystemmajrelease') == '5' + will_install_git = on(host, 'which git', :acceptable_exit_codes => [0,1]).exit_code == 1 + + if will_install_git + on host, puppet('module install stahnma-epel') + apply_manifest_on( host, 'include epel' ) + end + + end + + install_package(host, 'git') + + when 'Debian' + install_package(host, 'git-core') + + else + if !check_for_package(host, 'git') + puts "Git package is required for this module" + exit + end + end + on host, 'git config --global user.email "root@localhost"' + on host, 'git config --global user.name "root"' + end + end +end diff --git a/puppet/modules/vcsrepo/spec/spec_helper_local.rb b/puppet/modules/vcsrepo/spec/spec_helper_local.rb new file mode 100644 index 00000000..c7d27b52 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/spec_helper_local.rb @@ -0,0 +1,7 @@ +require 'support/filesystem_helpers' +require 'support/fixture_helpers' + +RSpec.configure do |c| + c.include FilesystemHelpers + c.include FixtureHelpers +end diff --git a/puppet/modules/vcsrepo/spec/support/filesystem_helpers.rb b/puppet/modules/vcsrepo/spec/support/filesystem_helpers.rb new file mode 100644 index 00000000..15e2ca75 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/support/filesystem_helpers.rb @@ -0,0 +1,18 @@ +module FilesystemHelpers + + def expects_chdir(path = resource.value(:path)) + Dir.expects(:chdir).with(path).at_least_once.yields + end + + def expects_mkdir(path = resource.value(:path)) + Dir.expects(:mkdir).with(path).at_least_once + end + + def expects_rm_rf(path = resource.value(:path)) + FileUtils.expects(:rm_rf).with(path) + end + + def expects_directory?(returns = true, path = resource.value(:path)) + File.expects(:directory?).with(path).returns(returns) + end +end diff --git a/puppet/modules/vcsrepo/spec/support/fixture_helpers.rb b/puppet/modules/vcsrepo/spec/support/fixture_helpers.rb new file mode 100644 index 00000000..8a0e0a0b --- /dev/null +++ b/puppet/modules/vcsrepo/spec/support/fixture_helpers.rb @@ -0,0 +1,7 @@ +module FixtureHelpers + + def fixture(name, ext = '.txt') + File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', name.to_s + ext)) + end + +end diff --git a/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb new file mode 100644 index 00000000..b5e2f731 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb @@ -0,0 +1,109 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:bzr_provider) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :bzr, + :revision => '2634', + :source => 'lp:do', + :path => '/tmp/test', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('bzr').returns('/usr/bin/bzr') + end + + describe 'creating' do + context 'with defaults' do + it "should execute 'bzr clone -r' with the revision" do + provider.expects(:bzr).with('branch', '-r', resource.value(:revision), resource.value(:source), resource.value(:path)) + provider.create + end + end + + context 'without revision' do + it "should just execute 'bzr clone' without a revision" do + resource.delete(:revision) + provider.expects(:bzr).with('branch', resource.value(:source), resource.value(:path)) + provider.create + end + end + + context 'without source' do + it "should execute 'bzr init'" do + resource.delete(:source) + provider.expects(:bzr).with('init', resource.value(:path)) + provider.create + end + end + end + + describe 'destroying' do + it "it should remove the directory" do + provider.destroy + end + end + + describe "checking existence" do + it "should check for the directory" do + File.expects(:directory?).with(File.join(resource.value(:path), '.bzr')).returns(true) + provider.exists? + end + end + + describe "checking the revision property" do + before do + expects_chdir + provider.expects(:bzr).with('version-info').returns(File.read(fixtures('bzr_version_info.txt'))) + @current_revid = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x' + end + + context "when given a non-revid as the resource revision" do + context "when its revid is not different than the current revid" do + it "should return the ref" do + resource[:revision] = '2634' + provider.expects(:bzr).with('revision-info', '2634').returns("2634 menesis@pov.lt-20100309191856-4wmfqzc803fj300x\n") + expect(provider.revision).to eq(resource.value(:revision)) + end + end + context "when its revid is different than the current revid" do + it "should return the current revid" do + resource[:revision] = '2636' + provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("2635 foo\n") + expect(provider.revision).to eq(@current_revid) + end + end + end + + context "when given a revid as the resource revision" do + context "when it is the same as the current revid" do + it "should return it" do + resource[:revision] = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x' + provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("1234 #{resource.value(:revision)}\n") + expect(provider.revision).to eq(resource.value(:revision)) + end + end + context "when it is not the same as the current revid" do + it "should return the current revid" do + resource[:revision] = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300y' + provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("2636 foo\n") + expect(provider.revision).to eq(@current_revid) + end + end + + end + end + + describe "setting the revision property" do + it "should use 'bzr update -r' with the revision" do + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:bzr).with('update', '-r', 'somerev') + provider.revision = 'somerev' + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb new file mode 100644 index 00000000..2e18149a --- /dev/null +++ b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb @@ -0,0 +1,124 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:cvs_provider) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :cvs, + :revision => '2634', + :source => 'lp:do', + :path => '/tmp/test', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('cvs').returns('/usr/bin/cvs') + end + + describe 'creating' do + context "with a source" do + it "should execute 'cvs checkout'" do + resource[:source] = ':ext:source@example.com:/foo/bar' + resource[:revision] = 'an-unimportant-value' + expects_chdir('/tmp') + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), 'checkout', '-r', 'an-unimportant-value', '-d', 'test', 'bar'], :custom_environment => {}) + provider.create + end + + it "should execute 'cvs checkout' as user 'muppet'" do + resource[:source] = ':ext:source@example.com:/foo/bar' + resource[:revision] = 'an-unimportant-value' + resource[:user] = 'muppet' + expects_chdir('/tmp') + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), 'checkout', '-r', 'an-unimportant-value', '-d', 'test', 'bar'], :uid => 'muppet', :custom_environment => {}) + provider.create + end + + it "should just execute 'cvs checkout' without a revision" do + resource[:source] = ':ext:source@example.com:/foo/bar' + resource.delete(:revision) + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), 'checkout', '-d', File.basename(resource.value(:path)), File.basename(resource.value(:source))], :custom_environment => {}) + provider.create + end + + context "with a compression" do + it "should just execute 'cvs checkout' without a revision" do + resource[:source] = ':ext:source@example.com:/foo/bar' + resource[:compression] = '3' + resource.delete(:revision) + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), '-z', '3', 'checkout', '-d', File.basename(resource.value(:path)), File.basename(resource.value(:source))], :custom_environment => {}) + provider.create + end + end + end + + context "when a source is not given" do + it "should execute 'cvs init'" do + resource.delete(:source) + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:path), 'init'], :custom_environment => {}) + provider.create + end + end + end + + describe 'destroying' do + it "it should remove the directory" do + provider.destroy + end + end + + describe "checking existence" do + it "should check for the CVS directory with source" do + resource[:source] = ':ext:source@example.com:/foo/bar' + File.expects(:directory?).with(File.join(resource.value(:path), 'CVS')) + provider.exists? + end + + it "should check for the CVSROOT directory without source" do + resource.delete(:source) + File.expects(:directory?).with(File.join(resource.value(:path), 'CVSROOT')) + provider.exists? + end + end + + describe "checking the revision property" do + before do + @tag_file = File.join(resource.value(:path), 'CVS', 'Tag') + end + + context "when CVS/Tag exists" do + before do + @tag = 'TAG' + File.expects(:exist?).with(@tag_file).returns(true) + end + it "should read CVS/Tag" do + File.expects(:read).with(@tag_file).returns("T#{@tag}") + expect(provider.revision).to eq(@tag) + end + end + + context "when CVS/Tag does not exist" do + before do + File.expects(:exist?).with(@tag_file).returns(false) + end + it "assumes HEAD" do + expect(provider.revision).to eq('HEAD') + end + end + end + + describe "when setting the revision property" do + before do + @tag = 'SOMETAG' + end + + it "should use 'cvs update -dr'" do + expects_chdir + Puppet::Util::Execution.expects(:execute).with([:cvs, 'update', '-dr', @tag, '.'], :custom_environment => {}) + provider.revision = @tag + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb new file mode 100644 index 00000000..6a8f58f8 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb @@ -0,0 +1,401 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:git_provider) do + def branch_a_list(include_branch = nil?) + < 'test', + :ensure => :present, + :provider => :git, + :revision => '2634', + :source => 'git@repo', + :path => '/tmp/test', + :force => false + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('git').returns('/usr/bin/git') + end + + context 'creating' do + context "with a revision that is a remote branch" do + it "should execute 'git clone' and 'git checkout -b'" do + resource[:revision] = 'only/remote' + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + end + + context "with a remote not named 'origin'" do + it "should execute 'git clone --origin not_origin" do + resource[:remote] = 'not_origin' + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', '--origin', 'not_origin', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("not_origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + end + + context "with shallow clone enable" do + it "should execute 'git clone --depth 1'" do + resource[:revision] = 'only/remote' + resource[:depth] = 1 + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', '--depth', '1', '--branch', resource.value(:revision),resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + end + + context "with a revision that is not a remote branch" do + it "should execute 'git clone' and 'git reset --hard'" do + resource[:revision] = 'a-commit-or-tag' + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + + it "should execute 'git clone' and submodule commands" do + resource.delete(:revision) + provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remotes) + provider.create + end + end + + context "with an ensure of bare" do + context "with revision" do + it "should raise an error" do + resource[:ensure] = :bare + expect { provider.create }.to raise_error Puppet::Error, /cannot set a revision.+bare/i + end + end + context "without revision" do + it "should just execute 'git clone --bare'" do + resource[:ensure] = :bare + resource.delete(:revision) + provider.expects(:git).with('clone', '--bare', resource.value(:source), resource.value(:path)) + provider.expects(:update_remotes) + provider.create + end + end + end + + context "with an ensure of mirror" do + context "with revision" do + it "should raise an error" do + resource[:ensure] = :mirror + expect { provider.create }.to raise_error Puppet::Error, /cannot set a revision.+bare/i + end + end + context "without revision" do + it "should just execute 'git clone --mirror'" do + resource[:ensure] = :mirror + resource.delete(:revision) + provider.expects(:git).with('clone', '--mirror', resource.value(:source), resource.value(:path)) + provider.expects(:update_remotes) + provider.create + end + end + end + + context "when a source is not given" do + context "when the path does not exist" do + it "should execute 'git init'" do + resource[:ensure] = :present + resource.delete(:source) + expects_mkdir + expects_chdir + expects_directory?(false) + + provider.expects(:bare_exists?).returns(false) + provider.expects(:git).with('init') + provider.create + end + end + + context "when the path is a bare repository" do + it "should convert it to a working copy" do + resource[:ensure] = :present + resource.delete(:source) + provider.expects(:bare_exists?).returns(true) + provider.expects(:convert_bare_to_working_copy) + provider.create + end + end + + context "when the path is not empty and not a repository" do + it "should raise an exception" do + provider.expects(:path_exists?).returns(true) + provider.expects(:path_empty?).returns(false) + expect { provider.create }.to raise_error(Puppet::Error) + end + end + end + + context "when the path does not exist" do + it "should execute 'git init --bare'" do + resource[:ensure] = :bare + resource.delete(:source) + resource.delete(:revision) + expects_chdir + expects_mkdir + expects_directory?(false) + provider.expects(:working_copy_exists?).returns(false) + provider.expects(:git).with('init', '--bare') + provider.create + end + + it "should raise an exeption" do + resource[:ensure] = :mirror + resource.delete(:source) + resource.delete(:revision) + + expect { provider.create }.to raise_error Puppet::Error, /cannot init repository with mirror.+try bare/i + end + end + + context "when the path is a working copy repository" do + it "should convert it to a bare repository" do + resource[:ensure] = :bare + resource.delete(:source) + resource.delete(:revision) + provider.expects(:working_copy_exists?).returns(true) + provider.expects(:convert_working_copy_to_bare) + provider.create + end + it "should clone overtop it using force" do + resource[:force] = true + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:path_exists?).returns(true) + provider.expects(:path_empty?).returns(false) + provider.destroy + provider.expects(:git).with('clone',resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + end + + context "when the path is not empty and not a repository" do + it "should raise an exception" do + provider.expects(:path_exists?).returns(true) + provider.expects(:path_empty?).returns(false) + provider.expects(:working_copy_exists?).returns(false) + expect { provider.create }.to raise_error(Puppet::Error) + end + end + end + + + context 'destroying' do + it "it should remove the directory" do + #expects_rm_rf + provider.destroy + end + end + + context "checking the revision property" do + before do + expects_chdir('/tmp/test') + resource[:revision] = 'currentsha' + resource[:source] = 'http://example.com' + provider.stubs(:git).with('config', 'remote.origin.url').returns('') + provider.stubs(:git).with('fetch', 'origin') # FIXME + provider.stubs(:git).with('fetch', '--tags', 'origin') + provider.stubs(:git).with('rev-parse', 'HEAD').returns('currentsha') + provider.stubs(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.stubs(:git).with('tag', '-l').returns("Hello") + end + + context "when its SHA is not different than the current SHA" do + it "should return the ref" do + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('currentsha') + provider.expects(:update_remotes) + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when its SHA is different than the current SHA" do + it "should return the current SHA" do + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('othersha') + provider.expects(:update_remotes) + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when its a ref to a remote head" do + it "should return the revision" do + provider.stubs(:git).with('branch', '-a').returns(" remotes/origin/#{resource.value(:revision)}") + provider.expects(:git).with('rev-parse', "origin/#{resource.value(:revision)}").returns("newsha") + provider.expects(:update_remotes) + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when its a ref to non existant remote head" do + it "should fail" do + provider.expects(:git).with('branch', '-a').returns(branch_a_list) + provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('') + provider.expects(:update_remotes) + expect { provider.revision }.to raise_error(Puppet::Error, /not a local or remote ref$/) + end + end + + context "when the source is modified" do + it "should update the origin url" do + resource[:source] = 'git://git@foo.com/bar.git' + provider.expects(:git).with('config', '-l').returns("remote.origin.url=git://git@foo.com/foo.git\n") + provider.expects(:git).with('remote', 'set-url', 'origin', 'git://git@foo.com/bar.git') + provider.expects(:git).with('remote','update') + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('currentsha') + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when multiple sources are modified" do + it "should update the urls" do + resource[:source] = {"origin" => "git://git@foo.com/bar.git", "new_remote" => "git://git@foo.com/baz.git"} + provider.expects(:git).at_least_once.with('config', '-l').returns("remote.origin.url=git://git@foo.com/bar.git\n", "remote.origin.url=git://git@foo.com/foo.git\n") + provider.expects(:git).with('remote', 'set-url', 'origin', 'git://git@foo.com/bar.git') + provider.expects(:git).with('remote', 'add', 'new_remote', 'git://git@foo.com/baz.git') + provider.expects(:git).with('remote','update') + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('currentsha') + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when there's no source" do + it 'should return the revision' do + resource.delete(:source) + provider.expects(:git).with('status') + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('currentsha') + expect(provider.revision).to eq(resource.value(:revision)) + end + end + end + + context "setting the revision property" do + before do + expects_chdir + end + context "when it's an existing local branch" do + it "should use 'git fetch' and 'git reset'" do + resource[:revision] = 'feature/foo' + provider.expects(:update_submodules) + provider.expects(:git).with('branch', '-a').at_least_once.returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}") + provider.revision = resource.value(:revision) + end + end + context "when it's a remote branch" do + it "should use 'git fetch' and 'git reset'" do + resource[:revision] = 'only/remote' + provider.expects(:update_submodules) + provider.expects(:git).with('branch', '-a').at_least_once.returns(resource.value(:revision)) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}") + provider.revision = resource.value(:revision) + end + end + context "when it's a commit or tag" do + it "should use 'git fetch' and 'git reset'" do + resource[:revision] = 'a-commit-or-tag' + provider.expects(:git).with('branch', '-a').at_least_once.returns(fixture(:git_branch_a)) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a)) + provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a)) + provider.expects(:git).with('submodule', 'update', '--init', '--recursive') + provider.revision = resource.value(:revision) + end + end + end + + context "updating references" do + it "should use 'git fetch --tags'" do + resource.delete(:source) + expects_chdir + provider.expects(:git).with('config', '-l').returns("remote.origin.url=git://git@foo.com/foo.git\n") + provider.expects(:git).with('fetch', 'origin') + provider.expects(:git).with('fetch', '--tags', 'origin') + provider.update_references + end + end + + describe 'latest?' do + context 'when true' do + it do + provider.expects(:revision).returns('testrev') + provider.expects(:latest_revision).returns('testrev') + expect(provider.latest?).to be_truthy + end + end + context 'when false' do + it do + provider.expects(:revision).returns('master') + provider.expects(:latest_revision).returns('testrev') + expect(provider.latest?).to be_falsey + end + end + end + + describe 'convert_working_copy_to_bare' do + it do + FileUtils.expects(:mv).returns(true) + FileUtils.expects(:rm_rf).returns(true) + FileUtils.expects(:mv).returns(true) + + provider.instance_eval { convert_working_copy_to_bare } + end + end + + describe 'convert_bare_to_working_copy' do + it do + FileUtils.expects(:mv).returns(true) + FileUtils.expects(:mkdir).returns(true) + FileUtils.expects(:mv).returns(true) + provider.expects(:commits_in?).returns(true) + # If you forget to stub these out you lose 3 hours of rspec work. + provider.expects(:reset).with('HEAD').returns(true) + provider.expects(:git_with_identity).returns(true) + provider.expects(:update_owner_and_excludes).returns(true) + + provider.instance_eval { convert_bare_to_working_copy } + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb new file mode 100644 index 00000000..65d820d9 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb @@ -0,0 +1,138 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:hg) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :hg, + :path => '/tmp/vcsrepo', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('hg').returns('/usr/bin/hg') + end + + describe 'creating' do + context 'with source and revision' do + it "should execute 'hg clone -u' with the revision" do + resource[:source] = 'something' + resource[:revision] = '1' + provider.expects(:hg).with('clone', '-u', + resource.value(:revision), + resource.value(:source), + resource.value(:path)) + provider.create + end + end + + context 'without revision' do + it "should just execute 'hg clone' without a revision" do + resource[:source] = 'something' + provider.expects(:hg).with('clone', resource.value(:source), resource.value(:path)) + provider.create + end + end + + context "when a source is not given" do + it "should execute 'hg init'" do + provider.expects(:hg).with('init', resource.value(:path)) + provider.create + end + end + + context "when basic auth is used" do + it "should execute 'hg clone'" do + resource[:source] = 'something' + resource[:basic_auth_username] = 'user' + resource[:basic_auth_password] = 'pass' + provider.expects(:hg).with('clone', + resource.value(:source), + resource.value(:path), + "--config","\"auth.x.prefix=" + resource.value(:source) + "\"", + "--config","\"auth.x.username=" + resource.value(:basic_auth_username) + "\"", + "--config","\"auth.x.password=" + resource.value(:basic_auth_password) + "\"", + "--config","\"auth.x.schemes=http https" + "\"") + provider.create + end + end + end + + describe 'destroying' do + it "it should remove the directory" do + expects_rm_rf + provider.destroy + end + end + + describe "checking existence" do + it "should check for the directory" do + expects_directory?(true, File.join(resource.value(:path), '.hg')) + provider.exists? + end + end + + describe "checking the revision property" do + before do + expects_chdir + end + + context "when given a non-SHA as the resource revision" do + before do + provider.expects(:hg).with('parents').returns(fixture(:hg_parents)) + provider.expects(:hg).with('tags').returns(fixture(:hg_tags)) + end + + context "when its SHA is not different than the current SHA" do + it "should return the ref" do + resource[:revision] = '0.6' + expect(provider.revision).to eq('0.6') + end + end + + context "when its SHA is different than the current SHA" do + it "should return the current SHA" do + resource[:revision] = '0.5.3' + expect(provider.revision).to eq('34e6012c783a') + end + end + end + context "when given a SHA as the resource revision" do + before do + provider.expects(:hg).with('parents').returns(fixture(:hg_parents)) + end + + context "when it is the same as the current SHA", :resource => {:revision => '34e6012c783a'} do + it "should return it" do + resource[:revision] = '34e6012c783a' + provider.expects(:hg).with('tags').returns(fixture(:hg_tags)) + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when it is not the same as the current SHA", :resource => {:revision => 'not-the-same'} do + it "should return the current SHA" do + resource[:revision] = 'not-the-same' + provider.expects(:hg).with('tags').returns(fixture(:hg_tags)) + expect(provider.revision).to eq('34e6012c783a') + end + end + end + end + + describe "setting the revision property" do + before do + @revision = '6aa99e9b3ab1' + end + it "should use 'hg update ---clean -r'" do + expects_chdir + provider.expects(:hg).with('pull') + provider.expects(:hg).with('merge') + provider.expects(:hg).with('update', '--clean', '-r', @revision) + provider.revision = @revision + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/p4_spec.rb b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/p4_spec.rb new file mode 100644 index 00000000..e331cae6 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/p4_spec.rb @@ -0,0 +1,82 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:p4) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :p4, + :path => '/tmp/vcsrepo', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('p4').returns('/usr/local/bin/p4') + end + + spec = { + :input => "Description: Generated by Puppet VCSrepo\nRoot: /tmp/vcsrepo\n\nView:\n", + :marshal => false + } + + describe 'creating' do + context 'with source and revision' do + it "should execute 'p4 sync' with the revision" do + resource[:source] = 'something' + resource[:revision] = '1' + ENV['P4CLIENT'] = 'client_ws1' + + provider.expects(:p4).with(['client', '-o', 'client_ws1']).returns({}) + provider.expects(:p4).with(['client', '-i'], spec) + provider.expects(:p4).with(['sync', resource.value(:source) + "@" + resource.value(:revision)]) + provider.create + end + end + + context 'without revision' do + it "should just execute 'p4 sync' without a revision" do + resource[:source] = 'something' + ENV['P4CLIENT'] = 'client_ws2' + + provider.expects(:p4).with(['client', '-o', 'client_ws2']).returns({}) + provider.expects(:p4).with(['client', '-i'], spec) + provider.expects(:p4).with(['sync', resource.value(:source)]) + provider.create + end + end + + context "when a client and source are not given" do + it "should execute 'p4 client'" do + ENV['P4CLIENT'] = nil + + path = resource.value(:path) + host = Facter.value('hostname') + default = "puppet-" + Digest::MD5.hexdigest(path + host) + + provider.expects(:p4).with(['client', '-o', default]).returns({}) + provider.expects(:p4).with(['client', '-i'], spec) + provider.create + end + end + end + + describe 'destroying' do + it "it should remove the directory" do + ENV['P4CLIENT'] = 'test_client' + + provider.expects(:p4).with(['client', '-d', '-f', 'test_client']) + expects_rm_rf + provider.destroy + end + end + + describe "checking existence" do + it "should check for the directory" do + provider.expects(:p4).with(['info'], {:marshal => false}).returns({}) + provider.expects(:p4).with(['where', resource.value(:path) + "..."], {:raise => false}).returns({}) + provider.exists? + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb new file mode 100644 index 00000000..6a37c205 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb @@ -0,0 +1,160 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:svn) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :svn, + :path => '/tmp/vcsrepo', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('git').returns('/usr/bin/git') + end + + describe 'creating' do + context 'with source and revision' do + it "should execute 'svn checkout' with a revision" do + resource[:source] = 'exists' + resource[:revision] = '1' + provider.expects(:svn).with('--non-interactive', 'checkout', '-r', + resource.value(:revision), + resource.value(:source), + resource.value(:path)) + provider.create + end + end + context 'with source' do + it "should just execute 'svn checkout' without a revision" do + resource[:source] = 'exists' + provider.expects(:svn).with('--non-interactive', 'checkout', + resource.value(:source), + resource.value(:path)) + provider.create + end + end + + context 'with fstype' do + it "should execute 'svnadmin create' with an '--fs-type' option" do + resource[:fstype] = 'ext4' + provider.expects(:svnadmin).with('create', '--fs-type', + resource.value(:fstype), + resource.value(:path)) + provider.create + end + end + context 'without fstype' do + it "should execute 'svnadmin create' without an '--fs-type' option" do + provider.expects(:svnadmin).with('create', resource.value(:path)) + provider.create + end + end + + context "with depth" do + it "should execute 'svn checkout' with a depth" do + resource[:source] = 'exists' + resource[:depth] = 'infinity' + provider.expects(:svn).with('--non-interactive', 'checkout', '--depth', 'infinity', + resource.value(:source), + resource.value(:path)) + provider.create + end + end + + context "with trust_server_cert" do + it "should execute 'svn checkout' without a trust-server-cert" do + resource[:source] = 'exists' + resource[:trust_server_cert] = :false + provider.expects(:svn).with('--non-interactive', 'checkout', + resource.value(:source), + resource.value(:path)) + provider.create + end + it "should execute 'svn checkout' with a trust-server-cert" do + resource[:source] = 'exists' + resource[:trust_server_cert] = :true + provider.expects(:svn).with('--non-interactive', '--trust-server-cert', 'checkout', + resource.value(:source), + resource.value(:path)) + provider.create + end + end + end + + describe 'destroying' do + it "it should remove the directory" do + expects_rm_rf + provider.destroy + end + end + + describe "checking existence" do + it "should check for the directory" do + expects_directory?(true, resource.value(:path)) + expects_directory?(true, File.join(resource.value(:path), '.svn')) + provider.exists? + end + end + + describe "checking the revision property" do + before do + provider.expects(:svn).with('--non-interactive', 'info').returns(fixture(:svn_info)) + end + it "should use 'svn info'" do + expects_chdir + expect(provider.revision).to eq('4') # From 'Revision', not 'Last Changed Rev' + end + end + + describe "setting the revision property" do + before do + @revision = '30' + end + context 'with conflict' do + it "should use 'svn update'" do + resource[:conflict] = 'theirs-full' + expects_chdir + provider.expects(:svn).with('--non-interactive', 'update', + '-r', @revision, + '--accept', resource.value(:conflict)) + provider.revision = @revision + end + end + context 'without conflict' do + it "should use 'svn update'" do + expects_chdir + provider.expects(:svn).with('--non-interactive', 'update', '-r', @revision) + provider.revision = @revision + end + end + end + + describe "setting the revision property and repo source" do + before do + @revision = '30' + end + context 'with conflict' do + it "should use 'svn switch'" do + resource[:source] = 'an-unimportant-value' + resource[:conflict] = 'theirs-full' + expects_chdir + provider.expects(:svn).with('--non-interactive', 'switch', + '-r', @revision, 'an-unimportant-value', + '--accept', resource.value(:conflict)) + provider.revision = @revision + end + end + context 'without conflict' do + it "should use 'svn switch'" do + resource[:source] = 'an-unimportant-value' + expects_chdir + provider.expects(:svn).with('--non-interactive', 'switch', '-r', @revision, 'an-unimportant-value') + provider.revision = @revision + end + end + end + +end diff --git a/puppet/modules/vcsrepo/spec/unit/puppet/type/README.markdown b/puppet/modules/vcsrepo/spec/unit/puppet/type/README.markdown new file mode 100644 index 00000000..1ee19ac8 --- /dev/null +++ b/puppet/modules/vcsrepo/spec/unit/puppet/type/README.markdown @@ -0,0 +1,4 @@ +Resource Type Specs +=================== + +Define specs for your resource types in this directory. -- cgit v1.2.3 From 1e1e25286b64790141c9627f81b50f579b13b719 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:46:28 -0400 Subject: git subrepo clone https://leap.se/git/puppet_rsyslog puppet/modules/rsyslog subrepo: subdir: "puppet/modules/rsyslog" merged: "b8ef11c" upstream: origin: "https://leap.se/git/puppet_rsyslog" branch: "master" commit: "b8ef11c" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: Iee06502c6df609f1a261410742360cec8694dab5 --- puppet/modules/rsyslog/.fixtures.yml | 3 + puppet/modules/rsyslog/.gemfile | 14 + puppet/modules/rsyslog/.gitignore | 5 + puppet/modules/rsyslog/.gitrepo | 11 + puppet/modules/rsyslog/.travis.yml | 56 +++ puppet/modules/rsyslog/LICENSE | 202 +++++++++ puppet/modules/rsyslog/README.md | 202 +++++++++ puppet/modules/rsyslog/Rakefile | 6 + .../modules/rsyslog/lib/facter/rsyslog_version.rb | 38 ++ puppet/modules/rsyslog/manifests/client.pp | 64 +++ puppet/modules/rsyslog/manifests/config.pp | 51 +++ puppet/modules/rsyslog/manifests/database.pp | 57 +++ puppet/modules/rsyslog/manifests/imfile.pp | 48 +++ puppet/modules/rsyslog/manifests/init.pp | 54 +++ puppet/modules/rsyslog/manifests/install.pp | 32 ++ puppet/modules/rsyslog/manifests/modload.pp | 15 + puppet/modules/rsyslog/manifests/params.pp | 222 ++++++++++ puppet/modules/rsyslog/manifests/server.pp | 70 +++ puppet/modules/rsyslog/manifests/service.pp | 21 + puppet/modules/rsyslog/manifests/snippet.pp | 35 ++ puppet/modules/rsyslog/metadata.json | 62 +++ .../rsyslog/spec/classes/rsyslog_client_spec.rb | 146 +++++++ .../rsyslog/spec/classes/rsyslog_database_spec.rb | 308 ++++++++++++++ .../rsyslog/spec/classes/rsyslog_server_spec.rb | 182 ++++++++ .../modules/rsyslog/spec/classes/rsyslog_spec.rb | 469 +++++++++++++++++++++ .../rsyslog/spec/defines/rsyslog_imfile_spec.rb | 169 ++++++++ .../rsyslog/spec/defines/rsyslog_snippet_spec.rb | 157 +++++++ puppet/modules/rsyslog/spec/spec.opts | 6 + puppet/modules/rsyslog/spec/spec_helper.rb | 28 ++ puppet/modules/rsyslog/templates/client.conf.erb | 180 ++++++++ puppet/modules/rsyslog/templates/database.conf.erb | 6 + puppet/modules/rsyslog/templates/imfile.erb | 15 + puppet/modules/rsyslog/templates/modload.erb | 3 + puppet/modules/rsyslog/templates/rsyslog.conf.erb | 49 +++ .../modules/rsyslog/templates/rsyslog_default.erb | 9 + .../rsyslog/templates/rsyslog_default_gentoo.erb | 16 + .../rsyslog/templates/rsyslog_default_rhel7.erb | 2 + .../rsyslog/templates/server-default.conf.erb | 42 ++ .../rsyslog/templates/server-hostname.conf.erb | 41 ++ .../templates/server/_default-footer.conf.erb | 13 + .../templates/server/_default-header.conf.erb | 36 ++ puppet/modules/rsyslog/tests/database.pp | 9 + puppet/modules/rsyslog/tests/init.pp | 1 + puppet/modules/rsyslog/tests/log_templates.pp | 9 + puppet/modules/rsyslog/tests/multiple_hosts.pp | 17 + 45 files changed, 3181 insertions(+) create mode 100644 puppet/modules/rsyslog/.fixtures.yml create mode 100644 puppet/modules/rsyslog/.gemfile create mode 100644 puppet/modules/rsyslog/.gitignore create mode 100644 puppet/modules/rsyslog/.gitrepo create mode 100644 puppet/modules/rsyslog/.travis.yml create mode 100644 puppet/modules/rsyslog/LICENSE create mode 100644 puppet/modules/rsyslog/README.md create mode 100644 puppet/modules/rsyslog/Rakefile create mode 100644 puppet/modules/rsyslog/lib/facter/rsyslog_version.rb create mode 100644 puppet/modules/rsyslog/manifests/client.pp create mode 100644 puppet/modules/rsyslog/manifests/config.pp create mode 100644 puppet/modules/rsyslog/manifests/database.pp create mode 100644 puppet/modules/rsyslog/manifests/imfile.pp create mode 100644 puppet/modules/rsyslog/manifests/init.pp create mode 100644 puppet/modules/rsyslog/manifests/install.pp create mode 100644 puppet/modules/rsyslog/manifests/modload.pp create mode 100644 puppet/modules/rsyslog/manifests/params.pp create mode 100644 puppet/modules/rsyslog/manifests/server.pp create mode 100644 puppet/modules/rsyslog/manifests/service.pp create mode 100644 puppet/modules/rsyslog/manifests/snippet.pp create mode 100644 puppet/modules/rsyslog/metadata.json create mode 100644 puppet/modules/rsyslog/spec/classes/rsyslog_client_spec.rb create mode 100644 puppet/modules/rsyslog/spec/classes/rsyslog_database_spec.rb create mode 100644 puppet/modules/rsyslog/spec/classes/rsyslog_server_spec.rb create mode 100644 puppet/modules/rsyslog/spec/classes/rsyslog_spec.rb create mode 100644 puppet/modules/rsyslog/spec/defines/rsyslog_imfile_spec.rb create mode 100644 puppet/modules/rsyslog/spec/defines/rsyslog_snippet_spec.rb create mode 100644 puppet/modules/rsyslog/spec/spec.opts create mode 100644 puppet/modules/rsyslog/spec/spec_helper.rb create mode 100644 puppet/modules/rsyslog/templates/client.conf.erb create mode 100644 puppet/modules/rsyslog/templates/database.conf.erb create mode 100644 puppet/modules/rsyslog/templates/imfile.erb create mode 100644 puppet/modules/rsyslog/templates/modload.erb create mode 100644 puppet/modules/rsyslog/templates/rsyslog.conf.erb create mode 100644 puppet/modules/rsyslog/templates/rsyslog_default.erb create mode 100644 puppet/modules/rsyslog/templates/rsyslog_default_gentoo.erb create mode 100644 puppet/modules/rsyslog/templates/rsyslog_default_rhel7.erb create mode 100644 puppet/modules/rsyslog/templates/server-default.conf.erb create mode 100644 puppet/modules/rsyslog/templates/server-hostname.conf.erb create mode 100644 puppet/modules/rsyslog/templates/server/_default-footer.conf.erb create mode 100644 puppet/modules/rsyslog/templates/server/_default-header.conf.erb create mode 100644 puppet/modules/rsyslog/tests/database.pp create mode 100644 puppet/modules/rsyslog/tests/init.pp create mode 100644 puppet/modules/rsyslog/tests/log_templates.pp create mode 100644 puppet/modules/rsyslog/tests/multiple_hosts.pp (limited to 'puppet/modules') diff --git a/puppet/modules/rsyslog/.fixtures.yml b/puppet/modules/rsyslog/.fixtures.yml new file mode 100644 index 00000000..b1fb3e0c --- /dev/null +++ b/puppet/modules/rsyslog/.fixtures.yml @@ -0,0 +1,3 @@ +fixtures: + symlinks: + "rsyslog": "#{source_dir}" diff --git a/puppet/modules/rsyslog/.gemfile b/puppet/modules/rsyslog/.gemfile new file mode 100644 index 00000000..e9e12704 --- /dev/null +++ b/puppet/modules/rsyslog/.gemfile @@ -0,0 +1,14 @@ +source 'https://rubygems.org' + +group :development, :test do + gem 'rake', :require => false + gem 'puppet-lint', :require => false + gem 'rspec-puppet', :require => false + gem 'puppetlabs_spec_helper', :require => false +end + +if puppetversion = ENV['PUPPET_GEM_VERSION'] + gem 'puppet', puppetversion, :require => false +else + gem 'puppet', :require => false +end diff --git a/puppet/modules/rsyslog/.gitignore b/puppet/modules/rsyslog/.gitignore new file mode 100644 index 00000000..d51673f2 --- /dev/null +++ b/puppet/modules/rsyslog/.gitignore @@ -0,0 +1,5 @@ +pkg/ +*.swp +.forge-releng +/spec/fixtures +.DS_Store diff --git a/puppet/modules/rsyslog/.gitrepo b/puppet/modules/rsyslog/.gitrepo new file mode 100644 index 00000000..fa9db13d --- /dev/null +++ b/puppet/modules/rsyslog/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_rsyslog + branch = master + commit = b8ef11c23949d12732ad5cdaebb3023ff39a297a + parent = 850a14b59444737f703686d0d1996bf09ab08e2b + cmdver = 0.3.0 diff --git a/puppet/modules/rsyslog/.travis.yml b/puppet/modules/rsyslog/.travis.yml new file mode 100644 index 00000000..bf7edebb --- /dev/null +++ b/puppet/modules/rsyslog/.travis.yml @@ -0,0 +1,56 @@ +--- +branches: + only: + - master +language: ruby +bundler_args: --without development +script: bundle exec rake spec SPEC_OPTS='--format documentation' +after_success: + - git clone -q git://github.com/puppetlabs/ghpublisher.git .forge-releng + - .forge-releng/publish +rvm: + - 1.8.7 + - 1.9.3 + - 2.0.0 + - 2.1.1 +env: + matrix: + - PUPPET_GEM_VERSION="~> 2.7.0" + - PUPPET_GEM_VERSION="~> 3.0.0" + - PUPPET_GEM_VERSION="~> 3.1.0" + - PUPPET_GEM_VERSION="~> 3.2.0" + - PUPPET_GEM_VERSION="~> 3.3.0" + - PUPPET_GEM_VERSION="~> 3.4.0" + - PUPPET_GEM_VERSION="~> 3.5.0" + global: + - PUBLISHER_LOGIN=saz + - secure: |- + EmipIx5A93xnHKwdHfuMPGNLjLz0M0wND0IyeucWhIHE+KtZ48oT+mO2XhnJSpu1DH + JaSoYgjQpCILvniWg76o+HY1bTDEP3AmUlxNFgfDAOAQfv0RHv2cEcgNxNrxsddx6S + Ks0FCvVkFgY703X+kBiYTpjP4SBzRe0y9OudSvk= +matrix: + fast_finish: true + exclude: + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 2.7.0" + - rvm: 2.0.0 + env: PUPPET_GEM_VERSION="~> 2.7.0" + - rvm: 2.0.0 + env: PUPPET_GEM_VERSION="~> 3.0.0" + - rvm: 2.0.0 + env: PUPPET_GEM_VERSION="~> 3.1.0" + - rvm: 2.1.1 + env: PUPPET_GEM_VERSION="~> 2.7.0" + - rvm: 2.1.1 + env: PUPPET_GEM_VERSION="~> 3.0.0" + - rvm: 2.1.1 + env: PUPPET_GEM_VERSION="~> 3.1.0" + - rvm: 2.1.1 + env: PUPPET_GEM_VERSION="~> 3.2.0" + - rvm: 2.1.1 + env: PUPPET_GEM_VERSION="~> 3.3.0" + - rvm: 2.1.1 + env: PUPPET_GEM_VERSION="~> 3.4.0" +notifications: + email: false +gemfile: .gemfile diff --git a/puppet/modules/rsyslog/LICENSE b/puppet/modules/rsyslog/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/puppet/modules/rsyslog/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/puppet/modules/rsyslog/README.md b/puppet/modules/rsyslog/README.md new file mode 100644 index 00000000..d9292866 --- /dev/null +++ b/puppet/modules/rsyslog/README.md @@ -0,0 +1,202 @@ +# puppet-rsyslog [![Build Status](https://secure.travis-ci.org/saz/puppet-rsyslog.png)](https://travis-ci.org/saz/puppet-rsyslog) + +Manage rsyslog client and server via Puppet + +## REQUIREMENTS + +* Puppet >=2.6 if using parameterized classes +* Currently supports Ubuntu >=11.04 & Debian running rsyslog >=4.5 + +## USAGE + +### Client + +#### Using default values +``` + class { 'rsyslog::client': } +``` + +#### Variables and default values +``` + class { 'rsyslog::client': + log_remote => true, + spool_size => '1g', + remote_type => 'tcp', + remote_forward_format => 'RSYSLOG_ForwardFormat', + log_local => false, + log_auth_local => false, + custom_config => undef, + custom_params => undef, + server => 'log', + port => '514', + remote_servers => false, + ssl_ca => undef, + log_templates => false, + actionfiletemplate => false + } +``` +for read from file +``` + rsyslog::imfile { 'my-imfile': + file_name => '/some/file', + file_tag => 'mytag', + file_facility => 'myfacility', + } + +``` + +#### Defining custom logging templates + +The `log_templates` parameter can be used to set up custom logging templates, which can be used for local and/or remote logging. More detail on template formats can be found in the [rsyslog documentation](http://www.rsyslog.com/doc/rsyslog_conf_templates.html). + +The following examples sets up a custom logging template as per [RFC3164fmt](https://www.ietf.org/rfc/rfc3164.txt): + +```puppet +class{'rsyslog::client': + log_templates => [ + { + name => 'RFC3164fmt', + template => '<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%', + }, + ] +} +``` + +#### Logging to multiple remote servers + +The `remote_servers` parameter can be used to set up logging to multiple remote servers which are supplied as a list of key value pairs for each remote. There is an example configuration provided in `./test/multiple_hosts.pp` + +Using the `remote_servers` parameter over-rides the other remote sever parameters, and they will not be used in the client configuration file: +* `log_remote` +* `remote_type` +* `server` +* `port` + +The following example sets up three remote logging hosts for the client: + +```puppet +class{'rsyslog::client': + remote_servers => [ + { + host => 'logs.example.org', + }, + { + port => '55514', + }, + { + host => 'logs.somewhere.com', + port => '555', + pattern => '*.log', + protocol => 'tcp', + format => 'RFC3164fmt', + }, + ] +} +``` + +Each host has the following parameters: +* *host*: Sets the address or hostname of the remote logging server. Defaults to `localhost` +* *port*: Sets the port the host is listening on. Defaults to `514` +* *pattern*: Sets the pattern to match logs. Defaults to `*.*` +* *protocol*: Sets the protocol. Only recognises TCP and UDP. Defaults to UDP +* *format*: Sets the log format. Defaults to not specifying log format, which defaults to the format set by `ActionFileDefaultTemplate` in the client configuration. + +#### Logging to a MySQL or PostgreSQL database + +Events can also be logged to a MySQL or PostgreSQL database. The database needs to be deployed separately, either locally or remotely. Schema are available from the `rsyslog` source: + + * [MySQL schema](http://git.adiscon.com/?p=rsyslog.git;a=blob_plain;f=plugins/ommysql/createDB.sql) + * [PostgreSQL schema](http://git.adiscon.com/?p=rsyslog.git;a=blob_plain;f=plugins/ompgsql/createDB.sql) + +Declare the following to configure the connection: +```` + class { 'rsyslog::database': + backend => 'mysql', + server => 'localhost', + database => 'Syslog', + username => 'rsyslog', + password => 'secret', + } +```` +### Server + +#### Using default values +``` + class { 'rsyslog::server': } +``` + +#### Variables and default values +``` + class { 'rsyslog::server': + enable_tcp => true, + enable_udp => true, + enable_onefile => false, + server_dir => '/srv/log/', + custom_config => undef, + high_precision_timestamps => false, + } +``` + +Both can be installed at the same time. + +## PARAMETERS + +The following lists all the class parameters this module accepts. + + RSYSLOG::SERVER CLASS PARAMETERS VALUES DESCRIPTION + ------------------------------------------------------------------- + enable_tcp true,false Enable TCP listener. Defaults to true. + enable_udp true,false Enable UDP listener. Defaults to true. + enable_onefile true,false Only one logfile per remote host. Defaults to false. + server_dir STRING Folder where logs will be stored on the server. Defaults to '/srv/log/' + custom_config STRING Specify your own template to use for server config. Defaults to undef. Example usage: custom_config => 'rsyslog/my_config.erb' + high_precision_timestamps true,false Whether or not to use high precision timestamps. + remote_servers HASH Provides a hash of multiple remote logging servers. Check documentation. + + RSYSLOG::CLIENT CLASS PARAMETERS VALUES DESCRIPTION + ------------------------------------------------------------------- + log_remote true,false Log Remotely. Defaults to true. + spool_size STRING Max size for disk queue if remote server failed. Defaults to '1g'. + remote_type 'tcp','udp' Which protocol to use when logging remotely. Defaults to 'tcp'. + remote_forward_format STRING Which forward format for remote servers should be used. Only used if remote_servers is false. + log_local true,false Log locally. Defaults to false. + log_auth_local true,false Just log auth facility locally. Defaults to false. + custom_config STRING Specify your own template to use for client config. Defaults to undef. Example usage: custom_config => 'rsyslog/my_config.erb' + custom_params TODO TODO + server STRING Rsyslog server to log to. Will be used in the client configuration file. Only used, if remote_servers is false. + port '514' Remote server port. Only used if remote_servers is false. + remote_servers Array of hashes Array of hashes with remote servers. See documentation above. Defaults to false. + ssl_ca STRING SSL CA file location. Defaults to undef. + log_templates HASH Provides a has defining custom logging templates using the `$template` configuration parameter. + actionfiletemplate STRING If set this defines the `ActionFileDefaultTemplate` which sets the default logging format for remote and local logging. + + RSYSLOG::DATABASE CLASS PARAMETERS VALUES DESCRIPTION + ------------------------------------------------------------------- + backend 'mysql','pgsql' Database backend (MySQL or PostgreSQL). + server STRING Database server. + database STRING Database name. + username STRING Database username. + password STRING Database password. + +### Other notes + +Due to a missing feature in current RELP versions (InputRELPServerBindRuleset option), +remote logging is using TCP. You can switch between TCP and UDP. As soon as there is +a new RELP version which supports setting Rulesets, I will add support for relp back. + +By default, rsyslog::server will strip numbers from hostnames. This means the logs of +multiple servers with the same non-numerical name will be aggregrated in a single +directory. i.e. www01 www02 and www02 would all log to the www directory. + +To log each host to a seperate directory, set the custom_config parameter to +'rsyslog/server-hostname.conf.erb' + +If any of the following parameters are set to `false`, then the module will not +manage the respective package: + + gnutls_package_name + relp_package_name + rsyslog_package_name + +This can be used when using the adiscon PPA repository, that has merged rsyslog-gnutls +with the main rsyslog package. diff --git a/puppet/modules/rsyslog/Rakefile b/puppet/modules/rsyslog/Rakefile new file mode 100644 index 00000000..469b83c6 --- /dev/null +++ b/puppet/modules/rsyslog/Rakefile @@ -0,0 +1,6 @@ +require 'puppetlabs_spec_helper/rake_tasks' + +# Enable puppet-lint for all manifests: rake lint +require 'puppet-lint/tasks/puppet-lint' +PuppetLint.configuration.send("disable_80chars") # no warnings on lines over 80 chars. +PuppetLint.configuration.ignore_paths = ["spec/fixtures/**/*.pp"] diff --git a/puppet/modules/rsyslog/lib/facter/rsyslog_version.rb b/puppet/modules/rsyslog/lib/facter/rsyslog_version.rb new file mode 100644 index 00000000..de8531e8 --- /dev/null +++ b/puppet/modules/rsyslog/lib/facter/rsyslog_version.rb @@ -0,0 +1,38 @@ +# Fact: :syslog_package +# +# Purpose: retrieve installed rsyslog version +# + +Facter.add(:rsyslog_version) do + setcode do + osfamily = Facter.value('osfamily') + case osfamily + when "Debian" + command='/usr/bin/dpkg-query -f \'${Status};${Version};\' -W rsyslog 2>/dev/null' + version = Facter::Util::Resolution.exec(command) + if version =~ /.*install ok installed;([^;]+);.*/ + $1 + else + nil + end + when "RedHat", "Suse" + command='rpm -qa --qf "%{VERSION}" "rsyslog"' + version = Facter::Util::Resolution.exec(command) + if version =~ /^(.+)$/ + $1 + else + nil + end + when "FreeBSD" + command='pkg query %v rsyslog' + version = Facter::Util::Resolution.exec(command) + if version =~ /^(.+)$/ + $1 + else + nil + end + else + nil + end + end +end diff --git a/puppet/modules/rsyslog/manifests/client.pp b/puppet/modules/rsyslog/manifests/client.pp new file mode 100644 index 00000000..193aa336 --- /dev/null +++ b/puppet/modules/rsyslog/manifests/client.pp @@ -0,0 +1,64 @@ +# == Class: rsyslog::client +# +# Full description of class role here. +# +# === Parameters +# +# [*log_remote*] +# [*spool_size*] +# [*remote_type*] +# [*remote_forward_format*] +# [*log_local*] +# [*log_auth_local*] +# [*custom_config*] +# [*custom_params*] +# [*server*] +# [*port*] +# [*remote_servers*] +# [*ssl_ca*] +# [*log_templates*] +# [*actionfiletemplate*] +# +# === Variables +# +# === Examples +# +# class { 'rsyslog::client': } +# +class rsyslog::client ( + $log_remote = true, + $spool_size = '1g', + $remote_type = 'tcp', + $remote_forward_format = 'RSYSLOG_ForwardFormat', + $log_local = false, + $log_auth_local = false, + $custom_config = undef, + $custom_params = undef, + $server = 'log', + $port = '514', + $remote_servers = false, + $ssl_ca = undef, + $log_templates = false, + $actionfiletemplate = false +) inherits rsyslog { + + if $custom_config { + $content_real = template($custom_config) + } else { + $content_real = template("${module_name}/client.conf.erb") + } + + rsyslog::snippet { $rsyslog::client_conf: + ensure => present, + content => $content_real, + } + + if $rsyslog::ssl and $ssl_ca == undef { + fail('You need to define $ssl_ca in order to use SSL.') + } + + if $rsyslog::ssl and $remote_type != 'tcp' { + fail('You need to enable tcp in order to use SSL.') + } + +} diff --git a/puppet/modules/rsyslog/manifests/config.pp b/puppet/modules/rsyslog/manifests/config.pp new file mode 100644 index 00000000..1aebe47b --- /dev/null +++ b/puppet/modules/rsyslog/manifests/config.pp @@ -0,0 +1,51 @@ +# == Class: rsyslog::config +# +# Full description of class role here. +# +# === Parameters +# +# === Variables +# +# === Examples +# +# class { 'rsyslog::config': } +# +class rsyslog::config { + file { $rsyslog::rsyslog_d: + ensure => directory, + owner => 'root', + group => $rsyslog::run_group, + purge => $rsyslog::purge_rsyslog_d, + recurse => true, + force => true, + require => Class['rsyslog::install'], + } + + file { $rsyslog::rsyslog_conf: + ensure => file, + owner => 'root', + group => $rsyslog::run_group, + content => template("${module_name}/rsyslog.conf.erb"), + require => Class['rsyslog::install'], + notify => Class['rsyslog::service'], + } + + file { $rsyslog::rsyslog_default: + ensure => file, + owner => 'root', + group => $rsyslog::run_group, + content => template("${module_name}/${rsyslog::rsyslog_default_file}.erb"), + require => Class['rsyslog::install'], + notify => Class['rsyslog::service'], + } + + file { $rsyslog::spool_dir: + ensure => directory, + owner => 'root', + group => $rsyslog::run_group, + seltype => 'syslogd_var_lib_t', + require => Class['rsyslog::install'], + notify => Class['rsyslog::service'], + } + +} diff --git a/puppet/modules/rsyslog/manifests/database.pp b/puppet/modules/rsyslog/manifests/database.pp new file mode 100644 index 00000000..fe6d6ac8 --- /dev/null +++ b/puppet/modules/rsyslog/manifests/database.pp @@ -0,0 +1,57 @@ +# == Class: rsyslog::database +# +# Full description of class role here. +# +# === Parameters +# +# [*backend*] - Which backend server to use (mysql|pgsql) +# [*server*] - Server hostname +# [*database*] - Database name +# [*username*] - Database username +# [*password*] - Database password +# +# === Variables +# +# === Examples +# +# class { 'rsyslog::database': +# backend => 'mysql', +# server => 'localhost', +# database => 'mydb', +# username => 'myuser', +# password => 'mypass', +# } +# +class rsyslog::database ( + $backend, + $server, + $database, + $username, + $password +) inherits rsyslog { + + $db_module = "om${backend}" + $db_conf = "${rsyslog::rsyslog_d}${backend}.conf" + + case $backend { + mysql: { $db_package = $rsyslog::mysql_package_name } + pgsql: { $db_package = $rsyslog::pgsql_package_name } + default: { fail("Unsupported backend: ${backend}. Only MySQL (mysql) and PostgreSQL (pgsql) are supported.") } + } + + package { $db_package: + ensure => $rsyslog::package_status, + before => File[$db_conf], + } + + file { $db_conf: + ensure => present, + owner => 'root', + group => $rsyslog::run_group, + mode => '0600', + content => template("${module_name}/database.conf.erb"), + require => Class['rsyslog::config'], + notify => Class['rsyslog::service'], + } + +} diff --git a/puppet/modules/rsyslog/manifests/imfile.pp b/puppet/modules/rsyslog/manifests/imfile.pp new file mode 100644 index 00000000..bd0afa36 --- /dev/null +++ b/puppet/modules/rsyslog/manifests/imfile.pp @@ -0,0 +1,48 @@ +# == Define: rsyslog::imfile +# +# Full description of class role here. +# +# === Parameters +# +# [*file_name*] +# [*file_tag*] +# [*file_facility*] +# [*polling_interval*] +# [*file_severity*] +# [*run_file_monitor*] +# [*persist_state_interval] +# +# === Variables +# +# === Examples +# +# rsyslog::imfile { 'my-imfile': +# file_name => '/some/file', +# file_tag => 'mytag', +# file_facility => 'myfacility', +# } +# +define rsyslog::imfile( + $file_name, + $file_tag, + $file_facility, + $polling_interval = 10, + $file_severity = 'notice', + $run_file_monitor = true, + $persist_state_interval = 0, +) { + + + include rsyslog + $extra_modules = $rsyslog::extra_modules + + file { "${rsyslog::rsyslog_d}${name}.conf": + ensure => file, + owner => 'root', + group => $rsyslog::run_group, + content => template('rsyslog/imfile.erb'), + require => Class['rsyslog::install'], + notify => Class['rsyslog::service'], + } + +} diff --git a/puppet/modules/rsyslog/manifests/init.pp b/puppet/modules/rsyslog/manifests/init.pp new file mode 100644 index 00000000..76d61023 --- /dev/null +++ b/puppet/modules/rsyslog/manifests/init.pp @@ -0,0 +1,54 @@ +# == Class: rsyslog +# +# Meta class to install rsyslog with a basic configuration. +# You probably want rsyslog::client or rsyslog::server +# +# === Parameters +# +# === Variables +# +# === Examples +# +# class { 'rsyslog': } +# +class rsyslog ( + $rsyslog_package_name = $rsyslog::params::rsyslog_package_name, + $relp_package_name = $rsyslog::params::relp_package_name, + $mysql_package_name = $rsyslog::params::mysql_package_name, + $pgsql_package_name = $rsyslog::params::pgsql_package_name, + $gnutls_package_name = $rsyslog::params::gnutls_package_name, + $package_status = $rsyslog::params::package_status, + $rsyslog_d = $rsyslog::params::rsyslog_d, + $purge_rsyslog_d = $rsyslog::params::purge_rsyslog_d, + $rsyslog_conf = $rsyslog::params::rsyslog_conf, + $rsyslog_default = $rsyslog::params::rsyslog_default, + $rsyslog_default_file = $rsyslog::params::default_config_file, + $run_user = $rsyslog::params::run_user, + $run_group = $rsyslog::params::run_group, + $log_user = $rsyslog::params::log_user, + $log_group = $rsyslog::params::log_group, + $log_style = $rsyslog::params::log_style, + $umask = $rsyslog::params::umask, + $perm_file = $rsyslog::params::perm_file, + $perm_dir = $rsyslog::params::perm_dir, + $spool_dir = $rsyslog::params::spool_dir, + $service_name = $rsyslog::params::service_name, + $service_hasrestart = $rsyslog::params::service_hasrestart, + $service_hasstatus = $rsyslog::params::service_hasstatus, + $client_conf = $rsyslog::params::client_conf, + $server_conf = $rsyslog::params::server_conf, + $ssl = $rsyslog::params::ssl, + $modules = $rsyslog::params::modules, + $preserve_fqdn = $rsyslog::params::preserve_fqdn, + $max_message_size = $rsyslog::params::max_message_size, + $extra_modules = $rsyslog::params::extra_modules +) inherits rsyslog::params { + class { 'rsyslog::install': } + class { 'rsyslog::config': } + + if $extra_modules != [] { + class { 'rsyslog::modload': } + } + + class { 'rsyslog::service': } +} diff --git a/puppet/modules/rsyslog/manifests/install.pp b/puppet/modules/rsyslog/manifests/install.pp new file mode 100644 index 00000000..9798b3f4 --- /dev/null +++ b/puppet/modules/rsyslog/manifests/install.pp @@ -0,0 +1,32 @@ +# == Class: rsyslog::install +# +# This class makes sure that the required packages are installed +# +# === Parameters +# +# === Variables +# +# === Examples +# +# class { 'rsyslog::install': } +# +class rsyslog::install { + if $rsyslog::rsyslog_package_name != false { + package { $rsyslog::rsyslog_package_name: + ensure => $rsyslog::package_status, + } + } + + if $rsyslog::relp_package_name != false { + package { $rsyslog::relp_package_name: + ensure => $rsyslog::package_status + } + } + + if $rsyslog::gnutls_package_name != false { + package { $rsyslog::gnutls_package_name: + ensure => $rsyslog::package_status + } + } + +} diff --git a/puppet/modules/rsyslog/manifests/modload.pp b/puppet/modules/rsyslog/manifests/modload.pp new file mode 100644 index 00000000..7a838af1 --- /dev/null +++ b/puppet/modules/rsyslog/manifests/modload.pp @@ -0,0 +1,15 @@ +# == Class: rsyslog::modload +# + +class rsyslog::modload ( + $modload_filename = '10-modload.conf', +) { + file { "${rsyslog::rsyslog_d}${modload_filename}": + ensure => file, + owner => 'root', + group => $rsyslog::run_group, + content => template('rsyslog/modload.erb'), + require => Class['rsyslog::install'], + notify => Class['rsyslog::service'], + } +} diff --git a/puppet/modules/rsyslog/manifests/params.pp b/puppet/modules/rsyslog/manifests/params.pp new file mode 100644 index 00000000..12a67cef --- /dev/null +++ b/puppet/modules/rsyslog/manifests/params.pp @@ -0,0 +1,222 @@ +# == Class: rsyslog::params +# +# This defines default configuration values for rsyslog. +# You don't want to use it directly. +# +# === Parameters +# +# === Variables +# +# === Examples +# +# class { 'rsyslog::params': } +# +class rsyslog::params { + + $max_message_size = '2k' + $purge_rsyslog_d = false + $extra_modules = [] + $run_user = 'root' + $log_user = 'root' + $preserve_fqdn = false + + case $::osfamily { + debian: { + $rsyslog_package_name = 'rsyslog' + $relp_package_name = 'rsyslog-relp' + $mysql_package_name = 'rsyslog-mysql' + $pgsql_package_name = 'rsyslog-pgsql' + $gnutls_package_name = 'rsyslog-gnutls' + $package_status = 'latest' + $rsyslog_d = '/etc/rsyslog.d/' + $rsyslog_conf = '/etc/rsyslog.conf' + $rsyslog_default = '/etc/default/rsyslog' + $default_config_file = 'rsyslog_default' + $run_group = 'root' + $log_group = 'adm' + $log_style = 'debian' + $umask = false + $perm_file = '0640' + $perm_dir = '0755' + $spool_dir = '/var/spool/rsyslog' + $service_name = 'rsyslog' + $client_conf = 'client' + $server_conf = 'server' + $ssl = false + $modules = [ + '$ModLoad imuxsock # provides support for local system logging', + '$ModLoad imklog # provides kernel logging support (previously done by rklogd)', + '#$ModLoad immark # provides --MARK-- message capability', + ] + $service_hasrestart = true + $service_hasstatus = true + + } + redhat: { + if $::operatingsystem == 'Amazon' { + $rsyslog_package_name = 'rsyslog' + $mysql_package_name = 'rsyslog-mysql' + $pgsql_package_name = 'rsyslog-pgsql' + $gnutls_package_name = 'rsyslog-gnutls' + $relp_package_name = false + $default_config_file = 'rsyslog_default' + $modules = [ + '$ModLoad imuxsock # provides support for local system logging', + '$ModLoad imklog # provides kernel logging support (previously done by rklogd)', + '#$ModLoad immark # provides --MARK-- message capability', + ] + } + elsif $::operatingsystemmajrelease == 6 { + $rsyslog_package_name = 'rsyslog' + $mysql_package_name = 'rsyslog-mysql' + $pgsql_package_name = 'rsyslog-pgsql' + $gnutls_package_name = 'rsyslog-gnutls' + $relp_package_name = 'rsyslog-relp' + $default_config_file = 'rsyslog_default' + $modules = [ + '$ModLoad imuxsock # provides support for local system logging', + '$ModLoad imklog # provides kernel logging support (previously done by rklogd)', + '#$ModLoad immark # provides --MARK-- message capability', + ] + } + elsif $::operatingsystemmajrelease >= 7 { + $rsyslog_package_name = 'rsyslog' + $mysql_package_name = 'rsyslog-mysql' + $pgsql_package_name = 'rsyslog-pgsql' + $gnutls_package_name = 'rsyslog-gnutls' + $relp_package_name = 'rsyslog-relp' + $default_config_file = 'rsyslog_default_rhel7' + $modules = [ + '$ModLoad imuxsock # provides support for local system logging', + '$ModLoad imjournal # provides access to the systemd journal', + '#$ModLoad imklog # provides kernel logging support (previously done by rklogd)', + '#$ModLoad immark # provides --MARK-- message capability', + ] + } else { + $rsyslog_package_name = 'rsyslog5' + $mysql_package_name = 'rsyslog5-mysql' + $pgsql_package_name = 'rsyslog5-pgsql' + $gnutls_package_name = 'rsyslog5-gnutls' + $relp_package_name = 'librelp' + $default_config_file = 'rsyslog_default' + $modules = [ + '$ModLoad imuxsock # provides support for local system logging', + '$ModLoad imklog # provides kernel logging support (previously done by rklogd)', + '#$ModLoad immark # provides --MARK-- message capability', + ] + } + $package_status = 'latest' + $rsyslog_d = '/etc/rsyslog.d/' + $rsyslog_conf = '/etc/rsyslog.conf' + $rsyslog_default = '/etc/sysconfig/rsyslog' + $run_group = 'root' + $log_group = 'root' + $log_style = 'redhat' + $umask = '0000' + $perm_file = '0600' + $perm_dir = '0750' + $spool_dir = '/var/lib/rsyslog' + $service_name = 'rsyslog' + $client_conf = 'client' + $server_conf = 'server' + $ssl = false + $service_hasrestart = true + $service_hasstatus = true + } + suse: { + $rsyslog_package_name = 'rsyslog' + $relp_package_name = false + $mysql_package_name = false + $pgsql_package_name = false + $gnutls_package_name = false + $package_status = 'latest' + $rsyslog_d = '/etc/rsyslog.d/' + $rsyslog_conf = '/etc/rsyslog.conf' + $rsyslog_default = '/etc/sysconfig/syslog' + $run_group = 'root' + $log_group = 'root' + $log_style = 'debian' + $umask = false + $perm_file = '0600' + $perm_dir = '0750' + $spool_dir = '/var/spool/rsyslog/' + $service_name = 'syslog' + $client_conf = 'client' + $server_conf = 'server' + $modules = [ + '$ModLoad imuxsock # provides support for local system logging', + '$ModLoad imklog # provides kernel logging support (previously done by rklogd)', + '#$ModLoad immark # provides --MARK-- message capability', + ] + } + freebsd: { + $rsyslog_package_name = 'sysutils/rsyslog5' + $relp_package_name = 'sysutils/rsyslog5-relp' + $mysql_package_name = 'sysutils/rsyslog5-mysql' + $pgsql_package_name = 'sysutils/rsyslog5-pgsql' + $gnutls_package_name = 'sysutils/rsyslog5-gnutls' + $package_status = 'present' + $rsyslog_d = '/etc/syslog.d/' + $rsyslog_conf = '/etc/syslog.conf' + $rsyslog_default = '/etc/defaults/syslogd' + $default_config_file = 'rsyslog_default' + $run_group = 'wheel' + $log_group = 'wheel' + $log_style = 'debian' + $umask = false + $perm_file = '0640' + $perm_dir = '0755' + $spool_dir = '/var/spool/syslog' + $service_name = 'syslogd' + $client_conf = 'client' + $server_conf = 'server' + $ssl = false + $modules = [ + '$ModLoad imuxsock # provides support for local system logging', + '$ModLoad imklog # provides kernel logging support (previously done by rklogd)', + '#$ModLoad immark # provides --MARK-- message capability', + ] + $service_hasrestart = true + $service_hasstatus = true + } + + default: { + case $::operatingsystem { + gentoo: { + $rsyslog_package_name = 'app-admin/rsyslog' + $relp_package_name = false + $mysql_package_name = 'rsyslog-mysql' + $pgsql_package_name = 'rsyslog-pgsql' + $gnutls_package_name = false + $package_status = 'latest' + $rsyslog_d = '/etc/rsyslog.d/' + $rsyslog_conf = '/etc/rsyslog.conf' + $rsyslog_default = '/etc/conf.d/rsyslog' + $default_config_file = 'rsyslog_default_gentoo' + $run_group = 'root' + $log_group = 'adm' + $log_style = 'debian' + $umask = false + $perm_file = '0640' + $perm_dir = '0755' + $spool_dir = '/var/spool/rsyslog' + $service_name = 'rsyslog' + $client_conf = 'client' + $server_conf = 'server' + $ssl = false + $modules = [ + '$ModLoad imuxsock # provides support for local system logging', + '$ModLoad imklog # provides kernel logging support (previously done by rklogd)', + '#$ModLoad immark # provides --MARK-- message capability', + ] + $service_hasrestart = true + $service_hasstatus = true + + } + default: { + fail("The ${module_name} module is not supported on ${::osfamily}/${::operatingsystem}.") + } + } + } + } +} diff --git a/puppet/modules/rsyslog/manifests/server.pp b/puppet/modules/rsyslog/manifests/server.pp new file mode 100644 index 00000000..13ee56de --- /dev/null +++ b/puppet/modules/rsyslog/manifests/server.pp @@ -0,0 +1,70 @@ +# == Class: rsyslog::server +# +# This class configures rsyslog for a server role. +# +# === Parameters +# +# [*enable_tcp*] +# [*enable_udp*] +# [*enable_onefile*] +# [*server_dir*] +# [*custom_config*] +# [*high_precision_timestamps*] +# [*ssl_ca*] +# [*ssl_cert*] +# [*ssl_key*] +# +# === Variables +# +# === Examples +# +# Defaults +# +# class { 'rsyslog::server': } +# +# Create seperate directory per host +# +# class { 'rsyslog::server': +# custom_config => 'rsyslog/server-hostname.conf.erb' +# } +# +class rsyslog::server ( + $enable_tcp = true, + $enable_udp = true, + $enable_onefile = false, + $server_dir = '/srv/log/', + $custom_config = undef, + $port = '514', + $high_precision_timestamps = false, + $ssl_ca = undef, + $ssl_cert = undef, + $ssl_key = undef, + $rotate = undef +) inherits rsyslog { + + ### Logrotate policy + $logpath = $rotate ? { + 'year' => '/%$YEAR%/', + 'YEAR' => '/%$YEAR%/', + 'month' => '/%$YEAR%/%$MONTH%/', + 'MONTH' => '/%$YEAR%/%$MONTH%/', + 'day' => '/%$YEAR%/%$MONTH%/%$DAY%/', + 'DAY' => '/%$YEAR%/%$MONTH%/%$DAY%/', + default => '/', + } + + if $custom_config { + $real_content = template($custom_config) + } else { + $real_content = template("${module_name}/server-default.conf.erb") + } + + rsyslog::snippet { $rsyslog::server_conf: + ensure => present, + content => $real_content, + } + + if $rsyslog::ssl and (!$enable_tcp or $ssl_ca == undef or $ssl_cert == undef or $ssl_key == undef) { + fail('You need to define all the ssl options and enable tcp in order to use SSL.') + } +} diff --git a/puppet/modules/rsyslog/manifests/service.pp b/puppet/modules/rsyslog/manifests/service.pp new file mode 100644 index 00000000..4be19999 --- /dev/null +++ b/puppet/modules/rsyslog/manifests/service.pp @@ -0,0 +1,21 @@ +# == Class: rsyslog::service +# +# This class enforces running of the rsyslog service. +# +# === Parameters +# +# === Variables +# +# === Examples +# +# class { 'rsyslog::service': } +# +class rsyslog::service { + service { $rsyslog::service_name: + ensure => running, + enable => true, + hasstatus => $rsyslog::service_hasstatus, + hasrestart => $rsyslog::service_hasrestart, + require => Class['rsyslog::config'], + } +} diff --git a/puppet/modules/rsyslog/manifests/snippet.pp b/puppet/modules/rsyslog/manifests/snippet.pp new file mode 100644 index 00000000..f6383963 --- /dev/null +++ b/puppet/modules/rsyslog/manifests/snippet.pp @@ -0,0 +1,35 @@ +# == Define: rsyslog::snippet +# +# This class allows for you to create a rsyslog configuration file with +# whatever content you pass in. +# +# === Parameters +# +# [*content*] - The actual content to place in the file. +# [*ensure*] - How to enforce the file (default: present) +# +# === Variables +# +# === Examples +# +# rsyslog::snippet { 'my-rsyslog-config': +# content => '', +# } +# +define rsyslog::snippet( + $content, + $ensure = 'present' +) { + + include rsyslog + + file { "${rsyslog::rsyslog_d}${name}.conf": + ensure => $ensure, + owner => $rsyslog::run_user, + group => $rsyslog::run_group, + content => "# This file is managed by Puppet, changes may be overwritten\n${content}\n", + require => Class['rsyslog::config'], + notify => Class['rsyslog::service'], + } + +} diff --git a/puppet/modules/rsyslog/metadata.json b/puppet/modules/rsyslog/metadata.json new file mode 100644 index 00000000..c9338eef --- /dev/null +++ b/puppet/modules/rsyslog/metadata.json @@ -0,0 +1,62 @@ +{ + "name": "saz-rsyslog", + "version": "3.4.0", + "author": "saz", + "summary": "Manage rsyslog client and server", + "license": "Apache License, Version 2.0", + "source": "https://github.com/saz/puppet-rsyslog.git", + "project_page": "https://github.com/saz/puppet-rsyslog", + "issues_url": "https://github.com/saz/puppet-rsyslog/issues", + "operatingsystem_support": [ + { + "operatingsystem": "RedHat" + }, + { + "operatingsystem": "Amazon" + }, + { + "operatingsystem": "CentOS" + }, + { + "operatingsystem": "SuSe" + }, + { + "operatingsystem": "SLES" + }, + { + "operatingsystem": "OracleLinux" + }, + { + "operatingsystem": "Scientific" + }, + { + "operatingsystem": "Debian" + }, + { + "operatingsystem": "Ubuntu" + }, + { + "operatingsystem": "FreeBSD" + }, + { + "operatingsystem": "Gentoo" + } + ], + "requirements": [ + { + "name": "pe", + "version_requirement": ">= 3.2.0 < 3.4.0" + }, + { + "name": "puppet", + "version_requirement": "3.x" + } + ], + "description": "Manage rsyslog client and server via Puppet", + "types": [ + + ], + "dependencies": [ + + ] +} diff --git a/puppet/modules/rsyslog/spec/classes/rsyslog_client_spec.rb b/puppet/modules/rsyslog/spec/classes/rsyslog_client_spec.rb new file mode 100644 index 00000000..82865db9 --- /dev/null +++ b/puppet/modules/rsyslog/spec/classes/rsyslog_client_spec.rb @@ -0,0 +1,146 @@ +require 'spec_helper' + +describe 'rsyslog::client', :type => :class do + + context "Rsyslog version >= 8" do + let(:default_facts) do + { + :rsyslog_version => '8.1.2' + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-client-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/client.conf') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-client-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/client.conf') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-client-basic' } + + it 'should compile' do + should contain_file('/etc/syslog.d/client.conf') + end + end + end + end + + context "Rsyslog version =< 8" do + let(:default_facts) do + { + :rsyslog_version => '7.1.2' + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-client-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/client.conf') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-client-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/client.conf') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-client-basic' } + + it 'should compile' do + should contain_file('/etc/syslog.d/client.conf') + end + end + end + end + + context "Rsyslog version = nil" do + let(:default_facts) do + { + :rsyslog_version => nil + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-client-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/client.conf') + end + end + end + end +end diff --git a/puppet/modules/rsyslog/spec/classes/rsyslog_database_spec.rb b/puppet/modules/rsyslog/spec/classes/rsyslog_database_spec.rb new file mode 100644 index 00000000..0421135a --- /dev/null +++ b/puppet/modules/rsyslog/spec/classes/rsyslog_database_spec.rb @@ -0,0 +1,308 @@ +require 'spec_helper' + +describe 'rsyslog::database', :type => :class do + + context "Rsyslog version >= 8" do + let(:default_facts) do + { + :rsyslog_version => '8.1.2' + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage mysql (osfamily = RedHat)" do + let(:title) { 'rsyslog-database-mysql' } + + let (:params) { + { + 'backend' => 'mysql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('rsyslog-mysql') + should contain_file('/etc/rsyslog.d/mysql.conf') + end + end + + context "default usage pgsql (osfamily = RedHat)" do + let(:title) { 'rsyslog-database-pgsql' } + + let (:params) { + { + 'backend' => 'pgsql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('rsyslog-pgsql') + should contain_file('/etc/rsyslog.d/pgsql.conf') + end + end + end + + + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage mysql (osfamily = Debian)" do + let(:title) { 'rsyslog-database-mysql' } + + let (:params) { + { + 'backend' => 'mysql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('rsyslog-mysql') + should contain_file('/etc/rsyslog.d/mysql.conf') + end + end + + context "default usage pgsql (osfamily = Debian)" do + let(:title) { 'rsyslog-database-pgsql' } + + let (:params) { + { + 'backend' => 'pgsql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('rsyslog-pgsql') + should contain_file('/etc/rsyslog.d/pgsql.conf') + end + end + end + + + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage mysql (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-database-mysql' } + + let (:params) { + { + 'backend' => 'mysql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('sysutils/rsyslog5-mysql') + should contain_file('/etc/syslog.d/mysql.conf') + end + end + + context "default usage pgsql (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-database-pgsql' } + + let (:params) { + { + 'backend' => 'pgsql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('sysutils/rsyslog5-pgsql') + should contain_file('/etc/syslog.d/pgsql.conf') + end + end + end + end + + context "Rsyslog version =< 8" do + let(:default_facts) do + { + :rsyslog_version => '7.1.2' + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage mysql (osfamily = RedHat)" do + let(:title) { 'rsyslog-database-mysql' } + + let (:params) { + { + 'backend' => 'mysql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('rsyslog-mysql') + should contain_file('/etc/rsyslog.d/mysql.conf') + end + end + + context "default usage pgsql (osfamily = RedHat)" do + let(:title) { 'rsyslog-database-pgsql' } + + let (:params) { + { + 'backend' => 'pgsql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('rsyslog-pgsql') + should contain_file('/etc/rsyslog.d/pgsql.conf') + end + end + end + + + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage mysql (osfamily = Debian)" do + let(:title) { 'rsyslog-database-mysql' } + + let (:params) { + { + 'backend' => 'mysql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('rsyslog-mysql') + should contain_file('/etc/rsyslog.d/mysql.conf') + end + end + + context "default usage pgsql (osfamily = Debian)" do + let(:title) { 'rsyslog-database-pgsql' } + + let (:params) { + { + 'backend' => 'pgsql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('rsyslog-pgsql') + should contain_file('/etc/rsyslog.d/pgsql.conf') + end + end + end + + + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage mysql (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-database-mysql' } + + let (:params) { + { + 'backend' => 'mysql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('sysutils/rsyslog5-mysql') + should contain_file('/etc/syslog.d/mysql.conf') + end + end + + context "default usage pgsql (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-database-pgsql' } + + let (:params) { + { + 'backend' => 'pgsql', + 'server' => 'localhost', + 'database' => 'rsyslog', + 'username' => 'us3rname', + 'password' => 'passw0rd', + } + } + + it 'should compile' do + should contain_package('sysutils/rsyslog5-pgsql') + should contain_file('/etc/syslog.d/pgsql.conf') + end + end + end + end +end diff --git a/puppet/modules/rsyslog/spec/classes/rsyslog_server_spec.rb b/puppet/modules/rsyslog/spec/classes/rsyslog_server_spec.rb new file mode 100644 index 00000000..8f57656b --- /dev/null +++ b/puppet/modules/rsyslog/spec/classes/rsyslog_server_spec.rb @@ -0,0 +1,182 @@ +require 'spec_helper' + +describe 'rsyslog::server', :type => :class do + + context "Rsyslog version >= 8" do + let(:default_facts) do + { + :rsyslog_version => '8.1.2' + } + end + + ['RedHat', 'Debian'].each do |osfamily| + context "osfamily = #{osfamily}" do + let :facts do + default_facts.merge!({ + :osfamily => osfamily, + :operatingsystem => osfamily, + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = #{osfamily})" do + let(:title) { 'rsyslog-server-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/auth.log/) + should contain_file('/etc/rsyslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/messages/) + end + end + + context "enable_onefile (osfamily = #{osfamily})" do + let(:title) { 'rsyslog-server-onefile' } + let(:params) { {'enable_onefile' => 'true'} } + + it 'should compile' do + should_not contain_file('/etc/rsyslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/auth.log/) + should contain_file('/etc/rsyslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/messages/) + end + end + + context "hostname_template (osfamily = #{osfamily})" do + let(:title) { 'rsyslog-server-onefile' } + let(:params) { {'custom_config' => 'rsyslog/server-hostname.conf.erb'} } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/server.conf').with_content(/%hostname%\/auth.log/) + should contain_file('/etc/rsyslog.d/server.conf').with_content(/%hostname%\/messages/) + end + end + + end + end + + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-server-basic' } + + it 'should compile' do + should contain_file('/etc/syslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/auth.log/) + should contain_file('/etc/syslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/messages/) + end + end + + context "enable_onefile (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-server-onefile' } + let(:params) { {'enable_onefile' => 'true'} } + + it 'should compile' do + should_not contain_file('/etc/syslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/auth.log/) + should contain_file('/etc/syslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/messages/) + end + end + + context "hostname_template (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-server-onefile' } + let(:params) { {'custom_config' => 'rsyslog/server-hostname.conf.erb'} } + + it 'should compile' do + should contain_file('/etc/syslog.d/server.conf').with_content(/%hostname%\/auth.log/) + should contain_file('/etc/syslog.d/server.conf').with_content(/%hostname%\/messages/) + end + end + + end + end + + context "Rsyslog version =< 8" do + let(:default_facts) do + { + :rsyslog_version => '7.1.2' + } + end + + ['RedHat', 'Debian'].each do |osfamily| + context "osfamily = #{osfamily}" do + let :facts do + default_facts.merge!({ + :osfamily => osfamily, + :operatingsystem => osfamily, + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = #{osfamily})" do + let(:title) { 'rsyslog-server-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/auth.log/) + should contain_file('/etc/rsyslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/messages/) + end + end + + context "enable_onefile (osfamily = #{osfamily})" do + let(:title) { 'rsyslog-server-onefile' } + let(:params) { {'enable_onefile' => 'true'} } + + it 'should compile' do + should_not contain_file('/etc/rsyslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/auth.log/) + should contain_file('/etc/rsyslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/messages/) + end + end + + context "hostname_template (osfamily = #{osfamily})" do + let(:title) { 'rsyslog-server-onefile' } + let(:params) { {'custom_config' => 'rsyslog/server-hostname.conf.erb'} } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/server.conf').with_content(/%hostname%\/auth.log/) + should contain_file('/etc/rsyslog.d/server.conf').with_content(/%hostname%\/messages/) + end + end + + end + end + + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-server-basic' } + + it 'should compile' do + should contain_file('/etc/syslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/auth.log/) + should contain_file('/etc/syslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/messages/) + end + end + + context "enable_onefile (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-server-onefile' } + let(:params) { {'enable_onefile' => 'true'} } + + it 'should compile' do + should_not contain_file('/etc/syslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/auth.log/) + should contain_file('/etc/syslog.d/server.conf').with_content(/\(\[A-Za-z-\]\*\)--end%\/messages/) + end + end + + context "hostname_template (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-server-onefile' } + let(:params) { {'custom_config' => 'rsyslog/server-hostname.conf.erb'} } + + it 'should compile' do + should contain_file('/etc/syslog.d/server.conf').with_content(/%hostname%\/auth.log/) + should contain_file('/etc/syslog.d/server.conf').with_content(/%hostname%\/messages/) + end + end + + end + end +end # describe 'rsyslog::server' diff --git a/puppet/modules/rsyslog/spec/classes/rsyslog_spec.rb b/puppet/modules/rsyslog/spec/classes/rsyslog_spec.rb new file mode 100644 index 00000000..344d7174 --- /dev/null +++ b/puppet/modules/rsyslog/spec/classes/rsyslog_spec.rb @@ -0,0 +1,469 @@ +require 'spec_helper' + +describe 'rsyslog', :type => :class do + + context "Rsyslog version >= 8" do + let(:default_facts) do + { + :rsyslog_version => '8.1.2' + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_class('rsyslog::install') + should contain_class('rsyslog::config') + should contain_class('rsyslog::service') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_class('rsyslog::install') + should contain_class('rsyslog::config') + should contain_class('rsyslog::service') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_class('rsyslog::install') + should contain_class('rsyslog::config') + should contain_class('rsyslog::service') + end + end + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.conf') + should contain_file('/etc/rsyslog.d/') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.conf') + should contain_file('/etc/rsyslog.d/') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_file('/etc/syslog.conf') + should contain_file('/etc/syslog.d/') + end + end + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-install-basic' } + + it 'should compile' do + should contain_package('rsyslog') + should contain_package('rsyslog-relp') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-install-basic' } + + it 'should compile' do + should contain_package('rsyslog') + should contain_package('rsyslog-relp') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-install-basic' } + + it 'should compile' do + should contain_package('sysutils/rsyslog5') + should contain_package('sysutils/rsyslog5-relp') + end + end + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-service-basic' } + + it 'should compile' do + should contain_service('rsyslog') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-service-basic' } + + it 'should compile' do + should contain_service('rsyslog') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-service-basic' } + + it 'should compile' do + should contain_service('syslogd') + end + end + end + end + + context "Rsyslog version =< 8" do + let(:default_facts) do + { + :rsyslog_version => '7.1.2' + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_class('rsyslog::install') + should contain_class('rsyslog::config') + should contain_class('rsyslog::service') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_class('rsyslog::install') + should contain_class('rsyslog::config') + should contain_class('rsyslog::service') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = FreeBSD)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_class('rsyslog::install') + should contain_class('rsyslog::config') + should contain_class('rsyslog::service') + end + end + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.conf') + should contain_file('/etc/rsyslog.d/') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.conf') + should contain_file('/etc/rsyslog.d/') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-basic' } + + it 'should compile' do + should contain_file('/etc/syslog.conf') + should contain_file('/etc/syslog.d/') + end + end + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-install-basic' } + + it 'should compile' do + should contain_package('rsyslog') + should contain_package('rsyslog-relp') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-install-basic' } + + it 'should compile' do + should contain_package('rsyslog') + should contain_package('rsyslog-relp') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-install-basic' } + + it 'should compile' do + should contain_package('sysutils/rsyslog5') + should contain_package('sysutils/rsyslog5-relp') + end + end + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-service-basic' } + + it 'should compile' do + should contain_service('rsyslog') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-service-basic' } + + it 'should compile' do + should contain_service('rsyslog') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-service-basic' } + + it 'should compile' do + should contain_service('syslogd') + end + end + end + end + + context "Rsyslog version >= 8" do + let(:default_facts) do + { + :rsyslog_version => nil + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + context "default usage (osfamily = RedHat)" do + it 'should compile' do + should contain_file('/etc/rsyslog.conf') + should contain_file('/etc/rsyslog.d/') + end + end + end + end +end diff --git a/puppet/modules/rsyslog/spec/defines/rsyslog_imfile_spec.rb b/puppet/modules/rsyslog/spec/defines/rsyslog_imfile_spec.rb new file mode 100644 index 00000000..1c505eb7 --- /dev/null +++ b/puppet/modules/rsyslog/spec/defines/rsyslog_imfile_spec.rb @@ -0,0 +1,169 @@ +require 'spec_helper' + +describe 'rsyslog::imfile', :type => :define do + + context "Rsyslog version >= 8" do + let(:default_facts) do + { + :rsyslog_version => '8.1.2' + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + let (:params) { + { + 'file_name' => 'mylogfile', + 'file_tag' => 'mytag', + 'file_facility' => 'myfacility', + } + } + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-imfile-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/rsyslog-imfile-basic.conf') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + let (:params) { + { + 'file_name' => 'mylogfile', + 'file_tag' => 'mytag', + 'file_facility' => 'myfacility', + } + } + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-imfile-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/rsyslog-imfile-basic.conf') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + let (:params) { + { + 'file_name' => 'mylogfile', + 'file_tag' => 'mytag', + 'file_facility' => 'myfacility', + } + } + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-imfile-basic' } + + it 'should compile' do + should contain_file('/etc/syslog.d/rsyslog-imfile-basic.conf') + end + end + end + end + + context "Rsyslog version =< 8" do + let(:default_facts) do + { + :rsyslog_version => '7.1.2' + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemmajrelease => 6, + }) + end + + let (:params) { + { + 'file_name' => 'mylogfile', + 'file_tag' => 'mytag', + 'file_facility' => 'myfacility', + } + } + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-imfile-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/rsyslog-imfile-basic.conf') + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + let (:params) { + { + 'file_name' => 'mylogfile', + 'file_tag' => 'mytag', + 'file_facility' => 'myfacility', + } + } + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-imfile-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/rsyslog-imfile-basic.conf') + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + let (:params) { + { + 'file_name' => 'mylogfile', + 'file_tag' => 'mytag', + 'file_facility' => 'myfacility', + } + } + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-imfile-basic' } + + it 'should compile' do + should contain_file('/etc/syslog.d/rsyslog-imfile-basic.conf') + end + end + end + end + +end diff --git a/puppet/modules/rsyslog/spec/defines/rsyslog_snippet_spec.rb b/puppet/modules/rsyslog/spec/defines/rsyslog_snippet_spec.rb new file mode 100644 index 00000000..6cc68839 --- /dev/null +++ b/puppet/modules/rsyslog/spec/defines/rsyslog_snippet_spec.rb @@ -0,0 +1,157 @@ +require 'spec_helper' + +describe 'rsyslog::snippet', :type => :define do + + context "Rsyslog version >= 8" do + let(:default_facts) do + { + :rsyslog_version => '8.1.2' + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'Redhat', + :operatingsystemmajrelease => 6, + }) + end + + let (:params) { + { + 'content' => 'Random Content', + } + } + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-snippet-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/rsyslog-snippet-basic.conf').with_content("# This file is managed by Puppet, changes may be overwritten\nRandom Content\n") + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + let (:params) { + { + 'content' => 'Random Content', + } + } + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-snippet-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/rsyslog-snippet-basic.conf').with_content("# This file is managed by Puppet, changes may be overwritten\nRandom Content\n") + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + let (:params) { + { + 'content' => 'Random Content', + } + } + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-snippet-basic' } + + it 'should compile' do + should contain_file('/etc/syslog.d/rsyslog-snippet-basic.conf').with_content("# This file is managed by Puppet, changes may be overwritten\nRandom Content\n") + end + end + end + end + + context "Rsyslog version =< 8" do + let(:default_facts) do + { + :rsyslog_version => '7.1.2' + } + end + + context "osfamily = RedHat" do + let :facts do + default_facts.merge!({ + :osfamily => 'RedHat', + :operatingsystem => 'Redhat', + :operatingsystemmajrelease => 6, + }) + end + + let (:params) { + { + 'content' => 'Random Content', + } + } + + context "default usage (osfamily = RedHat)" do + let(:title) { 'rsyslog-snippet-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/rsyslog-snippet-basic.conf').with_content("# This file is managed by Puppet, changes may be overwritten\nRandom Content\n") + end + end + end + + context "osfamily = Debian" do + let :facts do + default_facts.merge!({ + :osfamily => 'Debian', + }) + end + + let (:params) { + { + 'content' => 'Random Content', + } + } + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-snippet-basic' } + + it 'should compile' do + should contain_file('/etc/rsyslog.d/rsyslog-snippet-basic.conf').with_content("# This file is managed by Puppet, changes may be overwritten\nRandom Content\n") + end + end + end + + context "osfamily = FreeBSD" do + let :facts do + default_facts.merge!({ + :osfamily => 'freebsd', + }) + end + + let (:params) { + { + 'content' => 'Random Content', + } + } + + context "default usage (osfamily = Debian)" do + let(:title) { 'rsyslog-snippet-basic' } + + it 'should compile' do + should contain_file('/etc/syslog.d/rsyslog-snippet-basic.conf').with_content("# This file is managed by Puppet, changes may be overwritten\nRandom Content\n") + end + end + end + end + +end diff --git a/puppet/modules/rsyslog/spec/spec.opts b/puppet/modules/rsyslog/spec/spec.opts new file mode 100644 index 00000000..91cd6427 --- /dev/null +++ b/puppet/modules/rsyslog/spec/spec.opts @@ -0,0 +1,6 @@ +--format +s +--colour +--loadby +mtime +--backtrace diff --git a/puppet/modules/rsyslog/spec/spec_helper.rb b/puppet/modules/rsyslog/spec/spec_helper.rb new file mode 100644 index 00000000..12bb0b7f --- /dev/null +++ b/puppet/modules/rsyslog/spec/spec_helper.rb @@ -0,0 +1,28 @@ +require 'puppetlabs_spec_helper/module_spec_helper' + +RSpec.configure do |c| + c.mock_with :rspec do |mock| + mock.syntax = [:expect, :should] + end + c.include PuppetlabsSpec::Files + + c.before :each do + # Ensure that we don't accidentally cache facts and environment + # between test cases. + Facter::Util::Loader.any_instance.stubs(:load_all) + Facter.clear + Facter.clear_messages + + # Store any environment variables away to be restored later + @old_env = {} + ENV.each_key {|k| @old_env[k] = ENV[k]} + + if Gem::Version.new(`puppet --version`) >= Gem::Version.new('3.5') + Puppet.settings[:strict_variables]=true + end + end + + c.after :each do + PuppetlabsSpec::Files.cleanup + end +end diff --git a/puppet/modules/rsyslog/templates/client.conf.erb b/puppet/modules/rsyslog/templates/client.conf.erb new file mode 100644 index 00000000..c05ae797 --- /dev/null +++ b/puppet/modules/rsyslog/templates/client.conf.erb @@ -0,0 +1,180 @@ + +# An "In-Memory Queue" is created for remote logging. +$WorkDirectory <%= scope.lookupvar('rsyslog::spool_dir') -%> # where to place spool files +$ActionQueueFileName queue # unique name prefix for spool files +$ActionQueueMaxDiskSpace <%= scope.lookupvar('rsyslog::client::spool_size') -%> # spool space limit (use as much as possible) +$ActionQueueSaveOnShutdown on # save messages to disk on shutdown +$ActionQueueType LinkedList # run asynchronously +$ActionResumeRetryCount -1 # infinety retries if host is down +<% if scope.lookupvar('rsyslog::client::log_templates') and ! scope.lookupvar('rsyslog::client::log_templates').empty?-%> + +# Define custom logging templates +<% scope.lookupvar('rsyslog::client::log_templates').flatten.compact.each do |log_template| -%> +$template <%= log_template['name'] %>,"<%= log_template['template'] %>" +<% end -%> +<% end -%> +<% if scope.lookupvar('rsyslog::client::actionfiletemplate') -%> + +# Using specified format for default logging format: +$ActionFileDefaultTemplate <%= scope.lookupvar('rsyslog::client::actionfiletemplate') %> +<% else -%> + +#Using default format for default logging format: +$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat +<% end -%> +<% if scope.lookupvar('rsyslog::client::ssl') -%> + +# Setup SSL connection. +# CA/Cert +$DefaultNetStreamDriverCAFile <%= scope.lookupvar('rsyslog::client::ssl_ca') %> + +# Connection settings. +$DefaultNetstreamDriver gtls +$ActionSendStreamDriverMode 1 +$ActionSendStreamDriverAuthMode anon +<% end -%> +<% if scope.lookupvar('rsyslog::client::remote_servers') -%> + +<% scope.lookupvar('rsyslog::client::remote_servers').flatten.compact.each do |server| -%> +<% if server['pattern'] and server['pattern'] != ''-%> +<% pattern = server['pattern'] -%> +<% else -%> +<% pattern = '*.*' -%> +<% end -%> +<% if server['protocol'] == 'TCP' or server['protocol'] == 'tcp'-%> +<% protocol = '@@' -%> +<% protocol_type = 'TCP' -%> +<% else -%> +<% protocol = '@' -%> +<% protocol_type = 'UDP' -%> +<% end -%> +<% if server['host'] and server['host'] != ''-%> +<% host = server['host'] -%> +<% else -%> +<% host = 'localhost' -%> +<% end -%> +<% if server['port'] and server['port'] != ''-%> +<% port = server['port'] -%> +<% else -%> +<% port = '514' -%> +<% end -%> +<% if server['format'] -%> +<% format = ";#{server['format']}" -%> +<% format_type = server['format'] -%> +<% else -%> +<% format = '' -%> +<% format_type = 'the default' -%> +<% end -%> +# Sending logs that match <%= pattern %> to <%= host %> via <%= protocol_type %> on <%= port %> using <%=format_type %> format. +<%= pattern %> <%= protocol %><%= host %>:<%= port %><%= format %> +<% end -%> +<% elsif scope.lookupvar('rsyslog::client::log_remote') -%> + +# Log to remote syslog server using <%= scope.lookupvar('rsyslog::client::remote_type') %> +<% if scope.lookupvar('rsyslog::client::remote_type') == 'tcp' -%> +*.* @@<%= scope.lookupvar('rsyslog::client::server') -%>:<%= scope.lookupvar('rsyslog::client::port') -%>;<%= scope.lookupvar('remote_forward_format') -%> +<% else -%> +*.* @<%= scope.lookupvar('rsyslog::client::server') -%>:<%= scope.lookupvar('rsyslog::client::port') -%>;<%= scope.lookupvar('remote_forward_format') -%> +<% end -%> +<% end -%> +<% if scope.lookupvar('rsyslog::client::log_auth_local') or scope.lookupvar('rsyslog::client::log_local') -%> + +# Logging locally. + +<% if scope.lookupvar('rsyslog::log_style') == 'debian' -%> +# Log auth messages locally +auth,authpriv.* /var/log/auth.log +<% elsif scope.lookupvar('rsyslog::log_style') == 'redhat' -%> +# Log auth messages locally +auth,authpriv.* /var/log/secure +<% end -%> +<% end -%> +<% if scope.lookupvar('rsyslog::client::log_local') -%> +<% if scope.lookupvar('rsyslog::log_style') == 'debian' -%> +# First some standard log files. Log by facility. +# +*.*;auth,authpriv.none -/var/log/syslog +cron.* /var/log/cron.log +daemon.* -/var/log/daemon.log +kern.* -/var/log/kern.log +#lpr.* -/var/log/lpr.log +mail.* -/var/log/mail.log +user.* -/var/log/user.log + +# +# Logging for the mail system. Split it up so that +# it is easy to write scripts to parse these files. +# +mail.info -/var/log/mail.info +mail.warn -/var/log/mail.warn +mail.err /var/log/mail.err + +# +# Logging for INN news system. +# +news.crit /var/log/news/news.crit +news.err /var/log/news/news.err +news.notice -/var/log/news/news.notice + +# +# Some "catch-all" log files. +# +*.=debug;\ + auth,authpriv.none;\ + news.none;mail.none -/var/log/debug +*.=info;*.=notice;*.=warn;\ + auth,authpriv.none;\ + cron,daemon.none;\ + mail,news.none -/var/log/messages + +# +# I like to have messages displayed on the console, but only on a virtual +# console I usually leave idle. +# +#daemon,mail.*;\ +# news.=crit;news.=err;news.=notice;\ +# *.=debug;*.=info;\ +# *.=notice;*.=warn /dev/tty8 + +# The named pipe /dev/xconsole is for the `xconsole' utility. To use it, +# you must invoke `xconsole' with the `-file' option: +# +# $ xconsole -file /dev/xconsole [...] +# +# NOTE: adjust the list below, or you'll go crazy if you have a reasonably +# busy site.. +# +daemon.*;mail.*;\ + news.err;\ + *.=debug;*.=info;\ + *.=notice;*.=warn |/dev/xconsole +<% elsif scope.lookupvar('rsyslog::log_style') == 'redhat' -%> +# Log all kernel messages to the console. +# Logging much else clutters up the screen. +#kern.* /dev/console + +# Log anything (except mail) of level info or higher. +# Don't log private authentication messages! +*.info;mail.none;authpriv.none;cron.none /var/log/messages + +# Log all the mail messages in one place. +mail.* -/var/log/maillog + + +# Log cron stuff +cron.* /var/log/cron + +# Everybody gets emergency messages +<% if @rsyslog_version and @rsyslog_version.split('.')[0].to_i >= 8 -%> +*.emerg :omusrmsg:* +<% else -%> +*.emerg * +<% end -%> + +# Save news errors of level crit and higher in a special file. +uucp,news.crit -/var/log/spooler + +# Save boot messages also to boot.log +local7.* -/var/log/boot.log +<% end -%> +<% end -%> diff --git a/puppet/modules/rsyslog/templates/database.conf.erb b/puppet/modules/rsyslog/templates/database.conf.erb new file mode 100644 index 00000000..3934d6cf --- /dev/null +++ b/puppet/modules/rsyslog/templates/database.conf.erb @@ -0,0 +1,6 @@ +# File is managed by Puppet + +## Configuration file for rsyslog-<%= @backend %> + +$ModLoad <%= @db_module %> +*.* :<%= @db_module -%>:<%= @server -%>,<%= @database -%>,<%= @username -%>,<%= @password %> diff --git a/puppet/modules/rsyslog/templates/imfile.erb b/puppet/modules/rsyslog/templates/imfile.erb new file mode 100644 index 00000000..4a11c728 --- /dev/null +++ b/puppet/modules/rsyslog/templates/imfile.erb @@ -0,0 +1,15 @@ +<% if @extra_modules.empty?() or !@extra_modules.include?('imfile') -%> +$ModLoad imfile +<% end -%> + + +$InputFileName <%= @file_name %> +$InputFileTag <%= @file_tag %> +$InputFileStateFile state-<%= @name %> +$InputFileSeverity <%= @file_severity %> +$InputFileFacility <%= @file_facility %> +$InputFilePollInterval <%= @polling_interval %> +$InputFilePersistStateInterval <%= @persist_state_interval %> +<% if @run_file_monitor == true -%> +$InputRunFileMonitor +<% end -%> diff --git a/puppet/modules/rsyslog/templates/modload.erb b/puppet/modules/rsyslog/templates/modload.erb new file mode 100644 index 00000000..a14a612a --- /dev/null +++ b/puppet/modules/rsyslog/templates/modload.erb @@ -0,0 +1,3 @@ +<% @extra_modules.each do |mod| -%> +$ModLoad <%= mod %> +<% end -%> diff --git a/puppet/modules/rsyslog/templates/rsyslog.conf.erb b/puppet/modules/rsyslog/templates/rsyslog.conf.erb new file mode 100644 index 00000000..406aa49c --- /dev/null +++ b/puppet/modules/rsyslog/templates/rsyslog.conf.erb @@ -0,0 +1,49 @@ +# file is managed by puppet + +################# +#### MODULES #### +################# + +<% scope.lookupvar('rsyslog::modules').each do |module_row| -%> +<%= module_row %> +<% end -%> + +########################### +#### GLOBAL DIRECTIVES #### +########################### +# +# Set max message size for sending and receiving +# +$MaxMessageSize <%= scope.lookupvar('rsyslog::max_message_size') %> + +# +# Set the default permissions for all log files. +# +<% if scope.lookupvar('rsyslog::preserve_fqdn') -%> +$PreserveFQDN on +<% end -%> +$FileOwner <%= scope.lookupvar('rsyslog::log_user') %> +$FileGroup <%= scope.lookupvar('rsyslog::log_group') %> +$FileCreateMode <%= scope.lookupvar('rsyslog::perm_file') %> +$DirOwner <%= scope.lookupvar('rsyslog::log_user') %> +$DirGroup <%= scope.lookupvar('rsyslog::log_group') %> +$DirCreateMode <%= scope.lookupvar('rsyslog::perm_dir') %> +$PrivDropToUser <%= scope.lookupvar('rsyslog::run_user') %> +$PrivDropToGroup <%= scope.lookupvar('rsyslog::run_group') %> +<% if scope.lookupvar('rsyslog::umask') -%> +$Umask <%= scope.lookupvar('rsyslog::umask') %> +<% end -%> + +# +# Include all config files in <%= scope.lookupvar('rsyslog::rsyslog_d') %> +# +$IncludeConfig <%= scope.lookupvar('rsyslog::rsyslog_d') -%>*.conf + +# +# Emergencies are sent to everybody logged in. +# +<% if @rsyslog_version and @rsyslog_version.split('.')[0].to_i >= 8 -%> +*.emerg :omusrmsg:* +<% else -%> +*.emerg * +<% end -%> diff --git a/puppet/modules/rsyslog/templates/rsyslog_default.erb b/puppet/modules/rsyslog/templates/rsyslog_default.erb new file mode 100644 index 00000000..a49eb59e --- /dev/null +++ b/puppet/modules/rsyslog/templates/rsyslog_default.erb @@ -0,0 +1,9 @@ +# File is managed by puppet + +<% if @rsyslog_version and @rsyslog_version.split('.')[0].to_i < 7 -%> +# Debian, Ubuntu +RSYSLOGD_OPTIONS="-c4" +<% end -%> + +# CentOS, RedHat, Fedora +SYSLOGD_OPTIONS="${RSYSLOGD_OPTIONS}" diff --git a/puppet/modules/rsyslog/templates/rsyslog_default_gentoo.erb b/puppet/modules/rsyslog/templates/rsyslog_default_gentoo.erb new file mode 100644 index 00000000..f5de7b58 --- /dev/null +++ b/puppet/modules/rsyslog/templates/rsyslog_default_gentoo.erb @@ -0,0 +1,16 @@ +# Copyright 1999-2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/app-admin/rsyslog/files/7-stable/rsyslog.confd,v 1.1 2012/11/20 13:03:36 ultrabug Exp $ + +# Configuration file +CONFIGFILE="/etc/rsyslog.conf" + +# PID file +PIDFILE="/var/run/rsyslogd.pid" + +# Options to rsyslogd +# See rsyslogd(8) for more details +# Notes: +# * Do not specify another PIDFILE but use the variable above to change the location +# * Do not specify another CONFIGFILE but use the variable above to change the location +RSYSLOG_OPTS="" diff --git a/puppet/modules/rsyslog/templates/rsyslog_default_rhel7.erb b/puppet/modules/rsyslog/templates/rsyslog_default_rhel7.erb new file mode 100644 index 00000000..c3b95c7f --- /dev/null +++ b/puppet/modules/rsyslog/templates/rsyslog_default_rhel7.erb @@ -0,0 +1,2 @@ +# File is managed by puppet +SYSLOGD_OPTIONS="" diff --git a/puppet/modules/rsyslog/templates/server-default.conf.erb b/puppet/modules/rsyslog/templates/server-default.conf.erb new file mode 100644 index 00000000..0c7f67fe --- /dev/null +++ b/puppet/modules/rsyslog/templates/server-default.conf.erb @@ -0,0 +1,42 @@ +# File is managed by puppet + +<% # Common header across all templates -%> +<%= scope.function_template(['rsyslog/server/_default-header.conf.erb']) %> + +# Log files are stored in directories matching the short hostname, excluding numbers +# i.e. web01 web02 and web03 will all log to a the web directory +<% if scope.lookupvar('rsyslog::server::enable_onefile') == false -%> + +# Templates +$Template dynAuthLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%source:R,ERE,1,DFLT:([A-Za-z-]*)--end%<%= scope.lookupvar('rsyslog::server::logpath') -%>auth.log" +$Template dynSyslog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%source:R,ERE,1,DFLT:([A-Za-z-]*)--end%<%= scope.lookupvar('rsyslog::server::logpath') -%>syslog" +$Template dynCronLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%source:R,ERE,1,DFLT:([A-Za-z-]*)--end%<%= scope.lookupvar('rsyslog::server::logpath') -%>cron.log" +$Template dynDaemonLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%source:R,ERE,1,DFLT:([A-Za-z-]*)--end%<%= scope.lookupvar('rsyslog::server::logpath') -%>daemon.log" +$Template dynKernLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%source:R,ERE,1,DFLT:([A-Za-z-]*)--end%<%= scope.lookupvar('rsyslog::server::logpath') -%>kern.log" +$Template dynUserLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%source:R,ERE,1,DFLT:([A-Za-z-]*)--end%<%= scope.lookupvar('rsyslog::server::logpath') -%>user.log" +$Template dynMailLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%source:R,ERE,1,DFLT:([A-Za-z-]*)--end%<%= scope.lookupvar('rsyslog::server::logpath') -%>mail.log" +$Template dynDebug,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%source:R,ERE,1,DFLT:([A-Za-z-]*)--end%<%= scope.lookupvar('rsyslog::server::logpath') -%>debug" +$Template dynMessages,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%source:R,ERE,1,DFLT:([A-Za-z-]*)--end%<%= scope.lookupvar('rsyslog::server::logpath') -%>messages" + +# Rules +auth,authpriv.* ?dynAuthLog +*.*;auth,authpriv.none,mail.none,cron.none -?dynSyslog +cron.* ?dynCronLog +daemon.* -?dynDaemonLog +kern.* -?dynKernLog +mail.* -?dynMailLog +user.* -?dynUserLog +*.=info;*.=notice;*.=warn;\ + auth.none,authpriv.none;\ + cron.none,daemon.none;\ + mail.none,news.none -?dynMessages +<% else -%> +# Template +$Template dynAllMessages,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%source:R,ERE,1,DFLT:([A-Za-z-]*)--end%<%= scope.lookupvar('rsyslog::server::logpath') -%>messages" + +# Rules +*.* -?dynAllMessages +<% end -%> + +<% # Common footer across all templates -%> +<%= scope.function_template(['rsyslog/server/_default-footer.conf.erb']) %> diff --git a/puppet/modules/rsyslog/templates/server-hostname.conf.erb b/puppet/modules/rsyslog/templates/server-hostname.conf.erb new file mode 100644 index 00000000..67158d95 --- /dev/null +++ b/puppet/modules/rsyslog/templates/server-hostname.conf.erb @@ -0,0 +1,41 @@ +# File is managed by puppet + +<% # Common header across all templates -%> +<%= scope.function_template(['rsyslog/server/_default-header.conf.erb']) %> + +# Log files are stored in directories matching the hostname +<% if scope.lookupvar('rsyslog::server::enable_onefile') == false -%> + +# Templates +$Template dynAuthLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%hostname%<%= scope.lookupvar('rsyslog::server::logpath') -%>auth.log" +$Template dynSyslog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%hostname%<%= scope.lookupvar('rsyslog::server::logpath') -%>syslog" +$Template dynCronLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%hostname%<%= scope.lookupvar('rsyslog::server::logpath') -%>cron.log" +$Template dynDaemonLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%hostname%<%= scope.lookupvar('rsyslog::server::logpath') -%>daemon.log" +$Template dynKernLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%hostname%<%= scope.lookupvar('rsyslog::server::logpath') -%>kern.log" +$Template dynUserLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%hostname%<%= scope.lookupvar('rsyslog::server::logpath') -%>user.log" +$Template dynMailLog,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%hostname%<%= scope.lookupvar('rsyslog::server::logpath') -%>mail.log" +$Template dynDebug,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%hostname%<%= scope.lookupvar('rsyslog::server::logpath') -%>debug" +$Template dynMessages,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%hostname%<%= scope.lookupvar('rsyslog::server::logpath') -%>messages" + +# Rules +auth,authpriv.* ?dynAuthLog +*.*;auth,authpriv.none,mail.none,cron.none -?dynSyslog +cron.* ?dynCronLog +daemon.* -?dynDaemonLog +kern.* -?dynKernLog +mail.* -?dynMailLog +user.* -?dynUserLog +*.=info;*.=notice;*.=warn;\ + auth.none,authpriv.none;\ + cron.none,daemon.none;\ + mail.none,news.none -?dynMessages +<% else -%> +# Template +$Template dynAllMessages,"<%= scope.lookupvar('rsyslog::server::server_dir') -%>%hostname%<%= scope.lookupvar('rsyslog::server::logpath') -%>messages" + +# Rules +*.* -?dynAllMessages +<% end -%> + +<% # Common footer across all templates -%> +<%= scope.function_template(['rsyslog/server/_default-footer.conf.erb']) %> diff --git a/puppet/modules/rsyslog/templates/server/_default-footer.conf.erb b/puppet/modules/rsyslog/templates/server/_default-footer.conf.erb new file mode 100644 index 00000000..d8bd00ad --- /dev/null +++ b/puppet/modules/rsyslog/templates/server/_default-footer.conf.erb @@ -0,0 +1,13 @@ + +# Switch back to default ruleset +$RuleSet RSYSLOG_DefaultRuleset + +<% if scope.lookupvar('rsyslog::server::enable_udp') -%> +$InputUDPServerBindRuleset remote +$UDPServerRun <%= scope.lookupvar('rsyslog::server::port') %> +<% end -%> + +<% if scope.lookupvar('rsyslog::server::enable_tcp') -%> +$InputTCPServerBindRuleset remote +$InputTCPServerRun <%= scope.lookupvar('rsyslog::server::port') %> +<% end -%> diff --git a/puppet/modules/rsyslog/templates/server/_default-header.conf.erb b/puppet/modules/rsyslog/templates/server/_default-header.conf.erb new file mode 100644 index 00000000..4bffa858 --- /dev/null +++ b/puppet/modules/rsyslog/templates/server/_default-header.conf.erb @@ -0,0 +1,36 @@ +<% if scope.lookupvar('rsyslog::server::enable_udp') -%> +# Load UDP module +$ModLoad imudp +<% end -%> + +<% if scope.lookupvar('rsyslog::server::enable_tcp') -%> +# Load TCP module +$ModLoad imtcp +<% end -%> + +# +<% if scope.lookupvar('rsyslog::server::high_precision_timestamps') == false -%> +# Use traditional timestamp format. +# +$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat +<% else -%> +# Use high precision timestamp format. +# +$ActionFileDefaultTemplate RSYSLOG_FileFormat +<% end -%> + +<% if scope.lookupvar('rsyslog::server::ssl') -%> +# Server side SSL. +$DefaultNetstreamDriver gtls + +# Cert files. +$DefaultNetstreamDriverCAFile <%= scope.lookupvar('rsyslog::server::ssl_ca') %> +$DefaultNetstreamDriverCertFile <%= scope.lookupvar('rsyslog::server::ssl_cert') %> +$DefaultNetstreamDriverKeyFile <%= scope.lookupvar('rsyslog::server::ssl_key') %> + +$InputTCPServerStreamDriverMode 1 +$InputTCPServerStreamDriverAuthMode anon +<% end -%> + +# Switch to remote ruleset +$RuleSet remote diff --git a/puppet/modules/rsyslog/tests/database.pp b/puppet/modules/rsyslog/tests/database.pp new file mode 100644 index 00000000..269be696 --- /dev/null +++ b/puppet/modules/rsyslog/tests/database.pp @@ -0,0 +1,9 @@ +include rsyslog + +class { 'rsyslog::database': + backend => 'mysql', + server => 'localhost', + database => 'Syslog', + username => 'rsyslog', + password => 'secret', +} diff --git a/puppet/modules/rsyslog/tests/init.pp b/puppet/modules/rsyslog/tests/init.pp new file mode 100644 index 00000000..7fc50c8b --- /dev/null +++ b/puppet/modules/rsyslog/tests/init.pp @@ -0,0 +1 @@ +include rsyslog diff --git a/puppet/modules/rsyslog/tests/log_templates.pp b/puppet/modules/rsyslog/tests/log_templates.pp new file mode 100644 index 00000000..a6bf75b7 --- /dev/null +++ b/puppet/modules/rsyslog/tests/log_templates.pp @@ -0,0 +1,9 @@ +class { 'rsyslog::client': + log_templates => [ + { + name => 'RFC3164fmt', + template => '<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%', + }, + ], + actionfiletemplate => 'RFC3164fmt', +} diff --git a/puppet/modules/rsyslog/tests/multiple_hosts.pp b/puppet/modules/rsyslog/tests/multiple_hosts.pp new file mode 100644 index 00000000..9e5a60ed --- /dev/null +++ b/puppet/modules/rsyslog/tests/multiple_hosts.pp @@ -0,0 +1,17 @@ +class { 'rsyslog::client': + remote_servers => [ + { + host => 'logs.example.org', + }, + { + port => '55514', + }, + { + host => 'logs.somewhere.com', + port => '555', + pattern => '*.log', + protocol => 'tcp', + format => 'RFC3164fmt', + }, + ] +} -- cgit v1.2.3 From 6a895ece94a86c9ccc32c9bec51413d4e4f0df8e Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:46:29 -0400 Subject: git subrepo clone https://leap.se/git/puppet_backupninja puppet/modules/backupninja subrepo: subdir: "puppet/modules/backupninja" merged: "5268a87" upstream: origin: "https://leap.se/git/puppet_backupninja" branch: "master" commit: "5268a87" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I147608fbb12a35fe83642d4d031009dcc62cecee --- puppet/modules/backupninja/.gitrepo | 11 + puppet/modules/backupninja/LICENSE | 674 +++++++++++++++++++++ puppet/modules/backupninja/README | 202 ++++++ puppet/modules/backupninja/files/checkbackups.pl | 194 ++++++ .../files/nagios_plugins/duplicity/README.md | 24 + .../duplicity/backupninja_duplicity_freshness.sh | 268 ++++++++ .../duplicity/check_backupninja_duplicity.py | 123 ++++ puppet/modules/backupninja/manifests/cron.pp | 17 + puppet/modules/backupninja/manifests/duplicity.pp | 147 +++++ .../backupninja/manifests/generate_sshkey.pp | 33 + puppet/modules/backupninja/manifests/init.pp | 52 ++ puppet/modules/backupninja/manifests/key.pp | 41 ++ puppet/modules/backupninja/manifests/labelmount.pp | 62 ++ puppet/modules/backupninja/manifests/maildir.pp | 43 ++ puppet/modules/backupninja/manifests/mysql.pp | 38 ++ .../manifests/nagios_plugin/duplicity.pp | 45 ++ puppet/modules/backupninja/manifests/pgsql.pp | 27 + puppet/modules/backupninja/manifests/rdiff.pp | 109 ++++ puppet/modules/backupninja/manifests/rsync.pp | 128 ++++ puppet/modules/backupninja/manifests/server.pp | 147 +++++ puppet/modules/backupninja/manifests/sh.pp | 25 + puppet/modules/backupninja/manifests/svn.pp | 28 + puppet/modules/backupninja/manifests/sys.pp | 45 ++ .../backupninja/templates/backupninja.conf.erb | 25 + .../backupninja/templates/backupninja.cron.erb | 6 + puppet/modules/backupninja/templates/dup.conf.erb | 46 ++ .../backupninja/templates/labelmount.conf.erb | 2 + .../backupninja/templates/labelmount.handler | 17 + .../modules/backupninja/templates/maildir.conf.erb | 14 + .../modules/backupninja/templates/mysql.conf.erb | 25 + .../modules/backupninja/templates/pgsql.conf.erb | 13 + .../modules/backupninja/templates/rdiff.conf.erb | 38 ++ .../modules/backupninja/templates/rsync.conf.erb | 49 ++ puppet/modules/backupninja/templates/sh.conf.erb | 10 + puppet/modules/backupninja/templates/svn.conf.erb | 10 + puppet/modules/backupninja/templates/sys.conf.erb | 18 + .../modules/backupninja/templates/umount.conf.erb | 1 + .../modules/backupninja/templates/umount.handler | 15 + 38 files changed, 2772 insertions(+) create mode 100644 puppet/modules/backupninja/.gitrepo create mode 100644 puppet/modules/backupninja/LICENSE create mode 100644 puppet/modules/backupninja/README create mode 100755 puppet/modules/backupninja/files/checkbackups.pl create mode 100644 puppet/modules/backupninja/files/nagios_plugins/duplicity/README.md create mode 100644 puppet/modules/backupninja/files/nagios_plugins/duplicity/backupninja_duplicity_freshness.sh create mode 100644 puppet/modules/backupninja/files/nagios_plugins/duplicity/check_backupninja_duplicity.py create mode 100644 puppet/modules/backupninja/manifests/cron.pp create mode 100644 puppet/modules/backupninja/manifests/duplicity.pp create mode 100644 puppet/modules/backupninja/manifests/generate_sshkey.pp create mode 100644 puppet/modules/backupninja/manifests/init.pp create mode 100644 puppet/modules/backupninja/manifests/key.pp create mode 100644 puppet/modules/backupninja/manifests/labelmount.pp create mode 100644 puppet/modules/backupninja/manifests/maildir.pp create mode 100644 puppet/modules/backupninja/manifests/mysql.pp create mode 100644 puppet/modules/backupninja/manifests/nagios_plugin/duplicity.pp create mode 100644 puppet/modules/backupninja/manifests/pgsql.pp create mode 100644 puppet/modules/backupninja/manifests/rdiff.pp create mode 100644 puppet/modules/backupninja/manifests/rsync.pp create mode 100644 puppet/modules/backupninja/manifests/server.pp create mode 100644 puppet/modules/backupninja/manifests/sh.pp create mode 100644 puppet/modules/backupninja/manifests/svn.pp create mode 100644 puppet/modules/backupninja/manifests/sys.pp create mode 100644 puppet/modules/backupninja/templates/backupninja.conf.erb create mode 100644 puppet/modules/backupninja/templates/backupninja.cron.erb create mode 100644 puppet/modules/backupninja/templates/dup.conf.erb create mode 100644 puppet/modules/backupninja/templates/labelmount.conf.erb create mode 100644 puppet/modules/backupninja/templates/labelmount.handler create mode 100644 puppet/modules/backupninja/templates/maildir.conf.erb create mode 100644 puppet/modules/backupninja/templates/mysql.conf.erb create mode 100644 puppet/modules/backupninja/templates/pgsql.conf.erb create mode 100644 puppet/modules/backupninja/templates/rdiff.conf.erb create mode 100644 puppet/modules/backupninja/templates/rsync.conf.erb create mode 100644 puppet/modules/backupninja/templates/sh.conf.erb create mode 100644 puppet/modules/backupninja/templates/svn.conf.erb create mode 100644 puppet/modules/backupninja/templates/sys.conf.erb create mode 100644 puppet/modules/backupninja/templates/umount.conf.erb create mode 100644 puppet/modules/backupninja/templates/umount.handler (limited to 'puppet/modules') diff --git a/puppet/modules/backupninja/.gitrepo b/puppet/modules/backupninja/.gitrepo new file mode 100644 index 00000000..ea7862f0 --- /dev/null +++ b/puppet/modules/backupninja/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_backupninja + branch = master + commit = 5268a87c329f895017f8ea6c6abc377a4f9a6a77 + parent = 1e1e25286b64790141c9627f81b50f579b13b719 + cmdver = 0.3.0 diff --git a/puppet/modules/backupninja/LICENSE b/puppet/modules/backupninja/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/puppet/modules/backupninja/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/puppet/modules/backupninja/README b/puppet/modules/backupninja/README new file mode 100644 index 00000000..42a8bfe2 --- /dev/null +++ b/puppet/modules/backupninja/README @@ -0,0 +1,202 @@ +Backupninja Module +------------------- + +This module helps you configure all of your backups with puppet, using +backupninja! + +!! UPGRADE NOTICE !! + +If you were previously using this module, some pieces have changed, +and you need to carefully change your use of them, or you will find +your backups could stop working or get duplicated. + +The backupninja::client class has been renamed to backupninja, and is +now *required* in all node manifests. Make sure the backupninja class +is now declared in all your node manifests! This new class now defines +defaults which were previously provided by backupninja::client::defaults, +and can now be overridden thanks to the brand new technology of class +parameters. This class also manages the backupninja configuration file, +replacing the backupninja::config ressource. + +The backupninja::server class now takes parameters, replacing several +global variables such as $backupdir, $backupserver_tag and +$nagios_server. The $manage_nagios parameter also replaces the +$use_nagios global. + +As for handlers, they don't include the backupninja::client anymore and +now read several default values from the backupninja base class. The +$installkey parameter used in several handlers has been renamed to +$keymanage, to keep in line with the base class parameter. + +If you were using the rdiff-backup handler, you need to read the +following section carefully. + +Changes to the rdiff-backup handler +----------------------------------- + +You will need to make sure you change all of your "$directory" +parameters to be "$home" instead, and on your backupserver you will need +to move all of your backups into "$home"/rdiff-backup. Previously, they +were put in "$directory", which doubled as the home for the user that +was created. This caused problems with rdiff-backup because of dot files +and other things which were not part of any rdiff-backup. + +The rdiff resource name is now used as the subdirectory where rdiff +backups are sent. This was previously hardcoded to "rdiff-backup", but +in order to support multiple rdiff backups per host, we now use the +resource name. So if you were using the following resource: + + backupninja::rdiff { 'main': } + +You will want to use the following resource: + + backupninja::rdiff { 'rdiff-backup': } + file { '/etc/backup.d/90_main.rdiff': ensure => absent; } + +Otherwise your backups may be duplicated! + +Changes to nagios integration +----------------------------- + +The default nagios passive service name has changed from "backups" to +"backups-${name}". If you want it to be automatically created on your +nagios host, you will need to set $backupninja::manage_nagios to true. +on the client. + +Use the following resource to remove the old "backups" passive service. + + nagios::service { 'backups': ensure => absent } + +Getting started +--------------- + +This module requires Puppet versions 2.7 and up. + +An up-to-date version of the puppet-stdlib module is also required. + +Configure your backup server +---------------------------- + +Now you will need to configure a backup server by adding the following +to your node definition for that server: + + include backupninja::server + +The default configuration will store backup data in the "/backup" +directory. To change this you may declare the class with a "backupdir" +parameter: + + class { 'backupninja::server': + backupdir => '/mnt/backupdata' + } + +By configuring a backupninja::server, this module will automatically +create sandboxed users on the server for each client for their +backups. + +Configure your backup clients +----------------------------- + +First, you need to include the backupninja class or declare it with +custom parameters: + + class { 'backupninja': + loglvl => 3, + usecolors => false, + reportsuccess => false, + reportwarning => true, + ensure_backupninja_version => '1.0.1-1', + ensure_rdiffbackup_version => '1.2.8-7' + } + +In this case, the module will make sure that the backupninja package +is installed (using puppet's ensure parameter language) and create the +/etc/backupninja.conf configuration file. + +If you need to specify a specific version of either backupninja itself, +or the specific programs that the handler class installs, you can +specify the version you need installed by providing a class parameter, +as shown in the example. + +Configuring handlers +-------------------- + +Depending on which backup method you want to use on your client, you +can simply specify some configuration options for that handler that are +necessary for your client. + +Each handler has its own configuration options necessary to make it +work, each of those are available as puppet parameters. You can see +the handler documentation, or look at the handler puppet files +included in this module to see your different options. + +Included below are some configuration examples for different handlers. + +* An example mysql handler configuration: + +backupninja::mysql { 'all_databases': + user => root, + backupdir => '/var/backups', + compress => true, + sqldump => true +} + +* An example rdiff-backup handler configuration: + +backupninja::rdiff { 'backup_all': + directory => '/media/backupdisk', + include => ['/var/backups', '/home', '/var/lib/dpkg/status'], + exclude => '/home/*/.gnupg' +} + +* A remote rdiff-backup handler: + +backupninja::rdiff { 'main': + host => 'backup.example.com', + type => 'remote', + directory => "/backup/${::fqdn}", + user => "backup-${::hostname}", +} + +Automatic creation of ssh-keys for duplicity +-------------------------------------------- + +backupninja::duplicity can be used to + +- create an ssh keypair for a client +- place the keypair on the puppetmaster in a given location +- place the keypair in /root/.ssh on the client + +i.e.: + + backupninja::duplicity { "duplicity_${::fqdn}": + sshoptions => "-oIdentityFile=/root/.ssh/backupninja_${::hostname}_id_rsa", + desthost => 'HOST', + destdir => "/var/backup/backupninja/${::fqdn}", + destuser => "backupninja_${::hostname}", + encryptkey => 'KEYID', + password => 'PW', + backupkeystore => 'puppet:///keys', + backupkeystorefspath => '/etc/puppet/modules/keys/files', + backupkeydestname => "backupninja_${::hostname}_id_rsa", + createkey => true, + installkey => true, + ... + } + + +Nagios alerts about backup freshness +------------------------------------ + +If you set the $backupninja::server::nagios_server variable to be the +name of your nagios server, then a passive nagios service gets setup so +that the backup server pushes checks, via a cronjob that calls +/usr/local/bin/checkbackups.pl, to the nagios server to alert about +relative backup freshness. + +To use this feature a few pre-requisites are necessary: + + . configure nsca on your backup server (not done via puppet yet) + . configure nsca on your nagios server (not done via puppet yet) + . server backup directories are named after their $fqdn + . backups must be under $home/dup, $home/rdiff-backup depending on method diff --git a/puppet/modules/backupninja/files/checkbackups.pl b/puppet/modules/backupninja/files/checkbackups.pl new file mode 100755 index 00000000..39914469 --- /dev/null +++ b/puppet/modules/backupninja/files/checkbackups.pl @@ -0,0 +1,194 @@ +#!/usr/bin/perl -w + +# This script is designed to check a backup directory populated with +# subdirectories named after hosts, within which there are backups of various +# types. +# +# Example: +# /home/backup: +# foo.example.com +# +# foo.example.com: +# rdiff-backup .ssh +# +# rdiff-backup: +# root home rdiff-backup-data usr var +# +# There are heuristics to determine the backup type. Currently, the following +# types are supported: +# +# rdiff-backup: assumes there is a rdiff-backup/rdiff-backup-data/backup.log file +# duplicity: assumes there is a dup subdirectory, checks the latest file +# dump files: assumes there is a dump subdirectory, checks the latest file +# +# This script returns output suitable for send_nsca to send the results to +# nagios and should therefore be used like this: +# +# checkbackups.sh | send_nsca -H nagios.example.com + +use Getopt::Std; + +# XXX: taken from utils.sh from nagios-plugins-basic +my $STATE_OK=0; +my $STATE_WARNING=1; +my $STATE_CRITICAL=2; +my $STATE_UNKNOWN=3; +my $STATE_DEPENDENT=4; +my %ERRORS=(0=>'OK',1=>'WARNING',2=>'CRITICAL',3=>'UNKNOWN',4=>'DEPENDENT'); + +# gross hack: we look into subdirs to find vservers +my @vserver_dirs = qw{/var/lib/vservers /vservers}; + +our $opt_d = "/backup"; +our $opt_c = 48 * 60 * 60; +our $opt_w = 24 * 60 * 60; +our $opt_v = 0; +our $opt_o; +our $opt_s; + +if (!getopts('d:c:w:s:vo')) { + print < ] [ -c ] [ -w ] [ -o ] [ -s ] [ -v ] +EOF + ; + exit(); +} + +sub check_rdiff { + my ($host, $dir, $optv) = @_; + my $flag="$dir/rdiff-backup-data/backup.log"; + my $extra_msg = ''; + my @vservers; + if (open(FLAG, $flag)) { + while () { + if (/EndTime ([0-9]*).[0-9]* \((.*)\)/) { + $last_bak = $1; + $extra_msg = ' [backup.log]'; + $opt_v && print STDERR "found timestamp $1 ($2) in $flag\n"; + } + } + if (!$last_bak) { + print_status($host, $STATE_UNKNOWN, "cannot parse $flag for a valid timestamp"); + next; + } + } else { + $opt_v && print STDERR "cannot open $flag\n"; + } + close(FLAG); + ($state, $delta) = check_age($last_bak); + $dir =~ /([^\/]+)\/?$/; + $service = "backups-$1"; + print_status($host, $state, "$delta hours old$extra_msg", $service); + foreach my $vserver_dir (@vserver_dirs) { + $vsdir = "$dir/$vserver_dir"; + if (opendir(DIR, $vsdir)) { + @vservers = grep { /^[^\.]/ && -d "$vsdir/$_" } readdir(DIR); + $opt_v && print STDERR "found vservers $vsdir: @vservers\n"; + closedir DIR; + } else { + $opt_v && print STDERR "no vserver in $vsdir\n"; + } + } + my @dom_sufx = split(/\./, $host); + my $dom_sufx = join('.', @dom_sufx[1,-1]); + foreach my $vserver (@vservers) { + print_status("$vserver.$dom_sufx", $state, "$delta hours old$extra_msg, same as parent: $host"); + } +} + +sub check_age { + my ($last_bak) = @_; + my $t = time(); + my $delta = $t - $last_bak; + if ($delta > $opt_c) { + $state = $STATE_CRITICAL; + } elsif ($delta > $opt_w) { + $state = $STATE_WARNING; + } elsif ($delta >= 0) { + $state = $STATE_OK; + } + $delta = sprintf '%.2f', $delta/3600.0; + return ($state, $delta); +} + +sub print_status { + my ($host, $state, $message, $service) = @_; + my $state_msg = $ERRORS{$state}; + if (!$service) { + $service = 'backups'; + } + $line = "$host\t$service\t$state\t$state_msg $message\n"; + if ($opt_s) { + $opt_v && print STDERR "sending results to nagios...\n"; + open(NSCA, "|/usr/sbin/send_nsca -H $opt_s") or die("cannot start send_nsca: $!\n"); + print NSCA $line; + close(NSCA) or warn("could not close send_nsca pipe correctly: $!\n"); + } + if (!$opt_s || $opt_v) { + printf $line; + } +} + +sub check_flag { + my ($host, $flag) = @_; + my @stats = stat($flag); + if (not @stats) { + print_status($host, $STATE_UNKNOWN, "cannot stat flag $flag"); + } + else { + ($state, $delta) = check_age($stats[9]); + print_status($host, $state, "$delta hours old"); + } +} + +my $backupdir= $opt_d; + +my @hosts; +if (defined($opt_o)) { + @hosts=qx{hostname -f}; +} else { + # XXX: this should be a complete backup registry instead + @hosts=qx{ls $backupdir | grep -v lost+found}; +} + +chdir($backupdir); +my ($delta, $state, $host); +foreach $host (@hosts) { + chomp($host); + if ($opt_o) { + $dir = $backupdir; + } else { + $dir = $host; + } + my $flag; + if (-d $dir) { + # guess the backup type and find a proper stamp file to compare + @rdiffs = glob("$dir/*/rdiff-backup-data"); + foreach $subdir (@rdiffs) { + $subdir =~ s/rdiff-backup-data$//; + $opt_v && print STDERR "inspecting dir $subdir\n"; + check_rdiff($host, $subdir, $opt_v); + $flag = 1; + } + if (-d "$dir/dump") { + # XXX: this doesn't check backup consistency + $flag="$dir/dump/" . `ls -tr $dir/dump | tail -1`; + chomp($flag); + check_flag($host, $flag); + } elsif (-d "$dir/dup") { + # XXX: this doesn't check backup consistency + $flag="$dir/dup/" . `ls -tr $dir/dup | tail -1`; + chomp($flag); + check_flag($host, $flag); + } elsif (-r "$dir/rsync.log") { + # XXX: this doesn't check backup consistency + $flag="$dir/rsync.log"; + check_flag($host, $flag); + } + if (!$flag) { + print_status($host, $STATE_UNKNOWN, 'unknown system'); + } + } else { + print_status($host, $STATE_UNKNOWN, 'no directory'); + } +} diff --git a/puppet/modules/backupninja/files/nagios_plugins/duplicity/README.md b/puppet/modules/backupninja/files/nagios_plugins/duplicity/README.md new file mode 100644 index 00000000..1cd349af --- /dev/null +++ b/puppet/modules/backupninja/files/nagios_plugins/duplicity/README.md @@ -0,0 +1,24 @@ +duplicity-backup-status +======================= + +Backupninja generates duplicity configfiles, this nagios plugin can check their freshness. Currently only the config files generated by backupninja can be parsed and we depend on that. + +## Prerequisites + +Make sure you have python-argparse installed (yes an extra dependency, getopt doubles the amount of code, so I gave up on that). The Python script will look for the duplicity_freshness.sh shell script in /usr/local/lib/nagios/plugins/ or /usr/lib/nagios/plugins/ make sure you copy it there and make executable. + +## Getting started + +Run the python script from your nagios. Don't forget to specify some extras like when warnings or criticalities should be emerged. + +- -w WARNINC Number of hours allowed for incremential backup warning level default 28 +- -W WARNFULL Number of hours allowed for incremential backup critical level default 40 +- -c CRITINC Number of days allowed for full backup warning level default 52 +- -C CRITFULL Number of days allowed for full backup critical level default 60 + + +## TODO: + +- make it cuter, tidy up +- make it more robust +- support other config backends as backupninja - this can be done by writing more scripts like backupninja_duplicity_freshness.sh and parsing an extra parameter diff --git a/puppet/modules/backupninja/files/nagios_plugins/duplicity/backupninja_duplicity_freshness.sh b/puppet/modules/backupninja/files/nagios_plugins/duplicity/backupninja_duplicity_freshness.sh new file mode 100644 index 00000000..7af2bf7f --- /dev/null +++ b/puppet/modules/backupninja/files/nagios_plugins/duplicity/backupninja_duplicity_freshness.sh @@ -0,0 +1,268 @@ +#!/bin/bash +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# vim: set filetype=sh sw=3 sts=3 expandtab autoindent: + +# Load backupninja library/helpers, because why reinventing the wheel? [Because my wheels weren't round] +# some duplication is to be expected +# this is only supposed to work with duplicity + +## Functions +# simple lowercase function +function tolower() { + echo "$1" | tr '[:upper:]' '[:lower:]' +} + +# we grab the current time once, since processing +# all the configs might take more than an hour. +nowtime=`LC_ALL=C date +%H` +nowday=`LC_ALL=C date +%d` +nowdayofweek=`LC_ALL=C date +%A` +nowdayofweek=`tolower "$nowdayofweek"` + +conffile="/etc/backupninja.conf" + +# find $libdirectory +libdirectory=`grep '^libdirectory' $conffile | /usr/bin/awk '{print $3}'` +if [ -z "$libdirectory" ]; then + if [ -d "/usr/lib/backupninja" ]; then + libdirectory="/usr/lib/backupninja" + else + echo "Could not find entry 'libdirectory' in $conffile." + fatal "Could not find entry 'libdirectory' in $conffile." + fi +else + if [ ! -d "$libdirectory" ]; then + echo "Lib directory $libdirectory not found." + fatal "Lib directory $libdirectory not found." + fi +fi + +. $libdirectory/tools + +setfile $conffile + +# get global config options (second param is the default) +getconf configdirectory /etc/backup.d +getconf scriptdirectory /usr/share/backupninja +getconf reportdirectory +getconf reportemail +getconf reporthost +getconf reportspace +getconf reportsuccess yes +getconf reportinfo no +getconf reportuser +getconf reportwarning yes +getconf loglevel 3 +getconf when "Everyday at 01:00" +defaultwhen=$when +getconf logfile /var/log/backupninja.log +getconf usecolors "yes" +getconf SLAPCAT /usr/sbin/slapcat +getconf LDAPSEARCH /usr/bin/ldapsearch +getconf RDIFFBACKUP /usr/bin/rdiff-backup +getconf CSTREAM /usr/bin/cstream +getconf MYSQLADMIN /usr/bin/mysqladmin +getconf MYSQL /usr/bin/mysql +getconf MYSQLHOTCOPY /usr/bin/mysqlhotcopy +getconf MYSQLDUMP /usr/bin/mysqldump +getconf PGSQLDUMP /usr/bin/pg_dump +getconf PGSQLDUMPALL /usr/bin/pg_dumpall +getconf PGSQLUSER postgres +getconf GZIP /bin/gzip +getconf GZIP_OPTS --rsyncable +getconf RSYNC /usr/bin/rsync +getconf admingroup root + +if [ ! -d "$configdirectory" ]; then + echo "Configuration directory '$configdirectory' not found." + fatal "Configuration directory '$configdirectory' not found." +fi + +# get the duplicity configuration +function get_dupconf(){ + setfile $1 + getconf options + getconf testconnect yes + getconf nicelevel 0 + getconf tmpdir + + setsection gpg + getconf password + getconf sign no + getconf encryptkey + getconf signkey + + setsection source + getconf include + getconf vsnames all + getconf vsinclude + getconf exclude + + setsection dest + getconf incremental yes + getconf increments 30 + getconf keep 60 + getconf keepincroffulls all + getconf desturl + getconf awsaccesskeyid + getconf awssecretaccesskey + getconf cfusername + getconf cfapikey + getconf cfauthurl + getconf ftp_password + getconf sshoptions + getconf bandwidthlimit 0 + getconf desthost + getconf destdir + getconf destuser + destdir=${destdir%/} +} + +### some voodoo to mangle the correct commands + +function mangle_cli(){ + + execstr_options="$options " + execstr_source= + if [ -n "$desturl" ]; then + [ -z "$destuser" ] || warning 'the configured destuser is ignored since desturl is set' + [ -z "$desthost" ] || warning 'the configured desthost is ignored since desturl is set' + [ -z "$destdir" ] || warning 'the configured destdir is ignored since desturl is set' + execstr_serverpart="$desturl" + else + execstr_serverpart="scp://$destuser@$desthost/$destdir" + fi + + + ### Symmetric or asymmetric (public/private key pair) encryption + if [ -n "$encryptkey" ]; then + execstr_options="${execstr_options} --encrypt-key $encryptkey" + fi + + ### Data signing (or not) + if [ "$sign" == yes ]; then + # duplicity is not able to sign data when using symmetric encryption + [ -n "$encryptkey" ] || fatal "The encryptkey option must be set when signing." + # if needed, initialize signkey to a value that is not empty (checked above) + [ -n "$signkey" ] || signkey="$encryptkey" + execstr_options="${execstr_options} --sign-key $signkey" + fi + + ### Temporary directory + precmd= + if [ -n "$tmpdir" ]; then + if [ ! -d "$tmpdir" ]; then + #info "Temporary directory ($tmpdir) does not exist, creating it." + mkdir -p "$tmpdir" + [ $? -eq 0 ] || fatal "Could not create temporary directory ($tmpdir)." + chmod 0700 "$tmpdir" + fi + #info "Using $tmpdir as TMPDIR" + precmd="${precmd}TMPDIR=$tmpdir " + fi + + ### Source + + set -o noglob + + # excludes + SAVEIFS=$IFS + IFS=$(echo -en "\n\b") + for i in $exclude; do + str="${i//__star__/*}" + execstr_source="${execstr_source} --exclude '$str'" + done + IFS=$SAVEIFS + + # includes + SAVEIFS=$IFS + IFS=$(echo -en "\n\b") + for i in $include; do + [ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'" + str="${i//__star__/*}" + execstr_source="${execstr_source} --include '$str'" + done + IFS=$SAVEIFS + + set +o noglob + + execstr_options="${execstr_options} --ssh-options '$sshoptions'" + if [ "$bandwidthlimit" != 0 ]; then + [ -z "$desturl" ] || warning 'The bandwidthlimit option is not used when desturl is set.' + execstr_precmd="trickle -s -d $bandwidthlimit -u $bandwidthlimit" + fi +} + +#function findlastdates(){ +# outputfile=$1 +# lastfull=0 +# lastinc=0 +# backuptime=0 +# +# while read line; do +# atime=0 +# arr=() +# sort='' +# test=$(echo $line|awk '{if (NF == 7); if ($1 == "Full" || $1 == "Incremental") {print $4, $3, $6, $5}}' ) +# +# if [ -n "$test" ]; then +# backuptime=$(date -u -d "$test" +%s) +# +# arr=($(echo $line|awk '{print $1, $2, $3, $4, $5, $6}')) +# if [ ${arr[0]} == "Incremental" ] && [ "$lastinc" -lt "$backuptime" ] ; then +# lastinc=$backuptime +# elif [ ${arr[0]} == "Full" ] && [ "$lastfull" -lt "$backuptime" ] ; then +# lastfull=$backuptime +# fi +# +# fi +# +# done < $outputfile +# # a full backup can be seen as incremental too +# lastinc=$(echo $lastinc | awk 'max=="" || $1 > max {max=$1} END{ print max}') +#} + +function check_status() { + grep -q 'No orphaned or incomplete backup sets found.' $1 + if [ $? -ne 0 ] ; then + exit 2 + fi +} + +## +## this function handles the freshness check of a backup action +## + +function process_action() { + local file="$1" + local suffix="$2" + setfile $file + get_dupconf $1 + mangle_cli + + outputfile=`maketemp backupout` + export PASSPHRASE=$password + export FTP_PASSWORD=$ftp_password + output=` su -c \ + "$execstr_precmd duplicity $execstr_options collection-status $execstr_serverpart >$outputfile 2>&1"` + exit_code=$? + echo -n $outputfile + + #check_status + #findlastdates +} + +files=`find $configdirectory -follow -mindepth 1 -maxdepth 1 -type f ! -name '.*.swp' | sort -n` + +for file in $files; do + [ -f "$file" ] || continue + suffix="${file##*.}" + base=`basename $file` + if [ "${base:0:1}" == "0" -o "$suffix" == "disabled" ]; then + continue + fi + if [ -e "$scriptdirectory/$suffix" -a "$suffix" == "dup" ]; then + process_action $file $suffix + fi +done + diff --git a/puppet/modules/backupninja/files/nagios_plugins/duplicity/check_backupninja_duplicity.py b/puppet/modules/backupninja/files/nagios_plugins/duplicity/check_backupninja_duplicity.py new file mode 100644 index 00000000..8ed9ce68 --- /dev/null +++ b/puppet/modules/backupninja/files/nagios_plugins/duplicity/check_backupninja_duplicity.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python + +# Inspired by Arne Schwabe [with BSD license] +# Inspired by backupninja [that's gpl some version] +# minor changes by someon who doesn't understand all the license quirks + +from subprocess import Popen,PIPE +import sys +import time +import os +import argparse +import getopt + +def main(): + # getopt = much more writing + parser = argparse.ArgumentParser(description='Nagios Duplicity status checker') + + parser.add_argument("-w", dest="warninc", default=28, type=int, + help="Number of hours allowed for incremential backup warning level, default 28") + parser.add_argument("-W", dest="warnfull", default=31, type=int, + help="Number of days allowed for full backup warning level, default 31") + parser.add_argument("-c", dest="critinc", default=52, type=int, + help="Number of hours allowed for incremential backup critical level, default 52") + parser.add_argument("-C", dest="critfull", default=33, type=int, + help="Number of days allowed for full backup critical level, default 33") + args = parser.parse_args() + + okay = 0 + + # *sigh* check_output is from python 2.7 and onwards. Debian, upgrade yourself. + #output , err = check_output(['/root/freshness.sh']) + + if os.path.isfile("/usr/lib/nagios/plugins/backupninja_duplicity_freshness.sh") and os.access("/usr/lib/nagios/plugins/backupninja_duplicity_freshness.sh", os.X_OK): + checkstatus, err = Popen(['/bin/bash', '/usr/lib/nagios/plugins/backupninja_duplicity_freshness.sh'], stdout=PIPE, stderr=PIPE, env={'HOME': '/root', 'PATH': os.environ['PATH']}).communicate() + elif os.path.isfile("/usr/local/lib/nagios/plugins/backupninja_duplicity_freshness.sh") and os.access("/usr/local/lib/nagios/plugins/backupninja_duplicity_freshness.sh", os.X_OK): + checkstatus, err = Popen(['/bin/bash', '/usr/local/lib/nagios/plugins/backupninja_duplicity_freshness.sh'], stdout=PIPE, stderr=PIPE, env={'HOME': '/root', 'PATH': os.environ['PATH']}).communicate() + + # Don't use exec(), popen(), etc. to execute external commands without explicity using the full path of the external program. Hijacked search path could be problematic. + #checkstatus, err = Popen(['/bin/bash', './freshness.sh'], stdout=PIPE, stderr=PIPE, env={'HOME': '/root', 'PATH': os.environ['PATH']}).communicate() + + #another sigh: Debian testing, upgrade yourself, this is only needed because Debian testing uses duplicity 0.6.18-3 + # open file read/write + f = open (checkstatus,"r") + checklines = f.readlines() + f.close() + + # remove the line that says Import of duplicity.backends.giobackend Failed: No module named gio + f = open(checkstatus,"w") + for line in checklines: + if not 'Import of duplicity.backends.giobackend Failed: No module named gio' in line: + f.write(line) + f.close() + + output = open(checkstatus).read() + + lastfull, lastinc = findlastdates(output) + + sincelastfull = time.time() - lastfull + sincelastinc = time.time() - lastinc + + msg = "OK: " + + if sincelastfull > (args.warnfull * 24 * 3600) or sincelastinc > (args.warninc * 3600): + okay = 1 + msg = "WARNING: " + if sincelastfull > (args.critfull * 24 * 3600) or sincelastinc > (args.critinc * 3600): + okay = 2 + msg = "CRITICAL: " + if not checkoutput(output): + okay = max(okay,1) + msg = "WARNING: duplicity output: %s " % repr(output) + if err: + okay=2 + msg = "Unexpected output: %s, " % repr(err) + + print msg, "last full %s ago, last incremential %s ago|lastfull=%d, lastinc=%d" % ( formattime(sincelastfull), formattime(sincelastinc), sincelastfull, sincelastinc) + + #clean up cruft + os.remove(checkstatus) + sys.exit(okay) + +def checkoutput(output): + if not 'No orphaned or incomplete backup sets found.' in output: + return False + + return True + +def formattime(seconds): + days = seconds / (3600 * 24) + hours = seconds / 3600 % 24 + + if days: + return "%d days %d hours" % (days,hours) + else: + return "%d hours" % hours + + +def findlastdates(output): + lastfull = 0 + lastinc = 0 + + for line in output.split("\n"): + parts = line.split() + + # ['Incremental', 'Sun', 'Oct', '31', '03:00:04', '2010', '1'] + if len (parts) == 7 and parts[0] in ["Full","Incremental"]: + foo = time.strptime(" ".join(parts[1:6]),"%a %b %d %H:%M:%S %Y") + + backuptime = time.mktime(foo) + + if parts[0] == "Incremental" and lastinc < backuptime: + lastinc = backuptime + elif parts[0] == "Full" and lastfull < backuptime: + lastfull = backuptime + + + # Count a full backup as incremental backup + lastinc = max(lastfull,lastinc) + return (lastfull, lastinc) + + +if __name__=='__main__': + main() diff --git a/puppet/modules/backupninja/manifests/cron.pp b/puppet/modules/backupninja/manifests/cron.pp new file mode 100644 index 00000000..bd4e857c --- /dev/null +++ b/puppet/modules/backupninja/manifests/cron.pp @@ -0,0 +1,17 @@ +# Write the backupninja cron job, allowing you to specify an alternate backupninja +# command (if you want to wrap it in any other commands, e.g. to allow it to use +# the monkeysphere for authentication), or a different schedule to run it on. +define backupninja::cron( + $backupninja_cmd = '/usr/sbin/backupninja', + $backupninja_test_cmd = $backupninja_cmd, + $cronfile = "/etc/cron.d/backupninja", + $min = "0", $hour = "*", $dom = "*", $month = "*", + $dow = "*") +{ + file { $cronfile: + content => template('backupninja/backupninja.cron.erb'), + owner => root, + group => root, + mode => 0644 + } +} diff --git a/puppet/modules/backupninja/manifests/duplicity.pp b/puppet/modules/backupninja/manifests/duplicity.pp new file mode 100644 index 00000000..a05da876 --- /dev/null +++ b/puppet/modules/backupninja/manifests/duplicity.pp @@ -0,0 +1,147 @@ +# Run duplicity-backup as part of a backupninja run. +# +# Valid attributes for this type are: +# +# order: +# +# The prefix to give to the handler config filename, to set order in +# which the actions are executed during the backup run. +# +# ensure: +# +# Allows you to delete an entry if you don't want it any more (but be +# sure to keep the configdir, name, and order the same, so that we can +# find the correct file to remove). +# +# options, nicelevel, testconnect, tmpdir, sign, encryptkey, signkey, +# password, include, exclude, vsinclude, incremental, keep, bandwidthlimit, +# sshoptions, destdir, desthost, desuser: +# +# As defined in the backupninja documentation. The options will be +# placed in the correct sections automatically. The include and +# exclude options should be given as arrays if you want to specify +# multiple directories. +# +# directory, ssh_dir_manage, ssh_dir, authorized_keys_file, installuser, +# installkey, backuptag: +# +# Options for the bakupninja::server::sandbox define, check that +# definition for more info. +# +# Some notes about this handler: +# +# - When specifying a password, be sure to enclose it in single quotes, +# this is particularly important if you have any special characters, such +# as a $ which puppet will attempt to interpret resulting in a different +# password placed in the file than you expect! +# - There's no support for a 'local' type in backupninja's duplicity +# handler on version 0.9.6-4, which is the version available in stable and +# testing debian repositories by the time of this writing. +define backupninja::duplicity( $order = 90, + $ensure = present, + # options to the config file + $options = false, + $nicelevel = false, + $testconnect = false, + $tmpdir = false, + # [gpg] + $sign = false, + $encryptkey = false, + $signkey = false, + $password = false, + # [source] + $include = [ "/var/spool/cron/crontabs", + "/var/backups", + "/etc", + "/root", + "/home", + "/usr/local/*bin", + "/var/lib/dpkg/status*" ], + $exclude = [ "/home/*/.gnupg", + "/home/*/.local/share/Trash", + "/home/*/.Trash", + "/home/*/.thumbnails", + "/home/*/.beagle", + "/home/*/.aMule", + "/home/*/.gnupg", + "/home/*/.gpg", + "/home/*/.ssh", + "/home/*/gtk-gnutella-downloads", + "/etc/ssh/*" ], + $vsinclude = false, + # [dest] + $incremental = "yes", + $increments = false, + $keep = false, + $keepincroffulls = false, + $bandwidthlimit = false, + $sshoptions = false, + $destdir = false, + $desthost = false, + $destuser = false, + $desturl = false, + # configs to backupninja client + $backupkeystore = $backupninja::keystore, + $backupkeystorefspath = $backupninja::keystorefspath, + $backupkeytype = $backupninja::keytype, + $backupkeydest = $backupninja::keydest, + $backupkeydestname = $backupninja::keydestname, + # options to backupninja server sandbox + $ssh_dir_manage = true, + $ssh_dir = "${destdir}/.ssh", + $authorized_keys_file = 'authorized_keys', + $installuser = true, + $backuptag = "backupninja-${::fqdn}", + # key options + $createkey = false, + $keymanage = $backupninja::keymanage ) { + + # install client dependencies + ensure_resource('package', 'duplicity', {'ensure' => $backupninja::ensure_duplicity_version}) + + case $desthost { false: { err("need to define a destination host for remote backups!") } } + case $destdir { false: { err("need to define a destination directory for remote backups!") } } + case $password { false: { err("a password is necessary either to unlock the GPG key, or for symmetric encryption!") } } + + # guarantees there's a configured backup space for this backup + backupninja::server::sandbox { "${user}-${name}": + user => $destuser, + host => $desthost, + dir => $destdir, + manage_ssh_dir => $ssh_dir_manage, + ssh_dir => $ssh_dir, + authorized_keys_file => $authorized_keys_file, + installuser => $installuser, + backuptag => $backuptag, + backupkeys => $backupkeystore, + keytype => $backupkeytype, + } + + # the client's ssh key + backupninja::key { "${destuser}-${name}": + user => $destuser, + createkey => $createkey, + keymanage => $keymanage, + keytype => $backupkeytype, + keystore => $backupkeystore, + keystorefspath => $backupkeystorefspath, + keydest => $backupkeydest, + keydestname => $backupkeydestname + } + + # the backupninja rule for this duplicity backup + file { "${backupninja::configdir}/${order}_${name}.dup": + ensure => $ensure, + content => template('backupninja/dup.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::configdir}"] + } + + if $backupninja::manage_nagios { + nagios::service::passive { $nagios_description: } + } + +} + diff --git a/puppet/modules/backupninja/manifests/generate_sshkey.pp b/puppet/modules/backupninja/manifests/generate_sshkey.pp new file mode 100644 index 00000000..a3008e50 --- /dev/null +++ b/puppet/modules/backupninja/manifests/generate_sshkey.pp @@ -0,0 +1,33 @@ +define backupninja::generate_sshkey( + $ssh_key_basepath = '/etc/puppet/modules/keys/files/backupkeys', +){ + + # generate backupninja ssh keypair + $ssh_key_name = "backup_${::hostname}_id_rsa" + $ssh_keys = ssh_keygen("${ssh_key_basepath}/${ssh_key_name}") + $public = split($ssh_keys[1],' ') + $public_type = $public[0] + $public_key = $public[1] + + file { '/root/.ssh': + ensure => directory, + owner => 'root', + group => 'root', + mode => '0600'; + } + + # install ssh keypair on client + file { "/root/.ssh/$ssh_key_name": + content => $ssh_keys[0], + owner => root, + group => 0, + mode => '0600'; + } + + file { "/root/.ssh/$ssh_key_name.pub": + content => $public_key, + owner => root, + group => 0, + mode => '0666'; + } +} diff --git a/puppet/modules/backupninja/manifests/init.pp b/puppet/modules/backupninja/manifests/init.pp new file mode 100644 index 00000000..e453e703 --- /dev/null +++ b/puppet/modules/backupninja/manifests/init.pp @@ -0,0 +1,52 @@ +# configure backupninja +class backupninja ( + $ensure_backupninja_version = 'installed', + $ensure_rsync_version = 'installed', + $ensure_rdiffbackup_version = 'installed', + $ensure_debconfutils_version = 'installed', + $ensure_hwinfo_version = 'installed', + $ensure_duplicity_version = 'installed', + $configdir = '/etc/backup.d', + $keystore = "${::fileserver}/keys/backupkeys", + $keystorefspath = false, + $keytype = 'rsa', + $keydest = '/root/.ssh', + $keyowner = 0, + $keygroup = 0, + $keymanage = true, + $configfile = '/etc/backupninja.conf', + $loglvl = 4, + $when = 'everyday at 01:00', + $reportemail = 'root', + $reportsuccess = false, + $reportwarning = true, + $reporthost = undef, + $reportuser = undef, + $reportdirectory = undef, + $logfile = '/var/log/backupninja.log', + $scriptdir = '/usr/share/backupninja', + $libdir = '/usr/lib/backupninja', + $usecolors = true, + $vservers = false, + $manage_nagios = false, +) { + + # install client dependencies + ensure_resource('package', 'backupninja', {'ensure' => $ensure_backupninja_version}) + + # set up backupninja config directory + file { $configdir: + ensure => directory, + mode => '0750', + owner => 0, + group => 0; + } + + file { $configfile: + content => template('backupninja/backupninja.conf.erb'), + owner => root, + group => 0, + mode => '0644' + } + +} diff --git a/puppet/modules/backupninja/manifests/key.pp b/puppet/modules/backupninja/manifests/key.pp new file mode 100644 index 00000000..9d34cdbd --- /dev/null +++ b/puppet/modules/backupninja/manifests/key.pp @@ -0,0 +1,41 @@ +# generate and deploy backupninja sshkeys +define backupninja::key( + $user = $name, + $createkey = false, + $keymanage = $backupninja::keymanage, + $keyowner = $backupninja::keyowner, + $keygroup = $backupninja::keygroup, + $keystore= $backupninja::keystore, + $keystorefspath = $backupninja::keystorefspath, + $keytype = $backupninja::keytype, + $keydest = $backupninja::keydest, + $keydestname = "id_${backupninja::keytype}" ) +{ + + # generate the key + if $createkey == true { + if $keystorefspath == false { + err('need to define a destination directory for sshkey creation!') + } + $ssh_keys = ssh_keygen("${keystorefspath}/${keydestname}") + } + + # deploy/manage the key + if $keymanage == true { + $keydestfile = "${keydest}/${keydestname}" + ensure_resource('file', $keydest, { + 'ensure' => 'directory', + 'mode' => '0700', + 'owner' => $keyowner, + 'group' => $keygroup + }) + ensure_resource('file', $keydestfile, { + 'ensure' => 'present', + 'source' => "${keystore}/${user}_id_${keytype}", + 'mode' => '0700', + 'owner' => $keyowner, + 'group' => $keygroup, + 'require' => File[$keydest], + }) + } +} diff --git a/puppet/modules/backupninja/manifests/labelmount.pp b/puppet/modules/backupninja/manifests/labelmount.pp new file mode 100644 index 00000000..8974cec1 --- /dev/null +++ b/puppet/modules/backupninja/manifests/labelmount.pp @@ -0,0 +1,62 @@ +# Mount a labelled partition on a directory as part of a backupninja run. +# +# This type will automatically create an unmount action with an order of 99 +# for the destination directory you specify here. +# +# Valid attributes for this type are: +# +# order: The prefix to give to the handler config filename, to set +# order in which the actions are executed during the backup run. Note +# that the value given here should be less than any action which +# requires the filesystem to be mounted! +# +# ensure: Allows you to delete an entry if you don't want it any more +# (but be sure to keep the configdir, name, and order the same, so +# that we can find the correct file to remove). +# +# label: The partition label to mount. +# +# dest: The directory to mount the partition onto. +# +define backupninja::labelmount($order = 10, + $ensure = present, + $label, + $dest + ) { + file { "${backupninja::configdir}/${order}_${name}.labelmount": + ensure => $ensure, + content => template('backupninja/labelmount.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::configdir}"] + } + + file { "${backupninja::configdir}/99_${name}.umount": + ensure => $ensure, + content => template('backupninja/umount.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::configdir}"] + } + + # Copy over the handler scripts themselves, since they're not in the + # standard distribution, and are unlikely to end up there any time + # soon because backupninja's "build" system is balls. + file { "/usr/share/backupninja/labelmount": + content => template('backupninja/labelmount.handler'), + owner => root, + group => root, + mode => 0755, + require => Package[backupninja] + } + + file { "/usr/share/backupninja/umount": + content => template('backupninja/umount.handler'), + owner => root, + group => root, + mode => 0755, + require => Package[backupninja] + } +} diff --git a/puppet/modules/backupninja/manifests/maildir.pp b/puppet/modules/backupninja/manifests/maildir.pp new file mode 100644 index 00000000..2454b82d --- /dev/null +++ b/puppet/modules/backupninja/manifests/maildir.pp @@ -0,0 +1,43 @@ +# maildir handler, as part of a backupninja run. +# +# The maildir handler slowly creates a backup of each user's +# maildir to a remote server. It is designed to be run with +# low overhead in terms of CPU and bandwidth, so it runs pretty +# slow. Hardlinking is used to save storage space. The actual +# maildir is stored within each snapshot directory. +# +# Valid attributes for this type are: +# +# order: The prefix to give to the handler config filename, to set +# order in which the actions are executed during the backup run. +# +# ensure: Allows you to delete an entry if you don't want it any more +# (but be sure to keep the configdir, name, and order the same, so +# that we can find the correct file to remove). +# +# +define backupninja::maildir( + $order = 99, $ensure = present, + $when = 'everyday at 21:00', $srcdir = false, + $destdir = false, $desthost = false, $destuser = false, $destid_file = false, + $remove = false, $multiconnection = yes, $keepdaily='4', $keepweekly='2', + $keepmonthly='2') +{ + # install client dependencies + ensure_resource('package', 'rsync', {'ensure' => $backupninja::ensure_rsync_version}) + + case $srcdir { false: { err("need to define a source directory to backup!") } } + case $destdir { false: { err("need to define a destination directory to backup!") } } + case $desthost { false: { err("need to define a destination host for backups!") } } + case $destuser { false: { err("need to define a destination user for backups!") } } + case $destid_file { false: { err("need to define a ssh key id file to use!") } } + + file { "${backupninja::configdir}/${order}_${name}.maildir": + ensure => $ensure, + content => template('backupninja/maildir.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::configdir}"] + } +} diff --git a/puppet/modules/backupninja/manifests/mysql.pp b/puppet/modules/backupninja/manifests/mysql.pp new file mode 100644 index 00000000..b8877c05 --- /dev/null +++ b/puppet/modules/backupninja/manifests/mysql.pp @@ -0,0 +1,38 @@ +# Safe MySQL dumps, as part of a backupninja run. +# +# Valid attributes for this type are: +# +# order: The prefix to give to the handler config filename, to set +# order in which the actions are executed during the backup run. +# +# ensure: Allows you to delete an entry if you don't want it any more +# (but be sure to keep the configdir, name, and order the same, so +# that we can find the correct file to remove). +# +# user, dbusername, dbpassword, dbhost, databases, backupdir, +# hotcopy, sqldump, compress, configfile: As defined in the +# backupninja documentation, with the caveat that hotcopy, sqldump, +# and compress take true/false rather than yes/no. +# +define backupninja::mysql( + $order = 10, $ensure = present, $user = false, $dbusername = false, $dbpassword = false, + $dbhost = 'localhost', $databases = 'all', $backupdir = false, $hotcopy = false, + $sqldump = false, $compress = false, $configfile = true, + $vsname = false, $sqldumpoptions = '--lock-tables --complete-insert --add-drop-table --quick --quote-names', + $nodata = false) +{ + + $real_configfile = $configfile ? { + true => "/etc/mysql/debian.cnf", + default => $configfile, + } + + file { "${backupninja::configdir}/${order}_${name}.mysql": + ensure => $ensure, + content => template('backupninja/mysql.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::configdir}"] + } +} diff --git a/puppet/modules/backupninja/manifests/nagios_plugin/duplicity.pp b/puppet/modules/backupninja/manifests/nagios_plugin/duplicity.pp new file mode 100644 index 00000000..7dbd2633 --- /dev/null +++ b/puppet/modules/backupninja/manifests/nagios_plugin/duplicity.pp @@ -0,0 +1,45 @@ +class backupninja::nagios_plugin::duplicity { + case $::operatingsystem { + 'Debian': { package { 'python-argparse': ensure => installed, } } + 'Ubuntu': { package { 'python-argh': ensure => installed, } } + default: { + notify {'Backupninja-Duplicity Nagios check needs python-argparse to be installed !':} } + } + + file { '/usr/lib/nagios/plugins/check_backupninja_duplicity.py': + source => 'puppet:///modules/backupninja/nagios_plugins/duplicity/check_backupninja_duplicity.py', + mode => '0755', + owner => 'nagios', + group => 'nagios', + } + + # deploy helper script + file { '/usr/lib/nagios/plugins/backupninja_duplicity_freshness.sh': + source => 'puppet:///modules/backupninja/nagios_plugins/duplicity/backupninja_duplicity_freshness.sh', + mode => '0755', + owner => 'nagios', + group => 'nagios', + } + + nagios::nrpe::command { 'check_backupninja_duplicity': + command_line => "sudo ${::nagios::nrpe::nagios_plugin_dir}/check_backupninja_duplicity.py" + } + sudo::spec {'nrpe_check_backupninja_duplicity': + ensure => present, + users => 'nagios', + hosts => 'ALL', + commands => "NOPASSWD: ${::nagios::nrpe::nagios_plugin_dir}/check_backupninja_duplicity.py"; + } + + nagios::service { "Backupninja Duplicity $::fqdn": + use_nrpe => true, + check_command => 'check_backupninja_duplicity', + nrpe_timeout => '60', + # check only twice a day + normal_check_interval => '720', + # recheck every hour + retry_check_interval => '60', + } + + +} diff --git a/puppet/modules/backupninja/manifests/pgsql.pp b/puppet/modules/backupninja/manifests/pgsql.pp new file mode 100644 index 00000000..d4814be9 --- /dev/null +++ b/puppet/modules/backupninja/manifests/pgsql.pp @@ -0,0 +1,27 @@ +# Safe PGSQL dumps, as part of a backupninja run. +# +# Valid attributes for this type are: +# +# order: The prefix to give to the handler config filename, to set +# order in which the actions are executed during the backup run. +# +# ensure: Allows you to delete an entry if you don't want it any more +# (but be sure to keep the configdir, name, and order the same, so +# that we can find the correct file to remove). +# +# backupdir, compress, configfile: As defined in the +# backupninja documentation, with the caveat that hotcopy, sqldump, +# and compress take true/false rather than yes/no. +# +define backupninja::pgsql( + $order = 10, $ensure = present, $databases = 'all', $backupdir = "/var/backups/postgres", $compress = true, $vsname = false) +{ + file { "${backupninja::configdir}/${order}_${name}.pgsql": + ensure => $ensure, + content => template('backupninja/pgsql.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::configdir}"] + } +} diff --git a/puppet/modules/backupninja/manifests/rdiff.pp b/puppet/modules/backupninja/manifests/rdiff.pp new file mode 100644 index 00000000..cd73d22c --- /dev/null +++ b/puppet/modules/backupninja/manifests/rdiff.pp @@ -0,0 +1,109 @@ +# Run rdiff-backup as part of a backupninja run. +# +# Valid attributes for this type are: +# +# order: The prefix to give to the handler config filename, to set +# order in which the actions are executed during the backup run. +# +# ensure: Allows you to delete an entry if you don't want it any more +# (but be sure to keep the configdir, name, and order the same, so +# that we can find the correct file to remove). +# +# keep, include, exclude, type, host, directory, user, sshoptions: As +# defined in the backupninja documentation. The options will be placed +# in the correct sections automatically. The include and exclude +# options should be given as arrays if you want to specify multiple +# directories. +# +define backupninja::rdiff( $order = 90, + $ensure = present, + # [general] + $options = '--force', + $extras = false, + # [source] + $include = [ "/var/spool/cron/crontabs", + "/var/backups", + "/etc", + "/root", + "/home", + "/usr/local/*bin", + "/var/lib/dpkg/status*" + ], + $exclude = [ "/home/*/.gnupg", + "/home/*/.local/share/Trash", + "/home/*/.Trash", + "/home/*/.thumbnails", + "/home/*/.beagle", + "/home/*/.aMule", + "/home/*/gtk-gnutella-downloads" + ], + $vsinclude = false, + # [dest] + $type = 'local', + $host = false, + $user = false, + $home = "/home/${user}-${name}", + $keep = 30, + $sshoptions = false, + # ssh keypair config + $key = false, + $keymanage = $backupninja::keymanage, + $backupkeystore = $backupninja::keystore, + $backupkeytype = $backupninja::keytype, + $ssh_dir_manage = true, + $ssh_dir = "${home}/.ssh", + $authorized_keys_file = 'authorized_keys', + # sandbox config + $installuser = true, + $backuptag = "backupninja-${::fqdn}", + # monitoring + $nagios_description = "backups-${name}" ) { + + # install client dependencies + ensure_resource('package', 'rdiff-backup', {'ensure' => $backupninja::ensure_rdiffbackup_version}) + + $directory = "$home/$name/" + + case $type { + 'remote': { + case $host { false: { err("need to define a host for remote backups!") } } + + backupninja::server::sandbox { "${user}-${name}": + user => $user, + host => $host, + dir => $home, + manage_ssh_dir => $ssh_dir_manage, + ssh_dir => $ssh_dir, + key => $key, + authorized_keys_file => $authorized_keys_file, + installuser => $installuser, + backuptag => $backuptag, + backupkeys => $backupkeystore, + keytype => $backupkeytype, + } + + backupninja::key { "${user}-${name}": + user => $user, + keymanage => $keymanage, + keytype => $backupkeytype, + keystore => $backupkeystore, + } + } + } + + + file { "${backupninja::configdir}/${order}_${name}.rdiff": + ensure => $ensure, + content => template('backupninja/rdiff.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::configdir}"] + } + + if $backupninja::manage_nagios { + nagios::service::passive { $nagios_description: } + } + +} + diff --git a/puppet/modules/backupninja/manifests/rsync.pp b/puppet/modules/backupninja/manifests/rsync.pp new file mode 100644 index 00000000..fc59950b --- /dev/null +++ b/puppet/modules/backupninja/manifests/rsync.pp @@ -0,0 +1,128 @@ +# Run rsync as part of a backupninja run. +# Based on backupninja::rdiff + +define backupninja::rsync( $order = 90, + $ensure = present, + # [general] + $log = false, + $partition = false, + $fscheck = false, + $read_only = false, + $mountpoint = false, + $format = false, + $days = false, + $keepdaily = false, + $keepweekly = false, + $keepmonthly = false, + $lockfile = false, + $nicelevel = 0, + $tmp = false, + $multiconnection = false, + $enable_mv_timestamp_bug = false, + # [source] + $include = [ "/var/spool/cron/crontabs", + "/var/backups", + "/etc", + "/root", + "/home", + "/usr/local/*bin", + "/var/lib/dpkg/status*" + ], + $exclude = [ "/home/*/.gnupg", + "/home/*/.local/share/Trash", + "/home/*/.Trash", + "/home/*/.thumbnails", + "/home/*/.beagle", + "/home/*/.aMule", + "/home/*/gtk-gnutella-downloads" + ], + # [dest] + $host = false, + $user = false, + $home = "/home/${user}-${name}", + $subfolder = 'rsync', + $testconnect = false, + $ssh = false, + $protocol = false, + $numericids = false, + $compress = false, + $port = false, + $bandwidthlimit = false, + $remote_rsync = false, + $batch = false, + $batchbase = false, + $fakesuper = false, + $id_file = false, + # [services] + $initscripts = false, + $service = false, + # [system] + $rm = false, + $cp = false, + $touch = false, + $mv = false, + $fsck = false, + # ssh keypair config + $key = false, + $keymanage = $backupninja::keymanage, + $backupkeystore = $backupninja::keystore, + $backupkeytype = $backupninja::keytype, + $ssh_dir_manage = true, + $ssh_dir = "${home}/.ssh", + $authorized_keys_file = 'authorized_keys', + # sandbox config + $installuser = true, + $backuptag = "backupninja-${::fqdn}", + # monitoring + $nagios_description = "backups-${name}" ) { + + # install client dependencies + ensure_resource('package', 'rsync', {'ensure' => $backupninja::ensure_rsync_version}) + + # Right now just local origin with remote destination is supported. + $from = 'local' + $dest = 'remote' + + case $dest { + 'remote': { + case $host { false: { err("need to define a host for remote backups!") } } + + $directory = "${home}/${subfolder}/" + + backupninja::server::sandbox { "${user}-${name}": + user => $user, + host => $host, + dir => $home, + manage_ssh_dir => $ssh_dir_manage, + ssh_dir => $ssh_dir, + key => $key, + authorized_keys_file => $authorized_keys_file, + installuser => $installuser, + backuptag => $backuptag, + keytype => $backupkeytype, + backupkeys => $backupkeystore, + } + + backupninja::key { "${user}-${name}": + user => $user, + keymanage => $keymanage, + keytype => $backupkeytype, + keystore => $backupkeystore, + } + } + } + + file { "${backupninja::configdir}/${order}_${name}.rsync": + ensure => $ensure, + content => template('backupninja/rsync.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::configdir}"] + } + + if $backupninja::manage_nagios { + nagios::service::passive { $nagios_description: } + } + +} diff --git a/puppet/modules/backupninja/manifests/server.pp b/puppet/modules/backupninja/manifests/server.pp new file mode 100644 index 00000000..49e42a0f --- /dev/null +++ b/puppet/modules/backupninja/manifests/server.pp @@ -0,0 +1,147 @@ +# this define realizes all needed resources for a hosted backup +define backupninja_server_realize($host) { + User <<| tag == "backupninja-$host" |>> + File <<| tag == "backupninja-$host" |>> + Ssh_authorized_key <<| tag == "backupninja-$host" |>> +} + +class backupninja::server ( + $backupdir = '/backup', + $backupdir_ensure = 'directory', + $manage_nagios = false, + $nagios_server = undef, + $nagios_warn_level = 129600, + $nagios_crit_level = 216000, +) { + + group { "backupninjas": + ensure => "present", + gid => 700 + } + + file { $backupdir: + ensure => $backupdir_ensure, + mode => 0710, owner => root, group => "backupninjas", + require => $backupdir_ensure ? { + 'directory' => undef, + default => File["$backupdir_ensure"], + } + } + + if $manage_nagios { + + case $nagios_server { undef: { err('Cannot manage nagios without nagios_server parameter!') } } + + include nagios::nsca::client + + file { "/usr/local/bin/checkbackups": + ensure => "present", + source => "puppet:///modules/backupninja/checkbackups.pl", + mode => 0755, owner => root, group => root, + } + + cron { checkbackups: + command => "/usr/local/bin/checkbackups -d ${backupdir} -s ${nagios_server} -w ${nagios_warn_level} -c ${nagios_crit_level} | grep -v 'sent to host successfully'", + user => "root", + hour => "8-23", + minute => 59, + require => [ File["/usr/local/bin/checkbackups"], Package['nsca'] ] + } + } + + # collect all resources from hosted backups + Backupninja_server_realize <<| tag == $::fqdn |>> + + # this define allows nodes to declare a remote backup sandbox, that have to + # get created on the server + define sandbox ( + $user = $name, + $host = $::fqdn, + $installuser = true, + $dir, + $manage_ssh_dir = true, + $ssh_dir = "${dir}/.ssh", + $authorized_keys_file = 'authorized_keys', + $key = false, + $keytype = 'dss', + $backupkeys = "${fileserver}/keys/backupkeys", + $uid = false, + $gid = "backupninjas", + $backuptag = "backupninja-${::fqdn}", + ) { + + if !defined(Backupninja_server_realize["${::fqdn}@${host}"]) { + @@backupninja_server_realize { "${::fqdn}@${host}": + host => $::fqdn, + tag => $host, + } + } + + if !defined(File["$dir"]) { + @@file { "$dir": + ensure => directory, + mode => 0750, owner => $user, group => 0, + tag => "$backuptag", + } + } + + if $installuser { + + if $manage_ssh_dir { + if !defined(File["$ssh_dir"]) { + @@file { "${ssh_dir}": + ensure => directory, + mode => 0700, owner => $user, group => 0, + require => [User[$user], File["$dir"]], + tag => "$backuptag", + } + } + } + + if $key { + # $key contais ssh public key + if !defined(Ssh_autorized_key["$user"]) { + @@ssh_authorized_key{ "$user": + type => $keytype, + key => $key, + user => $user, + target => "${ssh_dir}/${authorized_keys_file}", + tag => "$backuptag", + require => User[$user], + } + } + } + else { + # get ssh public key exists from server + if !defined(File["${ssh_dir}/${authorized_keys_file}"]) { + @@file { "${ssh_dir}/${authorized_keys_file}": + ensure => present, + mode => 0644, owner => 0, group => 0, + source => "${backupkeys}/${user}_id_${keytype}.pub", + require => File["${ssh_dir}"], + tag => "$backuptag", + } + } + } + + if !defined(User["$user"]) { + @@user { "$user": + ensure => "present", + uid => $uid ? { + false => undef, + default => $uid + }, + gid => "$gid", + comment => "$user backup sandbox", + home => "$dir", + managehome => true, + shell => "/bin/bash", + password => '*', + require => Group['backupninjas'], + tag => "$backuptag" + } + } + } + } +} + diff --git a/puppet/modules/backupninja/manifests/sh.pp b/puppet/modules/backupninja/manifests/sh.pp new file mode 100644 index 00000000..4a60e5fa --- /dev/null +++ b/puppet/modules/backupninja/manifests/sh.pp @@ -0,0 +1,25 @@ +# sh handler, as part of a backupninja run. +# +# Valid attributes for this type are: +# +# order: The prefix to give to the handler config filename, to set +# order in which the actions are executed during the backup run. +# +# ensure: Allows you to delete an entry if you don't want it any more +# (but be sure to keep the configdir, name, and order the same, so +# that we can find the correct file to remove). +# +# +define backupninja::sh($order = 50, + $ensure = present, + $command_string + ) { + file { "${backupninja::configdir}/${order}_${name}.sh": + ensure => $ensure, + content => template('backupninja/sh.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::configdir}"] + } +} diff --git a/puppet/modules/backupninja/manifests/svn.pp b/puppet/modules/backupninja/manifests/svn.pp new file mode 100644 index 00000000..1ab0597f --- /dev/null +++ b/puppet/modules/backupninja/manifests/svn.pp @@ -0,0 +1,28 @@ +# Subversion dumps, as part of a backupninja run. +# +# Valid attributes for this type are: +# +# order: The prefix to give to the handler config filename, to set +# order in which the actions are executed during the backup run. +# +# ensure: Allows you to delete an entry if you don't want it any more +# (but be sure to keep the configdir, name, and order the same, so +# that we can find the correct file to remove). +# +# +define backupninja::svn($order = 20, + $ensure = present, + $src = '/var/lib/svn', + $dest = '/var/backups/svn', + $tmp = '/var/backups/svn.tmp', + $vsname = false + ) { + file { "${backupninja::configdir}/${order}_${name}.svn": + ensure => $ensure, + content => template('backupninja/svn.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::configdir}"] + } +} diff --git a/puppet/modules/backupninja/manifests/sys.pp b/puppet/modules/backupninja/manifests/sys.pp new file mode 100644 index 00000000..946a525e --- /dev/null +++ b/puppet/modules/backupninja/manifests/sys.pp @@ -0,0 +1,45 @@ +# sys handler, as part of a backupninja run. +# +# Valid attributes for this type are: +# +# order: The prefix to give to the handler config filename, to set +# order in which the actions are executed during the backup run. +# +# ensure: Allows you to delete an entry if you don't want it any more +# (but be sure to keep the configdir, name, and order the same, so +# that we can find the correct file to remove). +# +# +define backupninja::sys($order = 30, + $ensure = present, + $parentdir = '/var/backups', + $packages = true, + $packagesfile = '/var/backups/dpkg-selections.txt', + $partitions = true, + $partitionsfile = '/var/backups/partitions.__star__.txt', + $dosfdisk = true, + $hardware = true, + $hardwarefile = '/var/backups/hardware.txt', + $dohwinfo = true, + $doluks = false, + $dolvm = false + ) { + + # install client dependencies + case $operatingsystem { + debian,ubuntu: { + ensure_resource('package', 'debconf-utils', {'ensure' => $backupninja::ensure_debconfutils_version}) + ensure_resource('package', 'hwinfo', {'ensure' => $backupninja::ensure_hwinfo_version}) + } + default: {} + } + + file { "${backupninja::configdir}/${order}_${name}.sys": + ensure => $ensure, + content => template('backupninja/sys.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::configdir}"] + } +} diff --git a/puppet/modules/backupninja/templates/backupninja.conf.erb b/puppet/modules/backupninja/templates/backupninja.conf.erb new file mode 100644 index 00000000..7706a615 --- /dev/null +++ b/puppet/modules/backupninja/templates/backupninja.conf.erb @@ -0,0 +1,25 @@ +# This configuration file was auto-generated by the Puppet configuration +# management system. Any changes you make to this file will be overwritten +# the next time Puppet runs. Please make configuration changes to this +# service in Puppet. + +loglevel = <%= @loglvl %> +when = <%= send(:when) %> +reportemail = <%= @reportemail %> +reportsuccess = <%= @reportsuccess ? 'yes' : 'no' %> +reportwarning = <%= @reportwarning ? 'yes' : 'no' %> +<% if reporthost.is_a? String -%> +<%= 'reporthost = ' + @reporthost %> +<% end -%> +<% if reportuser.is_a? String -%> +<%= 'reportuser = ' + @reportuser %> +<% end -%> +<% if reportdirectory.is_a? String -%> +<%= 'reportdirectory = ' + @reportdirectory %> +<% end -%> +logfile = <%= @logfile %> +configdirectory = <%= @configdir %> +scriptdirectory = <%= @scriptdir %> +libdirectory = <%= @libdir %> +usecolors = <%= @usecolors ? 'yes' : 'no' %> +vservers = <%= @vservers ? 'yes' : 'no' %> diff --git a/puppet/modules/backupninja/templates/backupninja.cron.erb b/puppet/modules/backupninja/templates/backupninja.cron.erb new file mode 100644 index 00000000..ec392ca9 --- /dev/null +++ b/puppet/modules/backupninja/templates/backupninja.cron.erb @@ -0,0 +1,6 @@ +# /etc/cron.d/backupninja -- cron tab entry for package backupninja + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +# # run backupninja +<%= min %> <%= hour %> <%= dom %> <%= month %> <%= dow %> root if [ -x <%= backupninja_test_cmd %> ]; then <%= backupninja_cmd %>; fi diff --git a/puppet/modules/backupninja/templates/dup.conf.erb b/puppet/modules/backupninja/templates/dup.conf.erb new file mode 100644 index 00000000..4f15e789 --- /dev/null +++ b/puppet/modules/backupninja/templates/dup.conf.erb @@ -0,0 +1,46 @@ +# This configuration file was auto-generated by the Puppet configuration +# management system. Any changes you make to this file will be overwritten +# the next time Puppet runs. Please make configuration changes to this +# service in Puppet. + +<%= 'options = ' + options if options %> +<%= 'nicelevel = ' + nicelevel if nicelevel %> +<%= 'testconnect = ' + testconnect if testconnect %> +<%= 'tmpdir = ' + tmpdir if tmpdir %> + +[gpg] +<%= 'sign = ' + sign if sign %> +<%= 'encryptkey = ' + encryptkey if encryptkey %> +<%= 'signkey = ' + signkey if signkey %> +<%= 'password = ' + password if password %> + +[source] +<% if include.is_a? String -%> +<%= 'include = ' + include %> +<% elsif include.is_a? Array -%> +<%= include.map { |i| "include = #{i}" }.join("\n") %> +<% end -%> + +<% if exclude.is_a? String -%> +<%= 'exclude = ' + exclude %> +<% elsif exclude.is_a? Array -%> +<%= exclude.map { |i| "exclude = #{i}" }.join("\n") %> +<% end -%> + +<% if vsinclude.is_a? String -%> +<%= 'vsinclude = ' + vsinclude %> +<% elsif vsinclude.is_a? Array -%> +<%= vsinclude.map { |i| "vsinclude = #{i}" }.join("\n") %> +<% end -%> + +[dest] +<%= 'incremental = ' + incremental if incremental %> +<%= 'increments = ' + increments if increments %> +<%= 'keep = ' + keep if keep %> +<%= 'keepincroffulls = ' + keepincroffulls if keepincroffulls %> +<%= 'bandwidthlimit = ' + bandwidthlimit if bandwidthlimit %> +<%= 'sshoptions = ' + sshoptions if sshoptions %> +<%= 'destdir = ' + destdir if destdir %> +<%= 'desthost = ' + desthost if desthost %> +<%= 'destuser = ' + destuser if destuser %> +<%= 'desturl = ' + desturl if desturl %> diff --git a/puppet/modules/backupninja/templates/labelmount.conf.erb b/puppet/modules/backupninja/templates/labelmount.conf.erb new file mode 100644 index 00000000..e40c49d3 --- /dev/null +++ b/puppet/modules/backupninja/templates/labelmount.conf.erb @@ -0,0 +1,2 @@ +label = <%= label %> +dest = <%= dest %> diff --git a/puppet/modules/backupninja/templates/labelmount.handler b/puppet/modules/backupninja/templates/labelmount.handler new file mode 100644 index 00000000..22090bd4 --- /dev/null +++ b/puppet/modules/backupninja/templates/labelmount.handler @@ -0,0 +1,17 @@ +#!/bin/sh + +# Mount a block device with the specified label ('label') onto the given +# directory ('dest'). + +getconf label +getconf dest + +if [ ! -b "/dev/disk/by-label/$label" ]; then + halt "No partition labelled '$label' is available" +fi + +if [ ! -d "$dest" ]; then + halt "Destination directory does not exist" +fi + +mount -t auto /dev/disk/by-label/$label $dest || halt "Mount failed" diff --git a/puppet/modules/backupninja/templates/maildir.conf.erb b/puppet/modules/backupninja/templates/maildir.conf.erb new file mode 100644 index 00000000..351f3824 --- /dev/null +++ b/puppet/modules/backupninja/templates/maildir.conf.erb @@ -0,0 +1,14 @@ +# This configuration file was auto-generated by the Puppet configuration +# management system. Any changes you make to this file will be overwritten +# the next time Puppet runs. Please make configuration changes to this +# service in Puppet. + +<% %w{when srcdir destdir desthost destuser destid_file keepdaily keepweekly keepmonthly}.each do |v| + if send(v) + -%><%= v + ' = ' + send(v) + "\n" %><% + end +end -%> + +remove = <%= remove ? 'yes' : 'no' %> +multiconnection = <%= multiconnection ? 'yes' : 'no' %> + diff --git a/puppet/modules/backupninja/templates/mysql.conf.erb b/puppet/modules/backupninja/templates/mysql.conf.erb new file mode 100644 index 00000000..b7ac5e8f --- /dev/null +++ b/puppet/modules/backupninja/templates/mysql.conf.erb @@ -0,0 +1,25 @@ +# This configuration file was auto-generated by the Puppet configuration +# management system. Any changes you make to this file will be overwritten +# the next time Puppet runs. Please make configuration changes to this +# service in Puppet. + +<% %w{user dbusername dbpassword dbhost databases backupdir vsname sqldumpoptions}.each do |v| + if send(v) + -%><%= v + ' = ' + send(v) + "\n" %><% + end +end -%> + +hotcopy = <%= hotcopy ? 'yes' : 'no' %> +sqldump = <%= sqldump ? 'yes' : 'no' %> +compress = <%= compress ? 'yes' : 'no' %> + +<% if real_configfile %> +configfile = <%= real_configfile %> +<% end %> + +<% if nodata.is_a? String -%> +<%= 'nodata = ' + nodata %> +<% elsif nodata.is_a? Array -%> +<%= "nodata = " + nodata.map { |i| "#{i}" }.join(" ") %> +<% end -%> + diff --git a/puppet/modules/backupninja/templates/pgsql.conf.erb b/puppet/modules/backupninja/templates/pgsql.conf.erb new file mode 100644 index 00000000..5ffa89c0 --- /dev/null +++ b/puppet/modules/backupninja/templates/pgsql.conf.erb @@ -0,0 +1,13 @@ +<% if vsname %> +vsname = <%= vsname %> +<% end %> +<% if backupdir %> +backupdir = <%= backupdir %> +<% end %> +<% if databases.is_a? String -%> +<%= 'databases = ' + databases %> +<% elsif databases.is_a? Array -%> +<%= "databases = " + databases.map { |i| "#{i}" }.join(" ") %> +<% end -%> +compress = <%= compress ? 'yes' : 'no' %> + diff --git a/puppet/modules/backupninja/templates/rdiff.conf.erb b/puppet/modules/backupninja/templates/rdiff.conf.erb new file mode 100644 index 00000000..23c336fc --- /dev/null +++ b/puppet/modules/backupninja/templates/rdiff.conf.erb @@ -0,0 +1,38 @@ +# This configuration file was auto-generated by the Puppet configuration +# management system. Any changes you make to this file will be overwritten +# the next time Puppet runs. Please make configuration changes to this +# service in Puppet. + +<%= 'options = ' + options if options %> + +<%= extras if extras %> + +[source] +type = local +<%= 'keep = ' + keep if keep %> + +<% if include.is_a? String -%> +<%= 'include = ' + include %> +<% elsif include.is_a? Array -%> +<%= include.map { |i| "include = #{i}" }.join("\n") %> +<% end -%> + +<% if exclude.is_a? String -%> +<%= 'exclude = ' + exclude %> +<% elsif exclude.is_a? Array -%> +<%= exclude.map { |i| "exclude = #{i}" }.join("\n") %> +<% end -%> + +<% if vsinclude.is_a? String -%> +<%= 'vsinclude = ' + vsinclude %> +<% elsif vsinclude.is_a? Array -%> +<%= vsinclude.map { |i| "vsinclude = #{i}" }.join("\n") %> +<% end -%> + +[dest] +<%- %w{type host directory user sshoptions}.each do |v| + if has_variable?(v) and instance_variable_get("@#{v}").to_s != "false" -%> +<%= v + ' = ' + instance_variable_get("@#{v}").to_s %> +<%- + end +end -%> diff --git a/puppet/modules/backupninja/templates/rsync.conf.erb b/puppet/modules/backupninja/templates/rsync.conf.erb new file mode 100644 index 00000000..778676fc --- /dev/null +++ b/puppet/modules/backupninja/templates/rsync.conf.erb @@ -0,0 +1,49 @@ +# This configuration file was auto-generated by the Puppet configuration +# management system. Any changes you make to this file will be overwritten +# the next time Puppet runs. Please make configuration changes to this +# service in Puppet. + +[general] +<%- %w{log partition fscheck read_only mountpoint backupdir format days keepdaily keepweekly keepmonthly lockfile nicelevel enable_mv_timestamp_bug, tmp, multiconnection}.each do |v| + if has_variable?(v) and instance_variable_get("@#{v}").to_s != "false" -%> +<%= v + ' = ' + instance_variable_get("@#{v}").to_s %> +<%- + end +end -%> + +[source] +<% unless from.empty? and from.to_s != "false" -%> +from = <%= from %> +<% end -%> +<%- %w{include exclude}.each do |v| + if has_variable?(v) + instance_variable_get("@#{v}").to_a.each do |parameter| -%> +<%= v + ' = ' + parameter %> +<%- + end + end +end -%> + +[dest] +<%- %w{dest testconnect ssh protocol numericids compress host port user id_file bandwidthlimit remote_rsync batch batchbase fakesuper}.each do |v| + if has_variable?(v) and instance_variable_get("@#{v}").to_s != "false" -%> +<%= v + ' = ' + instance_variable_get("@#{v}").to_s %> +<%- + end +end -%> + +[services] +<%- %w{initscripts service}.each do |v| + if has_variable?(v) and instance_variable_get("@#{v}").to_s != "false" -%> +<%= v + ' = ' + instance_variable_get("@#{v}").to_s %> +<%- + end +end -%> + +[system] +<%- %w{rm cp touch mv fsck}.each do |v| + if has_variable?(v) and instance_variable_get("@#{v}").to_s != "false" -%> +<%= v + ' = ' + instance_variable_get("@#{v}").to_s %> +<%- + end +end -%> diff --git a/puppet/modules/backupninja/templates/sh.conf.erb b/puppet/modules/backupninja/templates/sh.conf.erb new file mode 100644 index 00000000..f1b4161a --- /dev/null +++ b/puppet/modules/backupninja/templates/sh.conf.erb @@ -0,0 +1,10 @@ +#!/bin/sh +# +# This configuration file was auto-generated by the Puppet configuration +# management system. Any changes you make to this file will be overwritten +# the next time Puppet runs. Please make configuration changes to this +# service in Puppet. + +<% @command_string.each_line do |line| -%> +<%= line %> +<% end -%> diff --git a/puppet/modules/backupninja/templates/svn.conf.erb b/puppet/modules/backupninja/templates/svn.conf.erb new file mode 100644 index 00000000..465cc673 --- /dev/null +++ b/puppet/modules/backupninja/templates/svn.conf.erb @@ -0,0 +1,10 @@ +# This configuration file was auto-generated by the Puppet configuration +# management system. Any changes you make to this file will be overwritten +# the next time Puppet runs. Please make configuration changes to this +# service in Puppet. + +<% %w{src dest tmp vsname}.each do |v| + if send(v) + -%><%= v + ' = ' + send(v) + "\n" %><% + end +end -%> \ No newline at end of file diff --git a/puppet/modules/backupninja/templates/sys.conf.erb b/puppet/modules/backupninja/templates/sys.conf.erb new file mode 100644 index 00000000..a684e8b7 --- /dev/null +++ b/puppet/modules/backupninja/templates/sys.conf.erb @@ -0,0 +1,18 @@ +# This configuration file was auto-generated by the Puppet configuration +# management system. Any changes you make to this file will be overwritten +# the next time Puppet runs. Please make configuration changes to this +# service in Puppet. + +<% %w{parentdir packagesfile partitionsfile hardwarefile}.each do |v| + if send(v) + -%><%= v + ' = ' + send(v) + "\n" %><% + end +end -%> + +packages = <%= packages ? 'yes' : 'no' %> +partitions = <%= partitions ? 'yes' : 'no' %> +dosfdisk = <%= dosfdisk ? 'yes' : 'no' %> +hardware = <%= hardware ? 'yes' : 'no' %> +dohwinfo = <%= dohwinfo ? 'yes' : 'no' %> +luksheaders = <%= doluks ? 'yes' : 'no' %> +lvm = <%= dolvm ? 'yes' : 'no' %> diff --git a/puppet/modules/backupninja/templates/umount.conf.erb b/puppet/modules/backupninja/templates/umount.conf.erb new file mode 100644 index 00000000..59bfaec8 --- /dev/null +++ b/puppet/modules/backupninja/templates/umount.conf.erb @@ -0,0 +1 @@ +dir = <%= dest %> diff --git a/puppet/modules/backupninja/templates/umount.handler b/puppet/modules/backupninja/templates/umount.handler new file mode 100644 index 00000000..4fea195a --- /dev/null +++ b/puppet/modules/backupninja/templates/umount.handler @@ -0,0 +1,15 @@ +#!/bin/sh + +# Unmount the specified directory ('dir'), forcefully if necessary. + +getconf dir + +if ! umount $dir; then + warning "Simple unmount failed for $dir; being forceful" + if ! umount -f $dir; then + warning "Forceful unmount failed for $dir; being lazy" + if ! umount -l $dir; then + warning "Lazy unmount failed for $dir; you're on your own" + fi + fi +fi -- cgit v1.2.3 From a75fea409bf8e62e55ba341672c202aab5fa480e Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:46:31 -0400 Subject: git subrepo clone https://leap.se/git/puppet_sysctl puppet/modules/sysctl subrepo: subdir: "puppet/modules/sysctl" merged: "975852b" upstream: origin: "https://leap.se/git/puppet_sysctl" branch: "master" commit: "975852b" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: Ica1925ea414df32850d0358ae17d6c704ae6fa7d --- puppet/modules/sysctl/.gitrepo | 11 +++++++++++ puppet/modules/sysctl/README | 20 ++++++++++++++++++++ puppet/modules/sysctl/manifests/config.pp | 18 ++++++++++++++++++ puppet/modules/sysctl/manifests/init.pp | 10 ++++++++++ 4 files changed, 59 insertions(+) create mode 100644 puppet/modules/sysctl/.gitrepo create mode 100644 puppet/modules/sysctl/README create mode 100644 puppet/modules/sysctl/manifests/config.pp create mode 100644 puppet/modules/sysctl/manifests/init.pp (limited to 'puppet/modules') diff --git a/puppet/modules/sysctl/.gitrepo b/puppet/modules/sysctl/.gitrepo new file mode 100644 index 00000000..a6d7f8fe --- /dev/null +++ b/puppet/modules/sysctl/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_sysctl + branch = master + commit = 975852b7acc1125b4cd9d4d490b9abd8d31217e6 + parent = 6a895ece94a86c9ccc32c9bec51413d4e4f0df8e + cmdver = 0.3.0 diff --git a/puppet/modules/sysctl/README b/puppet/modules/sysctl/README new file mode 100644 index 00000000..a3980f70 --- /dev/null +++ b/puppet/modules/sysctl/README @@ -0,0 +1,20 @@ +sysctl module +------------- + +This puppet module handles the setting of variables in sysctl.conf, its +a simple module that utilizes the puppet augeas built-in type and the +sysctl binary. You must have the augeas ruby libraries installed to +use this type. + +You can set a value and a comment for that value using this module, +some examples: + +sysctl::config { "vm.mmap_min_addr": + value => 32768, + comment => "Never mmap into the first 32k of memory", +} + +sysctl::config { "fs.file-max": + value => 65536, + comment => "Maximum number of filehandles", +} diff --git a/puppet/modules/sysctl/manifests/config.pp b/puppet/modules/sysctl/manifests/config.pp new file mode 100644 index 00000000..79ddd295 --- /dev/null +++ b/puppet/modules/sysctl/manifests/config.pp @@ -0,0 +1,18 @@ +define sysctl::config ($value, $comment) { + + include sysctl + + augeas { "sysctl_${name}": + context => '/files/etc/sysctl.conf', + changes => [ "set ${name} ${value}", "insert #comment before ${name}", + "set #comment[last()] '${comment}'" ], + onlyif => "get ${name} != ${value}", + notify => Exec["sysctl_${name}"], + } + + exec { "sysctl_${name}": + command => '/sbin/sysctl -p', + subscribe => File['/etc/sysctl.conf'], + refreshonly => true, + } +} diff --git a/puppet/modules/sysctl/manifests/init.pp b/puppet/modules/sysctl/manifests/init.pp new file mode 100644 index 00000000..43d9299e --- /dev/null +++ b/puppet/modules/sysctl/manifests/init.pp @@ -0,0 +1,10 @@ +class sysctl { + + file { '/etc/sysctl.conf': + ensure => present, + mode => '0644', + owner => root, + group => root + } +} + -- cgit v1.2.3 From 56a771a3008d10720dd05fd815aeafbacdd1e08e Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:46:32 -0400 Subject: git subrepo clone https://leap.se/git/puppet_check_mk puppet/modules/check_mk subrepo: subdir: "puppet/modules/check_mk" merged: "aa02571" upstream: origin: "https://leap.se/git/puppet_check_mk" branch: "master" commit: "aa02571" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: I6cb060eb80966dd6ae346f7a8105289caa9ccbaf --- puppet/modules/check_mk/.gitignore | 3 + puppet/modules/check_mk/.gitrepo | 11 + puppet/modules/check_mk/Changelog | 27 + puppet/modules/check_mk/LICENSE | 674 +++++++++++++++++++++ puppet/modules/check_mk/Modulefile | 10 + puppet/modules/check_mk/README.md | 268 ++++++++ puppet/modules/check_mk/Rakefile | 2 + puppet/modules/check_mk/TODO | 5 + puppet/modules/check_mk/debian.md | 35 ++ puppet/modules/check_mk/example.yaml | 93 +++ .../files/agent/local_checks/all_hosts/README.md | 2 + puppet/modules/check_mk/files/use_ssh.mk | 5 + puppet/modules/check_mk/manifests/agent.pp | 70 +++ puppet/modules/check_mk/manifests/agent/config.pp | 59 ++ .../check_mk/manifests/agent/generate_sshkey.pp | 70 +++ puppet/modules/check_mk/manifests/agent/install.pp | 70 +++ .../check_mk/manifests/agent/install_local.pp | 12 + .../check_mk/manifests/agent/local_checks.pp | 11 + puppet/modules/check_mk/manifests/agent/mrpe.pp | 19 + puppet/modules/check_mk/manifests/agent/ps.pp | 17 + .../modules/check_mk/manifests/agent/register.pp | 8 + puppet/modules/check_mk/manifests/agent/service.pp | 8 + puppet/modules/check_mk/manifests/config.pp | 109 ++++ puppet/modules/check_mk/manifests/host.pp | 18 + puppet/modules/check_mk/manifests/hostgroup.pp | 24 + puppet/modules/check_mk/manifests/htpasswd.pp | 12 + puppet/modules/check_mk/manifests/init.pp | 44 ++ puppet/modules/check_mk/manifests/install.pp | 50 ++ .../modules/check_mk/manifests/install_tarball.pp | 92 +++ puppet/modules/check_mk/manifests/omd_repo.pp | 6 + puppet/modules/check_mk/manifests/ps.pp | 34 ++ .../check_mk/manifests/server/collect_hosts.pp | 6 + .../check_mk/manifests/server/collect_ps.pp | 30 + .../check_mk/manifests/server/configure_ssh.pp | 16 + puppet/modules/check_mk/manifests/service.pp | 23 + .../modules/check_mk/templates/agent/check_mk.erb | 39 ++ puppet/modules/check_mk/templates/main.mk.erb | 4 + puppet/modules/check_mk/templates/setup.conf.erb | 29 + 38 files changed, 2015 insertions(+) create mode 100644 puppet/modules/check_mk/.gitignore create mode 100644 puppet/modules/check_mk/.gitrepo create mode 100644 puppet/modules/check_mk/Changelog create mode 100644 puppet/modules/check_mk/LICENSE create mode 100644 puppet/modules/check_mk/Modulefile create mode 100644 puppet/modules/check_mk/README.md create mode 100644 puppet/modules/check_mk/Rakefile create mode 100644 puppet/modules/check_mk/TODO create mode 100644 puppet/modules/check_mk/debian.md create mode 100644 puppet/modules/check_mk/example.yaml create mode 100644 puppet/modules/check_mk/files/agent/local_checks/all_hosts/README.md create mode 100644 puppet/modules/check_mk/files/use_ssh.mk create mode 100644 puppet/modules/check_mk/manifests/agent.pp create mode 100644 puppet/modules/check_mk/manifests/agent/config.pp create mode 100644 puppet/modules/check_mk/manifests/agent/generate_sshkey.pp create mode 100644 puppet/modules/check_mk/manifests/agent/install.pp create mode 100644 puppet/modules/check_mk/manifests/agent/install_local.pp create mode 100644 puppet/modules/check_mk/manifests/agent/local_checks.pp create mode 100644 puppet/modules/check_mk/manifests/agent/mrpe.pp create mode 100644 puppet/modules/check_mk/manifests/agent/ps.pp create mode 100644 puppet/modules/check_mk/manifests/agent/register.pp create mode 100644 puppet/modules/check_mk/manifests/agent/service.pp create mode 100644 puppet/modules/check_mk/manifests/config.pp create mode 100644 puppet/modules/check_mk/manifests/host.pp create mode 100644 puppet/modules/check_mk/manifests/hostgroup.pp create mode 100644 puppet/modules/check_mk/manifests/htpasswd.pp create mode 100644 puppet/modules/check_mk/manifests/init.pp create mode 100644 puppet/modules/check_mk/manifests/install.pp create mode 100644 puppet/modules/check_mk/manifests/install_tarball.pp create mode 100644 puppet/modules/check_mk/manifests/omd_repo.pp create mode 100644 puppet/modules/check_mk/manifests/ps.pp create mode 100644 puppet/modules/check_mk/manifests/server/collect_hosts.pp create mode 100644 puppet/modules/check_mk/manifests/server/collect_ps.pp create mode 100644 puppet/modules/check_mk/manifests/server/configure_ssh.pp create mode 100644 puppet/modules/check_mk/manifests/service.pp create mode 100644 puppet/modules/check_mk/templates/agent/check_mk.erb create mode 100644 puppet/modules/check_mk/templates/main.mk.erb create mode 100644 puppet/modules/check_mk/templates/setup.conf.erb (limited to 'puppet/modules') diff --git a/puppet/modules/check_mk/.gitignore b/puppet/modules/check_mk/.gitignore new file mode 100644 index 00000000..f6dc3f68 --- /dev/null +++ b/puppet/modules/check_mk/.gitignore @@ -0,0 +1,3 @@ +pkg/ +metadata.json +*.swp diff --git a/puppet/modules/check_mk/.gitrepo b/puppet/modules/check_mk/.gitrepo new file mode 100644 index 00000000..05058447 --- /dev/null +++ b/puppet/modules/check_mk/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_check_mk + branch = master + commit = aa02571537af90ac73309e6e216c9417802548c3 + parent = a75fea409bf8e62e55ba341672c202aab5fa480e + cmdver = 0.3.0 diff --git a/puppet/modules/check_mk/Changelog b/puppet/modules/check_mk/Changelog new file mode 100644 index 00000000..0b2f8a15 --- /dev/null +++ b/puppet/modules/check_mk/Changelog @@ -0,0 +1,27 @@ +0.3.0: + +* Added host tags to agent config so that host groups can be auto-populated + +* Fixed incorrect package name when using a file store that was causing the +package existence check to fail always causing an often failing reinstall + +* Enable a static list of hosts to be specified for those without the Puppet +check_mk module installed + +0.2.0: + +* Switched to using OMD rather than manually compiling check_mk + +* Added support for host tags and creating host groups based on these tags + +* Allow local check_mk configuration to be specified in +/etc/check_mk/main.mk.local that is appended to /etc/check_mk/main.mk as +check_mk can do a lot more than is covered by this module + +0.1.1: + +* Brown paper bag release to fix a silly typo + +0.1: + +* Initial release diff --git a/puppet/modules/check_mk/LICENSE b/puppet/modules/check_mk/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/puppet/modules/check_mk/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/puppet/modules/check_mk/Modulefile b/puppet/modules/check_mk/Modulefile new file mode 100644 index 00000000..60c355a3 --- /dev/null +++ b/puppet/modules/check_mk/Modulefile @@ -0,0 +1,10 @@ +name 'erwbgy-check_mk' +version '0.3.0' +source 'https://github.com/erwbgy/puppet-check_mk.git' +author 'erwbgy' +license 'Apache License, Version 2.0' +summary 'install and configure check_mk' +description 'Install and configure check_mk agent and Nagios plugin' +project_page 'https://github.com/erwbgy/puppet-check_mk' +dependency 'puppetlabs/stdlib', '>= 2.6.0' +dependency 'ripienaar/concat', '>= 0.2.0' diff --git a/puppet/modules/check_mk/README.md b/puppet/modules/check_mk/README.md new file mode 100644 index 00000000..81e1bc87 --- /dev/null +++ b/puppet/modules/check_mk/README.md @@ -0,0 +1,268 @@ +# check_mk + +Puppet module for: + +* Installing and configuring the Open Monitoring Distribution (OMD) which + includes Nagios, check_mk and lots of other tools + +* Installing and configuring check_mk agents + +Agent hostnames are automatically added to the server all_hosts configuration +using stored configs. + +Currently only tested on Redhat-like systems and on Debian. + +For examples how to use this class on a debian wheezy system, check out following +snippets: https://git.codecoop.org/snippets/1, https://git.codecoop.org/snippets/2 + +## Server + +* Installs omd package either using the system repository (eg. yum, apt) or + from a package file retrieved from the Puppet file store + +* Use check_mk::omd_repo to enable a debian repository for omd + (requires apt module from i.e. https://labs.riseup.net/code/projects/shared-apt). + For now, you need to fetch the omd apt-key manually from + http://labs.consol.de/nagios/omd-repository/, put it into your site_apt/files/keys + directory and pass the custom_key_dir parameter to the apt class, like + + + class { 'apt': + custom_key_dir => 'puppet:///modules/site-apt/keys' + } + +* Populates the all_hosts array in /etc/check_mk/main.mk with hostnames + exported by check::agent classes on agent hosts + +### Example 1 + + include check_mk + +Installs the 'monitoring' package from the system repository. The default 'monitoring' site is used. + +### Example 2 + + class { 'check_mk': + filestore => 'puppet:///files/check_mk', + package => 'omd-0.56-rh60-29.x86_64.rpm' + } + +Installs the specified omd package after retrieving it from the Puppet file store. + +### Example 3 + + class { 'check_mk': + site => 'acme', + } + +Installs the omd package from the system repository. A site called 'acme' is +created making the URL http://hostname/acme/check_mk/ running as the 'acme' user. + +### check_mk parameters + +*package*: The omd package (rpm or deb) to install. Optional. + +*filestore*: The Puppet file store location where the package can be found (eg. 'puppet:///files/check_mk'). Optional. + +*host_groups*: A hash with the host group names as the keys with a list of host tags to match as values. (See 'Host groups and tags' below). Optional. + +*site*: The name of the omd site (and the user/group it runs as). Default: 'monitoring' + +*workspace*: The directory to use to store files used during installation. Default: '/root/check_mk' + +*omdadmin_htpasswd*: changes the htpasswd of the amdadmin user (requires apache module from i.e. + https://labs.riseup.net/code/projects/shared-apache) + +*use_ssh*: Configures ssh to agents that use the same parameter. + Default: false. + +*inventory_only_on_changes*: By default (parameter set to `true`) these two execs are called + only when config files changes: + - Exec['check_mk-refresh'] (which runs a check inventory by calling `check_mk -II`) + - Exec['check_mk-reload'] (which generates the nagios config and reloads nagios by calling `check_mk -O`) + By setting this parameter to `false` these execs will be called on each puppetrun. + +### Notes + +* A user and group with the same value as the site parameter is created. By default this is 'monitoring'. + +* The URL is http://yourhostname/sitename/check_mk/ - for example http://monhost.domain/monitoring/check_mk/ + +* The default username/password is omdadmin/omd. To change this or add additional users log in as the site user and run htpasswd - for example: + + monitoring$ htpasswd -b ~/etc/htpasswd guest guest + +* A user called 'guest' is configured as a guest user but is not enabled unless a password is set (as above). + +* RedHat-like RPM downloads from http://files.omdistro.org/releases/centos_rhel/ + +## Agent + +* Installs the check_mk-agent and check_mk-agent-logwatch packages + +* Configures the /etc/xinetd.d/check_mk configuration file + +### Example 1 + + include check_mk::agent + +Installs the check_mk and check_mk_logwatch packages from the system repository +and configures /etc/xinetd.d/check_mk with no IP whitelist restrictions. + +### Example 2 + + class { 'check_mk::agent': + version => '1.2.0p3-1', + ip_whitelist => [ '10.7.96.21', '10.7.96.22' ], + } + +Installs the specified versions of the check_mk and check_mk_logwatch packages +after retrieving them from the Puppet file store. Configures +/etc/xinetd.d/check_mk so that only the specified IPs (and localhost/127.0.0.1) +are allowed to connect. + +### check_mk::agent parameters + +*filestore*: The Puppet file store location where the packages can be found (eg. 'puppet:///files/check_mk'). Optional. + +*ip_whitelist*: The list of IP addresses that are allowed to retrieve check_mk +data. (Note that localhost is always allowed to connect.) By default any IP can +connect. + +*port*: The port the check_mk agent listens on. Default: '6556' + +*server_dir*: The directory in which the check_mk_agent executable is located. +Default: '/usr/bin' + +*use_cache*: Whether or not to cache the results - useful with redundant +monitoring server setups. Default: 'false' + +*user*: The user that the agent runs as. Default: 'root' + +*version*: The version in the check_mk packages - for example if the RPM is +'check_mk-agent-1.2.0p3-1.noarch.rpm' then the version is '1.2.0p3-1'. +Only required if a filestore is used. + +*workspace*: The directory to use to store files used during installation. +Default: '/root/check_mk' + +*method*: "xinetd" (default) or "ssh" + "ssh": Use ssh instead of the tcp wrapper in order to allows the server to + execute the agent on the client. + +*generate_sshkey*: true or false (default) + + * Deploys ssh keypair on server (in /opt/omd/sites/monitoring/.ssh) + * Saves keypair on puppetmaster (/etc/puppet/modules/keys/files/check_mk_keys by default) + * Deploys public key on client in /root/.ssh/authorized_keys (restricting allows command to "/usr/bin/check_mk_agent") + +## Host groups and tags + +By default check_mk puts all hosts into a group called 'check_mk' but where you +have more than a few you will often want your own groups. We can do this by +setting host tags on the agents and then configuring host groups on the server +side to match hosts with these tags. + +For example in the hiera config for your agent hosts you could have: + + check_mk::agent::host_tags: + - '%{osfamily}' + +and on the monitoring host you could have: + + check_mk::host_groups: + RedHat: + description: 'RedHat or_CentOS hosts' + host_tags: + - RedHat + Debian: + description: 'Debian or Ubuntu_hosts' + host_tags: + - Debian + SuSE: + description: 'SuSE hosts' + host_tags: + - Suse + +You can of course have as many host tags as you like. I have custom facts for +the server role and the environment type (dev, qa, stage, prod) and define +groups based on the role and envtype host tags. + +Remember to run the Puppet agent on your agent hosts to export any host tags +and run the Puppet agent on the monitoring host to pick up any changes to the +host groups. + +## Static host config + +Hosts that do not run Puppet with the check_mk module are not automatically +added to the all_hosts list in main.mk. To manually include these hosts you can +add them to '/omd/sites/monitoring/etc/check_mk/all_hosts_static' (replacing +'monitoring' with your site name). Use the quoted fully qualified domain name +with a two-space prefix and a comma suffix - for example: + + 'host1.domain', + 'host2.domain', + +You can also include host tags - for example: + + 'host1.domain|windows|dev', + 'host2.domain|windows|prod', + +Remember to run the Puppet agent on your monitoring host to pick up any changes. + +## Migrating from nagios-statd + +nagios-statd provides several features that can be replaced with check_mk +plugins. + +*nagios-stat-proc*: checks processes on the agent system +If you previously used the nagios puppet module to do something like: + + check_command => 'nagios-stat-proc!/usr/sbin/foo!1!1!proc' + +you can now use the check_mk ps check: + + check_mk::agent::ps { + 'foo': + procname => '/usr/local/weirdpath/foo', + levels => '1, 2, 2, 3', + owner => 'alice' + } + +defaults: + procname: "/usr/sbin/${name}" + levels: '1, 1, 1, 1' + owner: not required + +Run check_mk with '-M ps' for the manpage explaining the parameters. + +*swap*: check_mk has a 'mem.used' check which is enabled by default. But + as it's manpage explains if you want to measure swappiness you are + better off using the 'kernel' check and measuring 'Major Page Faults' + (pgmajfault). + +*disk*: check_mk has a 'df' check which is enabled by default. + +## Migrating from nrpe to mrpe + +If you were using nrpe to run a nagios plugin locally, first check if a +native check_mk check exists with the same functionality, if not consider +writing one. But if continuing to use the nagios plugin makes sense you +can switch to mrpe. + +* Continue to deliver the plugin to the agent system +* include check_mk::agent::mrpe +* add a line to the mrpe.cfg file using augeas + + augeas { + "Foo": + incl => '/etc/check_mk/mrpe.cfg', + lens => 'Spacevars.lns', + changes => 'set FOO /usr/local/lib/nagios/plugins/check_foo', + require => [ File['/usr/local/lib/nagios/plugins' ], Package['check-mk-agent'] ]; + } + + +This is the riseup clone, available at: + +git://labs.riseup.net/module_check_mk diff --git a/puppet/modules/check_mk/Rakefile b/puppet/modules/check_mk/Rakefile new file mode 100644 index 00000000..14f1c246 --- /dev/null +++ b/puppet/modules/check_mk/Rakefile @@ -0,0 +1,2 @@ +require 'rubygems' +require 'puppetlabs_spec_helper/rake_tasks' diff --git a/puppet/modules/check_mk/TODO b/puppet/modules/check_mk/TODO new file mode 100644 index 00000000..1697f34b --- /dev/null +++ b/puppet/modules/check_mk/TODO @@ -0,0 +1,5 @@ +Use nagios_hostgroup type rather than clumsily creating our own. +Add support for ignored_services to eliminate false alerts. +Implement support for choosing either upstream install or distro supplied + packages. If using distro packages, detect distro and set package names + to reasonable default (currently requires overriding). diff --git a/puppet/modules/check_mk/debian.md b/puppet/modules/check_mk/debian.md new file mode 100644 index 00000000..96d32a4e --- /dev/null +++ b/puppet/modules/check_mk/debian.md @@ -0,0 +1,35 @@ +Examples for using this check_mk repository on debian +===================================================== + +What it does +============ + +* ssh authentication is configured to allow the server to execute check_mk on the client +* omd is installed on the server +* check_mk is installed as package on the client + +On the client +============= + + class site_check_mk::client { + class { 'check_mk::agent': + agent_package_name => 'check-mk-agent', + agent_logwatch_package_name => 'check-mk-agent-logwatch', + use_ssh => true, + register_agent => false + } + } + + +On the server +============= + + include check_mk::omd_repo + class { 'check_mk': + package => 'omd', + omd_service_name => 'omd-1.00', + http_service_name => 'apache2', + omdadmin_htpasswd => trocla("${::fqdn}_omdadmin"), + use_ssh => true; + } + diff --git a/puppet/modules/check_mk/example.yaml b/puppet/modules/check_mk/example.yaml new file mode 100644 index 00000000..de82ecc5 --- /dev/null +++ b/puppet/modules/check_mk/example.yaml @@ -0,0 +1,93 @@ +# Monitoring Server +check_mk::filestore: 'puppet:///files/check_mk' +check_mk::package: 'omd-0.56-rh60-29.x86_64.rpm' + +#check_parameters = [ +# ( (95, 99), ALL_HOSTS, [ "fs_/boot" ]), +# ( (3192, 3584), ALL_HOSTS, [ "JVM PODDSv3 Memory" ]), +# ( (150, 200), ALL_HOSTS, [ "JVM PODDSv3 Threads" ]), +# ( (4000, 6000), [ 'coherence' ], ALL_HOSTS, [ "Number of threads" ]), +#] +# Defaults: +# hosts: ALL_HOSTS +# tags: undef +check_mk::check_parameters: + 'fs_/boot': + warning: '95' + critical: '99' + 'JVM MyApp Memory': + warning: '3192' + critical: '3584' + 'JVM MyApp Threads': + warning: '150' + critical: '200' + 'Number of threads': + tags: [ 'coherence' ] + warning: '4000' + critical: '6000' + 'fs_/': + hosts: [ 'myhost1.domain.com', 'myhost2.domain.com' ] + warning: '60' + critical: '70' + +check_mk::host_groups: + 'Puppet_Masters': + host_tags: + - 'puppet-master' + + 'My_App': + description: 'My Application' + host_tags: + - 'my-app' + + 'My_DB': + description: 'My Database' + host_tags: + - 'my-db' + +#ignored_services = [ +# ( [ "windows" ], ALL_HOSTS, [ "LOG Security" ] ), +# ( ALL_HOSTS, [ "NFS mount /home/" ] ) +#] + +check_mk::ignored_services: + 'LOG security': + tags: + 'windows' + 'NFS mount /home/': + hosts: + - 'lnxuser1.domain.com' + - 'lnxuser2.domain.com' + +# Monitoring Agent +check_mk::agent::filestore: 'puppet:///files/check_mk' +check_mk::agent::version: '1.2.0p3-1' + +# Set host tags based on built-in and custom facts +check_mk::agent::host_tags: + - '%{envtype}' + - '%{kernel}' + - '%{role}' + - '%{location}' + +check_mk::agent::jolokia::server: '127.0.0.1' +check_mk::agent::jolokia::port: '8080' +check_mk::agent::jolokia::user: 'monitoring' +check_mk::agent::jolokia::password: 'tinstaafl' +check_mk::agent::jolokia::suburi: 'jolokia' + +check_mk::agent::jolokia::instances: + 'My-App': + server: '10.0.0.1' + port: '8190' + +check_mk::agent::logwatch::keep_defaults: 'true' +check_mk::agent::logwatch::logfiles: + '/apps/tomcat1/logs/tomcat/catalina.*.log': + critical: + - '^SERVERE:' + - '^ERROR:' + warning: + - '^WARNING:' + ignore: + - '^INFO' diff --git a/puppet/modules/check_mk/files/agent/local_checks/all_hosts/README.md b/puppet/modules/check_mk/files/agent/local_checks/all_hosts/README.md new file mode 100644 index 00000000..f5234cbf --- /dev/null +++ b/puppet/modules/check_mk/files/agent/local_checks/all_hosts/README.md @@ -0,0 +1,2 @@ +Place local checks in this directory, +see http://mathias-kettner.de/checkmk_localchecks.html diff --git a/puppet/modules/check_mk/files/use_ssh.mk b/puppet/modules/check_mk/files/use_ssh.mk new file mode 100644 index 00000000..b5d77c62 --- /dev/null +++ b/puppet/modules/check_mk/files/use_ssh.mk @@ -0,0 +1,5 @@ +# http://mathias-kettner.de/checkmk_datasource_programs.html +datasource_programs = [ + ( "ssh -l root -i /omd/sites/monitoring/.ssh/monitoring__id_rsa check_mk_agent", ['ssh'], ALL_HOSTS ), +] + diff --git a/puppet/modules/check_mk/manifests/agent.pp b/puppet/modules/check_mk/manifests/agent.pp new file mode 100644 index 00000000..64109ae9 --- /dev/null +++ b/puppet/modules/check_mk/manifests/agent.pp @@ -0,0 +1,70 @@ +class check_mk::agent ( + $filestore = undef, + $host_tags = undef, + $ip_whitelist = undef, + $port = '6556', + $server_dir = '/usr/bin', + $keydir = '/omd/sites/monitoring', + $authdir = '/omd/sites/monitoring', + $authfile = undef, + $use_cache = false, + $user = 'root', + $version = undef, + $workspace = '/root/check_mk', + $agent_package_name = 'check_mk-agent', + $agent_logwatch_package_name = 'check_mk-agent-logwatch', + $method = 'xinetd', + $generate_sshkey = false, + $sshuser = undef, + $use_ssh_tag = 'ssh', + $hostname = $::fqdn, + $register_agent = true +) { + + case $method { + 'xinetd': { + $tags = $host_tags + include check_mk::agent::service + } + 'ssh': { + if ( $host_tags == undef ) or ( $host_tags == '' ) { + $tags = $use_ssh_tag + } else { + $tags = "${host_tags}|${use_ssh_tag}" + } + } + default: {} + } + + class { 'check_mk::agent::install': + version => $version, + filestore => $filestore, + workspace => $workspace, + agent_package_name => $agent_package_name, + agent_logwatch_package_name => $agent_logwatch_package_name, + method => $method + } + + class { 'check_mk::agent::config': + ip_whitelist => $ip_whitelist, + port => $port, + server_dir => $server_dir, + keydir => $keydir, + authdir => $authdir, + authfile => $authfile, + use_cache => $use_cache, + user => $user, + method => $method, + generate_sshkey => $generate_sshkey, + sshuser => $sshuser, + hostname => $hostname, + require => Class['check_mk::agent::install'], + } + + if ( $register_agent ) { + class { 'check_mk::agent::register': + host_tags => $tags, + hostname => $hostname, + } + } +} diff --git a/puppet/modules/check_mk/manifests/agent/config.pp b/puppet/modules/check_mk/manifests/agent/config.pp new file mode 100644 index 00000000..8ee5f185 --- /dev/null +++ b/puppet/modules/check_mk/manifests/agent/config.pp @@ -0,0 +1,59 @@ +class check_mk::agent::config ( + $ip_whitelist = '', + $port, + $server_dir, + $keydir, + $authdir, + $authfile = undef, + $use_cache, + $user, + $method = 'xinetd', + $generate_sshkey = false, + $sshuser = undef, + $hostname = $::fqdn +) { + if $use_cache { + $server = "${server_dir}/check_mk_caching_agent" + } else { + $server = "${server_dir}/check_mk_agent" + } + + case $method { + 'xinetd': { + if $ip_whitelist { + $only_from = join($ip_whitelist, ' ') + } else { + $only_from = undef + } + + file { '/etc/xinetd.d/check_mk': + ensure => present, + owner => 'root', + group => 'root', + mode => '0444', + content => template('check_mk/agent/check_mk.erb'), + require => Package['check_mk-agent','check_mk-agent-logwatch'], + notify => Class['check_mk::agent::service'], + } + } + + 'ssh': { + if $generate_sshkey { + check_mk::agent::generate_sshkey { "check_mk_key_${hostname}": + keydir => $keydir, + authdir => $authdir, + authfile => $authfile, + sshuser => $sshuser, + hostname => $hostname + } + } + + # make sure the xinetd method is not configured + file { '/etc/xinetd.d/check_mk': + ensure => absent; + } + } + + default : {} + } +} diff --git a/puppet/modules/check_mk/manifests/agent/generate_sshkey.pp b/puppet/modules/check_mk/manifests/agent/generate_sshkey.pp new file mode 100644 index 00000000..b00271f5 --- /dev/null +++ b/puppet/modules/check_mk/manifests/agent/generate_sshkey.pp @@ -0,0 +1,70 @@ +define check_mk::agent::generate_sshkey ( + # dir on the check-mk-server where the collected key pairs are stored + $keydir, + # user/group the key should be owned by on the check-mk-server + $keyuser = 'nagios', + $keygroup = 'nagios', + # dir on the check-mk-agent where the authorized_keys file is stored + $authdir, + # name of the authorized_keys file + $authfile = undef, + # dir on the puppetmaster where keys are stored + # FIXME: need a way to ensure this dir is setup on the puppetmaster correctly + #$ssh_key_basepath = "${common::moduledir::module_dir_path}/check_mk/keys", + # for now use a dir we know works + $ssh_key_basepath = '/etc/puppet/modules/check_mk/keys', + # user on the client the check_mk server will ssh to, to run the agent + $sshuser = 'root', + $hostname = $::fqdn, + $check_mk_tag = 'check_mk_sshkey' +){ + + # generate check-mk ssh keypair, stored on puppetmaster + $ssh_key_name = "${hostname}_id_rsa" + $ssh_keys = ssh_keygen("${ssh_key_basepath}/${ssh_key_name}") + $public = split($ssh_keys[1],' ') + $public_type = $public[0] + $public_key = $public[1] + $secret_key = $ssh_keys[0] + + # if we're not root we need to use sudo + if $sshuser != 'root' { + $command = 'sudo /usr/bin/check_mk_agent' + } else { + $command = '/usr/bin/check_mk_agent' + } + + # setup the public half of the key in authorized_keys on the agent + # and restrict it to running only the agent + if $authdir or $authfile { + # if $authkey or $authdir are set, override authorized_keys path and file + # and also override using the built-in ssh_authorized_key since it may + # not be able to write to $authdir + sshd::ssh_authorized_key { $ssh_key_name: + type => 'ssh-rsa', + key => $public_key, + user => $sshuser, + target => "${authdir}/${authfile}", + override_builtin => true, + options => "command=\"${command}\""; + } + } else { + # otherwise use the defaults + sshd::ssh_authorized_key { $ssh_key_name: + type => 'ssh-rsa', + key => $public_key, + user => $sshuser, + options => "command=\"${command}\""; + } + } + + # resource collector for the private half of the keys, these end up on + # the check-mk-server host, and the user running check-mk needs access + @@file { "${keydir}/${ssh_key_name}": + content => $secret_key, + owner => $keyuser, + group => $keygroup, + mode => '0600', + tag => $check_mk_tag; + } +} diff --git a/puppet/modules/check_mk/manifests/agent/install.pp b/puppet/modules/check_mk/manifests/agent/install.pp new file mode 100644 index 00000000..5c0b56ef --- /dev/null +++ b/puppet/modules/check_mk/manifests/agent/install.pp @@ -0,0 +1,70 @@ +class check_mk::agent::install ( + $version = '', + $filestore = '', + $workspace, + $agent_package_name, + $agent_logwatch_package_name, + $method = 'xinetd', +) { + if $method == 'xinetd' { + if ! defined($require_method) { + package { 'xinetd': + ensure => latest, + } + } + $require_method = 'Package[\'xinetd\']' + } else { + $require_method = undef + } + + if $filestore { + if ! defined(File[$workspace]) { + file { $workspace: + ensure => directory, + } + } + file { "${workspace}/check_mk-agent-${version}.noarch.rpm": + ensure => latest, + source => "${filestore}/check_mk-agent-${version}.noarch.rpm", + require => $require_method, + } + file { "${workspace}/check_mk-agent-logwatch-${version}.noarch.rpm": + ensure => latest, + source => "${filestore}/check_mk-agent-logwatch-${version}.noarch.rpm", + require => $require_method, + } + package { 'check_mk-agent': + ensure => latest, + provider => 'rpm', + source => "${workspace}/check_mk-agent-${version}.noarch.rpm", + require => File["${workspace}/check_mk-agent-${version}.noarch.rpm"], + } + package { 'check_mk-agent-logwatch': + ensure => latest, + provider => 'rpm', + source => "${workspace}/check_mk-agent-logwatch-${version}.noarch.rpm", + require => [ + File["${workspace}/check_mk-agent-logwatch-${version}.noarch.rpm"], + Package['check_mk-agent'], + ], + } + } + else { + if $version { + $agent_package_version = $version + } else { + $agent_package_version = latest + } + + package { 'check_mk-agent': + ensure => $agent_package_version, + name => $agent_package_name, + require => $require_method, + } + package { 'check_mk-agent-logwatch': + ensure => $agent_package_version, + name => $agent_logwatch_package_name, + require => Package['check_mk-agent'], + } + } +} diff --git a/puppet/modules/check_mk/manifests/agent/install_local.pp b/puppet/modules/check_mk/manifests/agent/install_local.pp new file mode 100644 index 00000000..7238440f --- /dev/null +++ b/puppet/modules/check_mk/manifests/agent/install_local.pp @@ -0,0 +1,12 @@ +define check_mk::agent::install_local($source=undef, $content=undef, $ensure='present') { + @file { "/usr/lib/check_mk_agent/local/${name}" : + ensure => $ensure, + owner => 'root', + group => 'root', + mode => '0755', + content => $content, + source => $source, + tag => 'check_mk::local', + require => Package['check-mk-agent'], + } +} diff --git a/puppet/modules/check_mk/manifests/agent/local_checks.pp b/puppet/modules/check_mk/manifests/agent/local_checks.pp new file mode 100644 index 00000000..04896b0a --- /dev/null +++ b/puppet/modules/check_mk/manifests/agent/local_checks.pp @@ -0,0 +1,11 @@ +class check_mk::agent::local_checks{ + file { '/usr/lib/check_mk_agent/local': + ensure => directory, + source => [ + 'puppet:///modules/site_check_mk/agent/local_checks/all_hosts', + 'puppet:///modules/check_mk/agent/local_checks/all_hosts' ], + recurse => true, + require => Package['check_mk-agent'], + } + +} diff --git a/puppet/modules/check_mk/manifests/agent/mrpe.pp b/puppet/modules/check_mk/manifests/agent/mrpe.pp new file mode 100644 index 00000000..5bc5f331 --- /dev/null +++ b/puppet/modules/check_mk/manifests/agent/mrpe.pp @@ -0,0 +1,19 @@ +class check_mk::agent::mrpe { + # check_mk can use standard nagios plugins using + # a wrapper called mrpe + # see http://mathias-kettner.de/checkmk_mrpe.html + # this subclass is provided to be included by checks that use mrpe + + # FIXME: this is Debian specific and should be made more generic + if !defined(Package['nagios-plugins-basic']) { + package { 'nagios-plugins-basic': + ensure => latest, + } + } + + # ensure the config file exists, individual checks will add lines to it + file { '/etc/check_mk/mrpe.cfg': + ensure => present, + require => Package['check-mk-agent'] + } +} diff --git a/puppet/modules/check_mk/manifests/agent/ps.pp b/puppet/modules/check_mk/manifests/agent/ps.pp new file mode 100644 index 00000000..67a999f5 --- /dev/null +++ b/puppet/modules/check_mk/manifests/agent/ps.pp @@ -0,0 +1,17 @@ +define check_mk::agent::ps ( + # procname and levels have defaults in check_mk::ps + $procname = undef, + $levels = undef, + # user is optional + $user = undef +) { + + @@check_mk::ps { "${::fqdn}_${name}": + desc => $name, + host => $::fqdn, + procname => $procname, + user => $user, + levels => $levels, + tag => 'check_mk_ps'; + } +} diff --git a/puppet/modules/check_mk/manifests/agent/register.pp b/puppet/modules/check_mk/manifests/agent/register.pp new file mode 100644 index 00000000..46cdeaee --- /dev/null +++ b/puppet/modules/check_mk/manifests/agent/register.pp @@ -0,0 +1,8 @@ +class check_mk::agent::register ( + $host_tags = '', + $hostname = $::fqdn +) { + @@check_mk::host { $hostname: + host_tags => $host_tags, + } +} diff --git a/puppet/modules/check_mk/manifests/agent/service.pp b/puppet/modules/check_mk/manifests/agent/service.pp new file mode 100644 index 00000000..0f707082 --- /dev/null +++ b/puppet/modules/check_mk/manifests/agent/service.pp @@ -0,0 +1,8 @@ +class check_mk::agent::service { + if ! defined(Service['xinetd']) { + service { 'xinetd': + ensure => 'running', + enable => true, + } + } +} diff --git a/puppet/modules/check_mk/manifests/config.pp b/puppet/modules/check_mk/manifests/config.pp new file mode 100644 index 00000000..fba68361 --- /dev/null +++ b/puppet/modules/check_mk/manifests/config.pp @@ -0,0 +1,109 @@ +# Deploy check_mk config +class check_mk::config ( + $site, + $host_groups = undef, + $etc_dir = "/omd/sites/${site}/etc", + $nagios_subdir = 'nagios', + $bin_dir = "/omd/sites/${site}/bin", + $use_storedconfigs = true, + $inventory_only_on_changes = true +) { + file { + # for local check_mk checks + "${etc_dir}/${nagios_subdir}/local": + ensure => directory; + + # package provided and check_mk generated files, defined so the nagios + # module doesn't purge them + "${etc_dir}/${nagios_subdir}/conf.d": + ensure => directory; + "${etc_dir}/${nagios_subdir}/conf.d/check_mk": + ensure => directory; + } + file_line { 'nagios-add-check_mk-cfg_dir': + ensure => present, + line => "cfg_dir=${etc_dir}/${nagios_subdir}/local", + path => "${etc_dir}/${nagios_subdir}/nagios.cfg", + require => File["${etc_dir}/${nagios_subdir}/local"], + #notify => Class['check_mk::service'], + } + file_line { 'add-guest-users': + ensure => present, + line => 'guest_users = [ "guest" ]', + path => "${etc_dir}/check_mk/multisite.mk", + #notify => Class['check_mk::service'], + } + concat { "${etc_dir}/check_mk/main.mk": + owner => 'root', + group => 'root', + mode => '0644', + notify => Exec['check_mk-refresh'], + } + # all_hosts + concat::fragment { 'all_hosts-header': + target => "${etc_dir}/check_mk/main.mk", + content => "all_hosts = [\n", + order => 10, + } + concat::fragment { 'all_hosts-footer': + target => "${etc_dir}/check_mk/main.mk", + content => "]\n", + order => 19, + } + if ( $use_storedconfigs ) { + class { 'check_mk::server::collect_hosts': } + class { 'check_mk::server::collect_ps': } + } + + + # local list of hosts is in /omd/sites/${site}/etc/check_mk/all_hosts_static and is appended + concat::fragment { 'all-hosts-static': + ensure => "${etc_dir}/check_mk/all_hosts_static", + target => "${etc_dir}/check_mk/main.mk", + order => 18, + } + # host_groups + if $host_groups { + file { "${etc_dir}/nagios/local/hostgroups": + ensure => directory, + } + concat::fragment { 'host_groups-header': + target => "${etc_dir}/check_mk/main.mk", + content => "host_groups = [\n", + order => 20, + } + concat::fragment { 'host_groups-footer': + target => "${etc_dir}/check_mk/main.mk", + content => "]\n", + order => 29, + } + $groups = keys($host_groups) + check_mk::hostgroup { $groups: + dir => "${etc_dir}/nagios/local/hostgroups", + hostgroups => $host_groups, + target => "${etc_dir}/check_mk/main.mk", + notify => Exec['check_mk-refresh'] + } + } + # local config is in /omd/sites/${site}/etc/check_mk/main.mk.local and is appended + concat::fragment { 'check_mk-local-config': + ensure => "${etc_dir}/check_mk/main.mk.local", + target => "${etc_dir}/check_mk/main.mk", + order => 99, + } + # re-read config if it changes + exec { 'check_mk-refresh': + command => "/bin/su -l -c '${bin_dir}/check_mk -II' ${site}", + refreshonly => $inventory_only_on_changes, + notify => Exec['check_mk-reload'], + } + exec { 'check_mk-reload': + command => "/bin/su -l -c '${bin_dir}/check_mk -O' ${site}", + refreshonly => $inventory_only_on_changes, + } + # re-read inventory at least daily + exec { 'check_mk-refresh-inventory-daily': + command => "/bin/su -l -c '${bin_dir}/check_mk -O' ${site}", + schedule => 'daily', + } +} diff --git a/puppet/modules/check_mk/manifests/host.pp b/puppet/modules/check_mk/manifests/host.pp new file mode 100644 index 00000000..49f038b5 --- /dev/null +++ b/puppet/modules/check_mk/manifests/host.pp @@ -0,0 +1,18 @@ +define check_mk::host ( + $target, + $host_tags = [], +) { + $host = $title + if size($host_tags) > 0 { + $taglist = join(any2array($host_tags),'|') + $entry = "${host}|${taglist}" + } + else { + $entry = $host + } + concat::fragment { "check_mk-${host}": + target => $target, + content => " '${entry}',\n", + order => 11, + } +} diff --git a/puppet/modules/check_mk/manifests/hostgroup.pp b/puppet/modules/check_mk/manifests/hostgroup.pp new file mode 100644 index 00000000..baec45f9 --- /dev/null +++ b/puppet/modules/check_mk/manifests/hostgroup.pp @@ -0,0 +1,24 @@ +define check_mk::hostgroup ( + $dir, + $hostgroups, + $target, +) { + $group = $title + $group_tags = sprintf("'%s'", join($hostgroups[$group]['host_tags'], "', '")) + concat::fragment { "check_mk-hostgroup-${group}": + target => $target, + content => " ( '${group}', [ ${group_tags} ], ALL_HOSTS ),\n", + order => 21, + } + if $hostgroups[$group]['description'] { + $description = $hostgroups[$group]['description'] + } + else { + $description = regsubst($group, '_', ' ') + } + file { "${dir}/${group}.cfg": + ensure => present, + content => "define hostgroup {\n hostgroup_name ${group}\n alias ${description}\n}\n", + require => File[$dir], + } +} diff --git a/puppet/modules/check_mk/manifests/htpasswd.pp b/puppet/modules/check_mk/manifests/htpasswd.pp new file mode 100644 index 00000000..2bd24cc5 --- /dev/null +++ b/puppet/modules/check_mk/manifests/htpasswd.pp @@ -0,0 +1,12 @@ +class check_mk::htpasswd ( + $password, + $username = 'omdadmin', + $path = '/opt/omd/sites/monitoring/etc/htpasswd' ) { + + apache::htpasswd_user { $username: + ensure => present, + username => $username, + password => $password, + path => $path + } +} diff --git a/puppet/modules/check_mk/manifests/init.pp b/puppet/modules/check_mk/manifests/init.pp new file mode 100644 index 00000000..4aab837d --- /dev/null +++ b/puppet/modules/check_mk/manifests/init.pp @@ -0,0 +1,44 @@ +# configure check_mk server +class check_mk ( + $filestore = undef, + $host_groups = undef, + $package = 'omd-0.56', + $site = 'monitoring', + $workspace = '/root/check_mk', + $omd_service_name = 'omd', + $http_service_name = 'httpd', + $xinitd_service_name = 'xinetd', + $omdadmin_htpasswd = undef, + $use_ssh = false, + $shelluser = 'monitoring', + $shellgroup = 'monitoring', + $use_storedconfigs = true, + $inventory_only_on_changes = true) { + + class { 'check_mk::install': + filestore => $filestore, + package => $package, + site => $site, + workspace => $workspace, + } + class { 'check_mk::config': + host_groups => $host_groups, + site => $site, + use_storedconfigs => $use_storedconfigs, + inventory_only_on_changes => $inventory_only_on_changes, + require => Class['check_mk::install'], + } + class { 'check_mk::service': + require => Class['check_mk::config'], + } + if $omdadmin_htpasswd { + class { 'check_mk::htpasswd': + password => $omdadmin_htpasswd + } + } + + if ( $use_ssh == true ) { + class { 'check_mk::server::configure_ssh': } + } + +} diff --git a/puppet/modules/check_mk/manifests/install.pp b/puppet/modules/check_mk/manifests/install.pp new file mode 100644 index 00000000..5f8a4a0d --- /dev/null +++ b/puppet/modules/check_mk/manifests/install.pp @@ -0,0 +1,50 @@ +class check_mk::install ( + $filestore = '', + $version = '', + $package, + $site, + $workspace, +) { + if $filestore { + if ! defined(File[$workspace]) { + file { $workspace: + ensure => directory, + } + } + file { "${workspace}/${package}": + ensure => latest, + source => "${filestore}/${package}", + require => File[$workspace], + } + # omd-0.56-rh60-29.x86_64.rpm + if $package =~ /^(omd-\d+\.\d+)-(.*?)\.(rpm|deb)$/ { + $package_name = $1 + $type = $3 + package { $package_name: + ensure => installed, + provider => $type, + source => "${workspace}/${package}", + require => File["${workspace}/${package}"], + } + } + } + else { + $package_name = $package + + if $version { + $server_package_version = $version + } else { + $server_package_version = latest + } + + package { $package_name: + ensure => $server_package_version, + } + } + $etc_dir = "/omd/sites/${site}/etc" + exec { 'omd-create-site': + command => "/usr/bin/omd create ${site}", + creates => $etc_dir, + require => Package[$package_name], + } +} diff --git a/puppet/modules/check_mk/manifests/install_tarball.pp b/puppet/modules/check_mk/manifests/install_tarball.pp new file mode 100644 index 00000000..af40a267 --- /dev/null +++ b/puppet/modules/check_mk/manifests/install_tarball.pp @@ -0,0 +1,92 @@ +class check_mk::install_tarball ( + $filestore, + $version, + $workspace, +) { + package { 'nagios': + ensure => present, + notify => Exec['set-nagiosadmin-password', 'set-guest-password', 'add-apache-to-nagios-group'], + } + file { '/etc/nagios/passwd': + ensure => present, + owner => 'root', + group => 'apache', + mode => '0640', + } + exec { 'set-nagiosadmin-password': + command => '/usr/bin/htpasswd -b /etc/nagios/passwd nagiosadmin letmein', + refreshonly => true, + require => File['/etc/nagios/passwd'], + } + exec { 'set-guest-password': + command => '/usr/bin/htpasswd -b /etc/nagios/passwd guest guest', + refreshonly => true, + require => File['/etc/nagios/passwd'], + } + exec { 'add-apache-to-nagios-group': + command => '/usr/sbin/usermod -a -G nagios apache', + refreshonly => true, + } + package { 'nagios-plugins-all': + ensure => present, + require => Package['nagios'], + } + # FIXME: this should get and check $use_ssh before requiring xinetd + package { [ 'xinetd', 'mod_python', 'make', 'gcc-c++', 'tar', 'gzip' ]: + ensure => present, + } + file { "${workspace}/check_mk-${version}.tar.gz": + ensure => present, + source => "${filestore}/check_mk-${version}.tar.gz", + } + exec { 'unpack-check_mk-tarball': + command => "/bin/tar -zxf ${workspace}/check_mk-${version}.tar.gz", + cwd => $workspace, + creates => "${workspace}/check_mk-${version}", + require => File["${workspace}/check_mk-${version}.tar.gz"], + } + exec { 'change-setup-config-location': + command => "/usr/bin/perl -pi -e 's#^SETUPCONF=.*?$#SETUPCONF=${workspace}/check_mk_setup.conf#' ${workspace}/check_mk-${version}/setup.sh", + unless => "/bin/egrep '^SETUPCONF=${workspace}/check_mk_setup.conf$' ${workspace}/check_mk-${version}/setup.sh", + require => Exec['unpack-check_mk-tarball'], + } + # Avoid header like 'Written by setup of check_mk 1.2.0p3 at Thu Feb 7 12:26:17 GMT 2013' + # that changes every time the setup script is run + exec { 'remove-setup-header': + command => "/usr/bin/perl -pi -e 's#^DIRINFO=.*?$#DIRINFO=#' ${workspace}/check_mk-${version}/setup.sh", + unless => "/bin/egrep '^DIRINFO=$' ${workspace}/check_mk-${version}/setup.sh", + require => Exec['unpack-check_mk-tarball'], + } + file { "${workspace}/check_mk_setup.conf": + ensure => present, + content => template('check_mk/setup.conf.erb'), + notify => Exec['check_mk-setup'], + } + file { '/etc/nagios/check_mk': + ensure => directory, + owner => 'nagios', + group => 'nagios', + recurse => true, + require => Package['nagios'], + } + file { '/etc/nagios/check_mk/hostgroups': + ensure => directory, + owner => 'nagios', + group => 'nagios', + require => File['/etc/nagios/check_mk'], + } + exec { 'check_mk-setup': + command => "${workspace}/check_mk-${version}/setup.sh --yes", + cwd => "${workspace}/check_mk-${version}", + refreshonly => true, + require => [ + Exec['change-setup-config-location'], + Exec['remove-setup-header'], + Exec['unpack-check_mk-tarball'], + File["${workspace}/check_mk_setup.conf"], + File['/etc/nagios/check_mk'], + Package['nagios'], + ], + notify => Class['check_mk::service'], + } +} diff --git a/puppet/modules/check_mk/manifests/omd_repo.pp b/puppet/modules/check_mk/manifests/omd_repo.pp new file mode 100644 index 00000000..2100f378 --- /dev/null +++ b/puppet/modules/check_mk/manifests/omd_repo.pp @@ -0,0 +1,6 @@ +class check_mk::omd_repo { + apt::sources_list { 'omd.list': + content => "deb http://labs.consol.de/OMD/debian ${::lsbdistcodename} main", + before => Package['omd'] + } +} diff --git a/puppet/modules/check_mk/manifests/ps.pp b/puppet/modules/check_mk/manifests/ps.pp new file mode 100644 index 00000000..1171a135 --- /dev/null +++ b/puppet/modules/check_mk/manifests/ps.pp @@ -0,0 +1,34 @@ +define check_mk::ps ( + $target, + $host, + $desc, + $procname = "/usr/sbin/${desc}", + $levels = '1, 1, 1, 1', + $user = undef +) { + # This class is called on check-mk agent machines in order to create + # checks using the built-in ps check type. They create stored configs + # and then the check_mk::server::collect_ps class on the server + # generates the config file to set them up + + # lines in the ps.mk config file look like + # ( "foo.example.com", "ps", "NAME", ( "/usr/sbin/foo", 1, 1, 1, 1 ) ) + # or with a user + # ( "foo.example.com", "ps", "NAME", ( "/usr/sbin/foo", "user", 1, 1, 1, 1 ) ) + if $user { + $check = " ( \"${host}\", \"ps\", \"${desc}\", ( \"${procname}\", ${user}, ${levels} ) ),\n" + } else { + $check = " ( \"${host}\", \"ps\", \"${desc}\", ( \"${procname}\", ${levels} ) ),\n" + } + + # FIXME: we could be smarter about this and consolidate host checks + # that have identical settings and that would make the config file + # make more sense for humans. but for now we'll just do separate + # lines (which may result in a very large file, but check-mk is fine) + concat::fragment { "check_mk_ps-${host}_${desc}": + target => $target, + content => $check, + order => 20 + } +} + diff --git a/puppet/modules/check_mk/manifests/server/collect_hosts.pp b/puppet/modules/check_mk/manifests/server/collect_hosts.pp new file mode 100644 index 00000000..6d07897b --- /dev/null +++ b/puppet/modules/check_mk/manifests/server/collect_hosts.pp @@ -0,0 +1,6 @@ +class check_mk::server::collect_hosts { + Check_mk::Host <<| |>> { + target => "${::check_mk::config::etc_dir}/check_mk/main.mk", + notify => Exec['check_mk-refresh'] + } +} diff --git a/puppet/modules/check_mk/manifests/server/collect_ps.pp b/puppet/modules/check_mk/manifests/server/collect_ps.pp new file mode 100644 index 00000000..067a25c9 --- /dev/null +++ b/puppet/modules/check_mk/manifests/server/collect_ps.pp @@ -0,0 +1,30 @@ +class check_mk::server::collect_ps ( + $config = "${::check_mk::config::etc_dir}/check_mk/conf.d/ps.mk" +) { + + # this class gets run on the check-mk server in order to collect the + # stored configs created on clients and assemble the ps.mk config file + concat { $config: + owner => 'root', + group => 'root', + mode => '0644', + notify => Exec['check_mk-refresh'], + } + + concat::fragment{'check_mk_ps_header': + target => $config, + content => "checks += [\n", + order => 10, + } + + Check_mk::Ps <<| tag == 'check_mk_ps' |>> { + target => $config, + notify => Exec['check_mk-refresh'] + } + + concat::fragment{'check_mk_ps_footer': + target => $config, + content => "]\n", + order => 90, + } +} diff --git a/puppet/modules/check_mk/manifests/server/configure_ssh.pp b/puppet/modules/check_mk/manifests/server/configure_ssh.pp new file mode 100644 index 00000000..987cc7af --- /dev/null +++ b/puppet/modules/check_mk/manifests/server/configure_ssh.pp @@ -0,0 +1,16 @@ +class check_mk::server::configure_ssh ( + $check_mk_tag = 'check_mk_sshkey' +) { + # collect exported files from client::generate_sshkey + File <<| tag == $check_mk_tag |>> + + # configure ssh access to agents which have 'ssh' tags + file { "${check_mk::config::etc_dir}/check_mk/conf.d/use_ssh.mk": + source => [ 'puppet:///modules/site_check_mk/use_ssh.mk', + 'puppet:///modules/check_mk/use_ssh.mk' ], + owner => $::check_mk::shelluser, + group => $::check_mk::shellgroup, + mode => '0644', + notify => Exec['check_mk-refresh'] + } +} diff --git a/puppet/modules/check_mk/manifests/service.pp b/puppet/modules/check_mk/manifests/service.pp new file mode 100644 index 00000000..36fb2d16 --- /dev/null +++ b/puppet/modules/check_mk/manifests/service.pp @@ -0,0 +1,23 @@ +class check_mk::service { + + if ! defined(Service[$check_mk::http_service_name]) { + service { $check_mk::http_service_name: + ensure => 'running', + enable => true, + } + } + # FIXME: this should get and check $use_ssh before doing this + if ! defined(Service[xinetd]) { + service { 'xinetd': + ensure => 'running', + name => $check_mk::xinitd_service_name, + hasstatus => false, + enable => true, + } + } + service { 'omd': + ensure => 'running', + name => $check_mk::omd_service_name, + enable => true, + } +} diff --git a/puppet/modules/check_mk/templates/agent/check_mk.erb b/puppet/modules/check_mk/templates/agent/check_mk.erb new file mode 100644 index 00000000..47824a9f --- /dev/null +++ b/puppet/modules/check_mk/templates/agent/check_mk.erb @@ -0,0 +1,39 @@ +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2012 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +service check_mk +{ + type = UNLISTED + port = <%= @port %> + socket_type = stream + protocol = tcp + wait = no + user = <%= @user %> + server = <%= @server %> +<% if @only_from -%> + only_from = 127.0.0.1 <%= @only_from %> +<% end -%> + log_on_success = + disable = no +} diff --git a/puppet/modules/check_mk/templates/main.mk.erb b/puppet/modules/check_mk/templates/main.mk.erb new file mode 100644 index 00000000..e1fbe81c --- /dev/null +++ b/puppet/modules/check_mk/templates/main.mk.erb @@ -0,0 +1,4 @@ +all_hosts = [ + 'lnxmgt-01.sbetenv.ads', + 'lnxmgt-02.sbetenv.ads', +] diff --git a/puppet/modules/check_mk/templates/setup.conf.erb b/puppet/modules/check_mk/templates/setup.conf.erb new file mode 100644 index 00000000..41e1143b --- /dev/null +++ b/puppet/modules/check_mk/templates/setup.conf.erb @@ -0,0 +1,29 @@ + +bindir='/usr/bin' +confdir='/etc/check_mk' +sharedir='/usr/share/check_mk' +docdir='/usr/share/doc/check_mk' +checkmandir='/usr/share/doc/check_mk/checks' +vardir='/var/lib/check_mk' +agentslibdir='/usr/lib/check_mk_agent' +agentsconfdir='/etc/check_mk' +nagiosuser='nagios' +wwwuser='apache' +wwwgroup='nagios' +nagios_binary='/usr/sbin/nagios' +nagios_config_file='/etc/nagios/nagios.cfg' +nagconfdir='/etc/nagios/check_mk' +nagios_startscript='/etc/init.d/nagios' +nagpipe='/var/spool/nagios/cmd/nagios.cmd' +check_result_path='/var/log/nagios/spool/checkresults' +nagios_status_file='/var/log/nagios/status.dat' +check_icmp_path='/usr/lib64/nagios/plugins/check_icmp' +url_prefix='/' +apache_config_dir='/etc/httpd/conf.d' +htpasswd_file='/etc/nagios/passwd' +nagios_auth_name='Nagios Access' +pnptemplates='/usr/share/nagios/html/pnp4nagios/templates' +enable_livestatus='yes' +libdir='/usr/lib/check_mk' +livesock='/var/spool/nagios/cmd/live' +livebackendsdir='/usr/share/check_mk/livestatus' -- cgit v1.2.3 From fae09e7fad7bc3230dc6184d256ddcd58b4484c7 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 16:46:34 -0400 Subject: git subrepo clone https://leap.se/git/puppet_systemd puppet/modules/systemd subrepo: subdir: "puppet/modules/systemd" merged: "6d47fd4" upstream: origin: "https://leap.se/git/puppet_systemd" branch: "master" commit: "6d47fd4" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "1e79595" Change-Id: If71ec55d9f038b04fcab6d4ce5620db89168f75c --- puppet/modules/systemd/.gitignore | 10 ++++ puppet/modules/systemd/.gitrepo | 11 ++++ puppet/modules/systemd/.puppet-lint.rc | 5 ++ puppet/modules/systemd/.sync.yml | 3 + puppet/modules/systemd/.travis.yml | 32 +++++++++++ puppet/modules/systemd/CHANGELOG.md | 65 ++++++++++++++++++++++ puppet/modules/systemd/Gemfile | 47 ++++++++++++++++ puppet/modules/systemd/HISTORY.md | 62 +++++++++++++++++++++ puppet/modules/systemd/README.md | 38 +++++++++++++ puppet/modules/systemd/Rakefile | 23 ++++++++ puppet/modules/systemd/manifests/init.pp | 18 ++++++ puppet/modules/systemd/metadata.json | 48 ++++++++++++++++ .../acceptance/nodesets/centos-5-x86_64-docker.yml | 15 +++++ .../acceptance/nodesets/centos-6-x86_64-docker.yml | 15 +++++ .../nodesets/centos-6-x86_64-openstack.yml | 14 +++++ .../nodesets/centos-6-x86_64-vagrant.yml | 11 ++++ .../acceptance/nodesets/centos-7-x86_64-docker.yml | 15 +++++ .../nodesets/centos-7-x86_64-openstack.yml | 14 +++++ .../nodesets/centos-7-x86_64-vagrant.yml | 11 ++++ .../acceptance/nodesets/debian-6-x86_64-docker.yml | 15 +++++ .../nodesets/debian-6-x86_64-openstack.yml | 14 +++++ .../nodesets/debian-6-x86_64-vagrant.yml | 11 ++++ .../acceptance/nodesets/debian-7-x86_64-docker.yml | 15 +++++ .../nodesets/debian-7-x86_64-openstack.yml | 14 +++++ .../nodesets/debian-7-x86_64-vagrant.yml | 11 ++++ .../acceptance/nodesets/debian-8-x86_64-docker.yml | 15 +++++ .../nodesets/debian-8-x86_64-openstack.yml | 14 +++++ .../nodesets/debian-8-x86_64-vagrant.yml | 11 ++++ .../nodesets/ubuntu-10.04-x86_64-docker.yml | 13 +++++ .../nodesets/ubuntu-12.04-x86_64-docker.yml | 15 +++++ .../nodesets/ubuntu-12.04-x86_64-openstack.yml | 14 +++++ .../nodesets/ubuntu-14.04-x86_64-docker.yml | 15 +++++ .../nodesets/ubuntu-14.04-x86_64-openstack.yml | 14 +++++ .../nodesets/ubuntu-14.04-x86_64-vagrant.yml | 11 ++++ .../nodesets/ubuntu-14.10-x86_64-docker.yml | 15 +++++ .../nodesets/ubuntu-14.10-x86_64-openstack.yml | 14 +++++ .../nodesets/ubuntu-15.04-x86_64-docker.yml | 15 +++++ .../nodesets/ubuntu-15.04-x86_64-openstack.yml | 14 +++++ puppet/modules/systemd/spec/spec.opts | 6 ++ puppet/modules/systemd/spec/spec_helper.rb | 42 ++++++++++++++ 40 files changed, 765 insertions(+) create mode 100644 puppet/modules/systemd/.gitignore create mode 100644 puppet/modules/systemd/.gitrepo create mode 100644 puppet/modules/systemd/.puppet-lint.rc create mode 100644 puppet/modules/systemd/.sync.yml create mode 100644 puppet/modules/systemd/.travis.yml create mode 100644 puppet/modules/systemd/CHANGELOG.md create mode 100644 puppet/modules/systemd/Gemfile create mode 100644 puppet/modules/systemd/HISTORY.md create mode 100644 puppet/modules/systemd/README.md create mode 100644 puppet/modules/systemd/Rakefile create mode 100644 puppet/modules/systemd/manifests/init.pp create mode 100644 puppet/modules/systemd/metadata.json create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/centos-5-x86_64-docker.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-docker.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-openstack.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-vagrant.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-docker.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-openstack.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-vagrant.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-docker.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-openstack.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-vagrant.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-docker.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-openstack.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-vagrant.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-docker.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-openstack.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-vagrant.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-10.04-x86_64-docker.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-12.04-x86_64-docker.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-12.04-x86_64-openstack.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-docker.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-openstack.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-vagrant.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.10-x86_64-docker.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.10-x86_64-openstack.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-15.04-x86_64-docker.yml create mode 100644 puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-15.04-x86_64-openstack.yml create mode 100644 puppet/modules/systemd/spec/spec.opts create mode 100644 puppet/modules/systemd/spec/spec_helper.rb (limited to 'puppet/modules') diff --git a/puppet/modules/systemd/.gitignore b/puppet/modules/systemd/.gitignore new file mode 100644 index 00000000..65839fa0 --- /dev/null +++ b/puppet/modules/systemd/.gitignore @@ -0,0 +1,10 @@ +pkg/ +Gemfile.lock +vendor/ +spec/fixtures/ +.vagrant/ +.bundle/ +coverage/ +log/ +.*.swp +*~ diff --git a/puppet/modules/systemd/.gitrepo b/puppet/modules/systemd/.gitrepo new file mode 100644 index 00000000..1548a815 --- /dev/null +++ b/puppet/modules/systemd/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_systemd + branch = master + commit = 6d47fd4999fe03eba6fb11c4490dcbb90d937900 + parent = 56a771a3008d10720dd05fd815aeafbacdd1e08e + cmdver = 0.3.0 diff --git a/puppet/modules/systemd/.puppet-lint.rc b/puppet/modules/systemd/.puppet-lint.rc new file mode 100644 index 00000000..d8f5c59e --- /dev/null +++ b/puppet/modules/systemd/.puppet-lint.rc @@ -0,0 +1,5 @@ +--fail-on-warnings +--relative +--no-80chars +--no-documentation +--no-class_inherits_from_params_class-check diff --git a/puppet/modules/systemd/.sync.yml b/puppet/modules/systemd/.sync.yml new file mode 100644 index 00000000..5fffcb05 --- /dev/null +++ b/puppet/modules/systemd/.sync.yml @@ -0,0 +1,3 @@ +--- +.travis.yml: + forge_password: "ASTRdmLjJNa1NvHy2LRGvmvUeth6W3Fh/alYWvcvI8nDDsdkweHk0iXhcXZwtMQReb0NI5vJiRNXNy7a3XySC4+SP3hfHuDU58H2FqC4Ff0EHRPRHTEiXf7xmN53RxXYXZQvrFfqUb6tIsBNVKVmsYWNe01k8NVKPyYDfQB75PQ=" diff --git a/puppet/modules/systemd/.travis.yml b/puppet/modules/systemd/.travis.yml new file mode 100644 index 00000000..467045c5 --- /dev/null +++ b/puppet/modules/systemd/.travis.yml @@ -0,0 +1,32 @@ +--- +language: ruby +sudo: false +cache: bundler +bundler_args: --without system_tests +script: ["bundle exec rake validate", "bundle exec rake lint", "bundle exec rake spec SPEC_OPTS='--format documentation'", "bundle exec rake metadata"] +matrix: + fast_finish: true + include: + - rvm: 1.8.7 + env: PUPPET_GEM_VERSION="~> 3.0" FACTER_GEM_VERSION="~> 1.7.0" + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 3.0" + - rvm: 2.0.0 + env: PUPPET_GEM_VERSION="~> 3.0" + - rvm: 2.0.0 + env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" + - rvm: 2.1.6 + env: PUPPET_GEM_VERSION="~> 4.0" +notifications: + email: false +deploy: + provider: puppetforge + user: camptocamp + password: + secure: "ASTRdmLjJNa1NvHy2LRGvmvUeth6W3Fh/alYWvcvI8nDDsdkweHk0iXhcXZwtMQReb0NI5vJiRNXNy7a3XySC4+SP3hfHuDU58H2FqC4Ff0EHRPRHTEiXf7xmN53RxXYXZQvrFfqUb6tIsBNVKVmsYWNe01k8NVKPyYDfQB75PQ=" + on: + tags: true + # all_branches is required to use tags + all_branches: true + # Only publish if our main Ruby target builds + rvm: 1.9.3 diff --git a/puppet/modules/systemd/CHANGELOG.md b/puppet/modules/systemd/CHANGELOG.md new file mode 100644 index 00000000..11e84399 --- /dev/null +++ b/puppet/modules/systemd/CHANGELOG.md @@ -0,0 +1,65 @@ +# Change Log + +## [0.2.2](https://forge.puppetlabs.com/camptocamp/systemd/0.2.2) (2015-08-25) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.2.1...0.2.2) + +**Implemented enhancements:** + +- Add 'systemd-tmpfiles-create' [\#1](https://github.com/camptocamp/puppet-systemd/pull/1) ([roidelapluie](https://github.com/roidelapluie)) + + +## [0.2.1](https://forge.puppetlabs.com/camptocamp/systemd/0.2.1) (2015-08-21) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.2.0...0.2.1) + +- Use docker for acceptance tests + +## [0.1.15](https://forge.puppetlabs.com/camptocamp/systemd/0.1.15) (2015-06-26) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.14...0.1.15) + +- Fix strict_variables activation with rspec-puppet 2.2 + +## [0.1.14](https://forge.puppetlabs.com/camptocamp/systemd/0.1.14) (2015-05-28) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.13...0.1.14) + +- Add beaker_spec_helper to Gemfile + +## [0.1.13](https://forge.puppetlabs.com/camptocamp/systemd/0.1.13) (2015-05-26) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.12...0.1.13) + +- Use random application order in nodeset + +## [0.1.12](https://forge.puppetlabs.com/camptocamp/systemd/0.1.12) (2015-05-26) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.11...0.1.12) + +- Add utopic & vivid nodesets + +## [0.1.11](https://forge.puppetlabs.com/camptocamp/systemd/0.1.11) (2015-05-25) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.10...0.1.11) + +- Don't allow failure on Puppet 4 + +## [0.1.10](https://forge.puppetlabs.com/camptocamp/systemd/0.1.10) (2015-05-13) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.9...0.1.10) + +- Add puppet-lint-file_source_rights-check gem + +## [0.1.9](https://forge.puppetlabs.com/camptocamp/systemd/0.1.9) (2015-05-12) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.8...0.1.9) + +- Don't pin beaker + +## [0.1.8](https://forge.puppetlabs.com/camptocamp/systemd/0.1.8) (2015-04-27) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.7...0.1.8) + +- Add nodeset ubuntu-12.04-x86_64-openstack + +## [0.1.7](https://forge.puppetlabs.com/camptocamp/systemd/0.1.7) (2015-04-03) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.6...0.1.7) + +- Confine rspec pinning to ruby 1.8 + + +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* + + +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file diff --git a/puppet/modules/systemd/Gemfile b/puppet/modules/systemd/Gemfile new file mode 100644 index 00000000..0cb59337 --- /dev/null +++ b/puppet/modules/systemd/Gemfile @@ -0,0 +1,47 @@ +source ENV['GEM_SOURCE'] || "https://rubygems.org" + +group :development, :unit_tests do + gem 'rake', :require => false + gem 'rspec', '< 3.2', :require => false if RUBY_VERSION =~ /^1.8/ + gem 'rspec-puppet', :require => false + gem 'puppetlabs_spec_helper', :require => false + gem 'metadata-json-lint', :require => false + gem 'puppet-lint', :require => false + gem 'puppet-lint-unquoted_string-check', :require => false + gem 'puppet-lint-empty_string-check', :require => false + gem 'puppet-lint-spaceship_operator_without_tag-check', :require => false + gem 'puppet-lint-variable_contains_upcase', :require => false + gem 'puppet-lint-absolute_classname-check', :require => false + gem 'puppet-lint-undef_in_function-check', :require => false + gem 'puppet-lint-leading_zero-check', :require => false + gem 'puppet-lint-trailing_comma-check', :require => false + gem 'puppet-lint-file_ensure-check', :require => false + gem 'puppet-lint-version_comparison-check', :require => false + gem 'puppet-lint-fileserver-check', :require => false + gem 'puppet-lint-file_source_rights-check', :require => false + gem 'puppet-lint-alias-check', :require => false + gem 'rspec-puppet-facts', :require => false + gem 'github_changelog_generator', :require => false, :git => 'https://github.com/raphink/github-changelog-generator.git', :branch => 'dev/all_patches' if RUBY_VERSION !~ /^1.8/ + gem 'puppet-blacksmith', :require => false if RUBY_VERSION !~ /^1.8/ +end + +group :system_tests do + gem 'beaker', :require => false + gem 'beaker-rspec', :require => false + gem 'beaker_spec_helper', :require => false + gem 'serverspec', :require => false +end + +if facterversion = ENV['FACTER_GEM_VERSION'] + gem 'facter', facterversion, :require => false +else + gem 'facter', :require => false +end + +if puppetversion = ENV['PUPPET_GEM_VERSION'] + gem 'puppet', puppetversion, :require => false +else + gem 'puppet', :require => false +end + +# vim:ft=ruby diff --git a/puppet/modules/systemd/HISTORY.md b/puppet/modules/systemd/HISTORY.md new file mode 100644 index 00000000..c7bf2b4e --- /dev/null +++ b/puppet/modules/systemd/HISTORY.md @@ -0,0 +1,62 @@ +## [0.2.2](https://forge.puppetlabs.com/camptocamp/systemd/0.2.2) (2015-08-25) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.2.1...0.2.2) + +**Implemented enhancements:** + +- Add 'systemd-tmpfiles-create' [\#1](https://github.com/camptocamp/puppet-systemd/pull/1) ([roidelapluie](https://github.com/roidelapluie)) + +## [0.2.1](https://forge.puppetlabs.com/camptocamp/systemd/0.2.1) (2015-08-21) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.2.0...0.2.1) + +- Use docker for acceptance tests + +## [0.1.15](https://forge.puppetlabs.com/camptocamp/systemd/0.1.15) (2015-06-26) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.14...0.1.15) + +- Fix strict_variables activation with rspec-puppet 2.2 + +## [0.1.14](https://forge.puppetlabs.com/camptocamp/systemd/0.1.14) (2015-05-28) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.13...0.1.14) + +- Add beaker_spec_helper to Gemfile + +## [0.1.13](https://forge.puppetlabs.com/camptocamp/systemd/0.1.13) (2015-05-26) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.12...0.1.13) + +- Use random application order in nodeset + +## [0.1.12](https://forge.puppetlabs.com/camptocamp/systemd/0.1.12) (2015-05-26) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.11...0.1.12) + +- Add utopic & vivid nodesets + +## [0.1.11](https://forge.puppetlabs.com/camptocamp/systemd/0.1.11) (2015-05-25) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.10...0.1.11) + +- Don't allow failure on Puppet 4 + +## [0.1.10](https://forge.puppetlabs.com/camptocamp/systemd/0.1.10) (2015-05-13) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.9...0.1.10) + +- Add puppet-lint-file_source_rights-check gem + +## [0.1.9](https://forge.puppetlabs.com/camptocamp/systemd/0.1.9) (2015-05-12) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.8...0.1.9) + +- Don't pin beaker + +## [0.1.8](https://forge.puppetlabs.com/camptocamp/systemd/0.1.8) (2015-04-27) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.7...0.1.8) + +- Add nodeset ubuntu-12.04-x86_64-openstack + +## [0.1.7](https://forge.puppetlabs.com/camptocamp/systemd/0.1.7) (2015-04-03) +[Full Changelog](https://github.com/camptocamp/puppet-systemd/compare/0.1.6...0.1.7) + +- Confine rspec pinning to ruby 1.8 + + +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* + + +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* diff --git a/puppet/modules/systemd/README.md b/puppet/modules/systemd/README.md new file mode 100644 index 00000000..f70bcb0c --- /dev/null +++ b/puppet/modules/systemd/README.md @@ -0,0 +1,38 @@ +# Systemd + +[![Puppet Forge](http://img.shields.io/puppetforge/v/camptocamp/systemd.svg)](https://forge.puppetlabs.com/camptocamp/systemd) +[![Build Status](https://travis-ci.org/camptocamp/puppet-systemd.png?branch=master)](https://travis-ci.org/camptocamp/puppet-systemd) + +## Overview + +This module declares exec resources that you can use when you change systemd units or configuration files. + +## Examples + +### systemctl --daemon-reload + +```puppet +include ::systemd +file { '/usr/lib/systemd/system/foo.service': + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + source => "puppet:///modules/${module_name}/foo.service", +} ~> +Exec['systemctl-daemon-reload'] +``` + +### systemd-tmpfiles --create + +```puppet +include ::systemd +file { '/etc/tmpfiles.d/foo.conf': + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + source => "puppet:///modules/${module_name}/foo.conf", +} ~> +Exec['systemd-tmpfiles-create'] +``` diff --git a/puppet/modules/systemd/Rakefile b/puppet/modules/systemd/Rakefile new file mode 100644 index 00000000..adcac180 --- /dev/null +++ b/puppet/modules/systemd/Rakefile @@ -0,0 +1,23 @@ +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' + +Rake::Task[:lint].clear +PuppetLint::RakeTask.new :lint do |config| + config.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp", "vendor/**/*.pp"] + config.disable_checks = ['80chars'] + config.fail_on_warnings = true +end + +PuppetSyntax.exclude_paths = ["spec/fixtures/**/*.pp", "vendor/**/*"] + +# Publishing tasks +unless RUBY_VERSION =~ /^1\.8/ + require 'puppet_blacksmith' + require 'puppet_blacksmith/rake_tasks' + require 'github_changelog_generator/task' + GitHubChangelogGenerator::RakeTask.new :changelog do |config| + m = Blacksmith::Modulefile.new + config.future_release = m.version + config.release_url = "https://forge.puppetlabs.com/#{m.author}/#{m.name}/%s" + end +end diff --git a/puppet/modules/systemd/manifests/init.pp b/puppet/modules/systemd/manifests/init.pp new file mode 100644 index 00000000..5e6ad792 --- /dev/null +++ b/puppet/modules/systemd/manifests/init.pp @@ -0,0 +1,18 @@ +class systemd { + + Exec { + refreshonly => true, + path => $::path, + } + + exec { + 'systemctl-daemon-reload': + command => 'systemctl daemon-reload', + } + + exec { + 'systemd-tmpfiles-create': + command => 'systemd-tmpfiles --create', + } + +} diff --git a/puppet/modules/systemd/metadata.json b/puppet/modules/systemd/metadata.json new file mode 100644 index 00000000..abdd481e --- /dev/null +++ b/puppet/modules/systemd/metadata.json @@ -0,0 +1,48 @@ +{ + "name": "camptocamp-systemd", + "version": "0.2.2", + "author": "camptocamp", + "summary": "Puppet Systemd module", + "license": "Apache-2.0", + "source": "https://github.com/camptocamp/puppet-systemd", + "project_page": "https://github.com/camptocamp/puppet-systemd", + "issues_url": "https://github.com/camptocamp/puppet-systemd/issues", + "dependencies": [ + + ], + "requirements": [ + { + "name": "pe", + "version_requirement": "3.x" + }, + { + "name": "puppet", + "version_requirement": "3.x" + } + ], + "operatingsystem_support": [ + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "8" + ] + }, + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "7" + ] + } + ], + "puppet_version": [ + "2.7", + "3.0", + "3.1", + "3.2", + "3.3", + "3.4", + "3.5", + "3.6", + "3.7" + ] +} diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/centos-5-x86_64-docker.yml b/puppet/modules/systemd/spec/acceptance/nodesets/centos-5-x86_64-docker.yml new file mode 100644 index 00000000..679afb04 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/centos-5-x86_64-docker.yml @@ -0,0 +1,15 @@ +HOSTS: + centos-5-x64: + default_apply_opts: + order: random + strict_variables: + platform: el-5-x86_64 + hypervisor : docker + image: centos:5 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'yum install -y crontabs tar wget' +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-docker.yml b/puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-docker.yml new file mode 100644 index 00000000..9cab03d0 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-docker.yml @@ -0,0 +1,15 @@ +HOSTS: + centos-6-x64: + default_apply_opts: + order: random + strict_variables: + platform: el-6-x86_64 + hypervisor : docker + image: centos:6 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'yum install -y crontabs tar wget' +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-openstack.yml b/puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-openstack.yml new file mode 100644 index 00000000..e325b9e9 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-openstack.yml @@ -0,0 +1,14 @@ +HOSTS: + centos-6-x64: + default_apply_opts: + order: random + strict_variables: + platform: el-6-x86_64 + hypervisor : openstack + flavor: m1.small + image: centos-6-latest + user: root +CONFIG: + type: foss + log_level: debug + openstack_network: default diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-vagrant.yml b/puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-vagrant.yml new file mode 100644 index 00000000..f06036ec --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/centos-6-x86_64-vagrant.yml @@ -0,0 +1,11 @@ +HOSTS: + centos-6-x64: + default_apply_opts: + order: random + strict_variables: + platform: el-6-x86_64 + hypervisor : vagrant + box : camptocamp/centos-6-x86_64 +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-docker.yml b/puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-docker.yml new file mode 100644 index 00000000..0bc97271 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-docker.yml @@ -0,0 +1,15 @@ +HOSTS: + centos-7-x64: + default_apply_opts: + order: random + strict_variables: + platform: el-7-x86_64 + hypervisor : docker + image: centos:7 + docker_preserve_image: true + docker_cmd: '["/usr/sbin/init"]' + docker_image_commands: + - 'yum install -y crontabs tar wget' +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-openstack.yml b/puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-openstack.yml new file mode 100644 index 00000000..9003c867 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-openstack.yml @@ -0,0 +1,14 @@ +HOSTS: + centos-7-x64: + default_apply_opts: + order: random + strict_variables: + platform: el-7-x86_64 + hypervisor : openstack + flavor: m1.small + image: centos-7-latest + user: centos +CONFIG: + type: foss + log_level: debug + openstack_network: default diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-vagrant.yml b/puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-vagrant.yml new file mode 100644 index 00000000..95402e54 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/centos-7-x86_64-vagrant.yml @@ -0,0 +1,11 @@ +HOSTS: + centos-7-x64: + default_apply_opts: + order: random + strict_variables: + platform: el-7-x86_64 + hypervisor : vagrant + box : camptocamp/centos-7-x86_64 +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-docker.yml b/puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-docker.yml new file mode 100644 index 00000000..359dae7d --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-docker.yml @@ -0,0 +1,15 @@ +HOSTS: + debian-6-x64: + default_apply_opts: + order: random + strict_variables: + platform: debian-6-amd64 + hypervisor : docker + image: debian:6 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get install -y wget' +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-openstack.yml b/puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-openstack.yml new file mode 100644 index 00000000..c6c192fe --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-openstack.yml @@ -0,0 +1,14 @@ +HOSTS: + debian-6-x64: + default_apply_opts: + order: random + strict_variables: + platform: debian-6-amd64 + hypervisor : openstack + flavor: m1.small + image: debian-6-latest + user: debian +CONFIG: + type: foss + log_level: debug + openstack_network: default diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-vagrant.yml b/puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-vagrant.yml new file mode 100644 index 00000000..03db0fa7 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/debian-6-x86_64-vagrant.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-6-x64: + default_apply_opts: + order: random + strict_variables: + platform: debian-6-amd64 + hypervisor : vagrant + box : puppetlabs/debian-6.0.10-64-nocm +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-docker.yml b/puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-docker.yml new file mode 100644 index 00000000..fc11f574 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-docker.yml @@ -0,0 +1,15 @@ +HOSTS: + debian-7-x64: + default_apply_opts: + order: random + strict_variables: + platform: debian-7-amd64 + hypervisor : docker + image: debian:7 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get install -y cron wget' +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-openstack.yml b/puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-openstack.yml new file mode 100644 index 00000000..017b4c74 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-openstack.yml @@ -0,0 +1,14 @@ +HOSTS: + debian-7-x64: + default_apply_opts: + order: random + strict_variables: + platform: debian-7-amd64 + hypervisor : openstack + flavor: m1.small + image: debian-7-latest + user: debian +CONFIG: + type: foss + log_level: debug + openstack_network: default diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-vagrant.yml b/puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-vagrant.yml new file mode 100644 index 00000000..8ed1264d --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/debian-7-x86_64-vagrant.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-7-x64: + default_apply_opts: + order: random + strict_variables: + platform: debian-7-amd64 + hypervisor : vagrant + box : camptocamp/debian-7-amd64 +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-docker.yml b/puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-docker.yml new file mode 100644 index 00000000..86a55e15 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-docker.yml @@ -0,0 +1,15 @@ +HOSTS: + debian-8-x64: + default_apply_opts: + order: random + strict_variables: + platform: debian-8-amd64 + hypervisor : docker + image: debian:8 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get install -y cron wget' +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-openstack.yml b/puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-openstack.yml new file mode 100644 index 00000000..003b6f4b --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-openstack.yml @@ -0,0 +1,14 @@ +HOSTS: + debian-8-x64: + default_apply_opts: + order: random + strict_variables: + platform: debian-8-amd64 + hypervisor : openstack + flavor: m1.small + image: debian-8-latest + user: debian +CONFIG: + type: foss + log_level: debug + openstack_network: default diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-vagrant.yml b/puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-vagrant.yml new file mode 100644 index 00000000..5cc7f0c5 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/debian-8-x86_64-vagrant.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-8-x64: + default_apply_opts: + order: random + strict_variables: + platform: debian-8-amd64 + hypervisor : vagrant + box : camptocamp/debian-8-amd64 +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-10.04-x86_64-docker.yml b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-10.04-x86_64-docker.yml new file mode 100644 index 00000000..933dee60 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-10.04-x86_64-docker.yml @@ -0,0 +1,13 @@ +HOSTS: + ubuntu-1004-x64: + default_apply_opts: + order: random + strict_variables: + platform: ubuntu-10.04-amd64 + hypervisor : docker + image: ubuntu:10.04 + # This stops the image from being deleted on completion, speeding up the process. + docker_preserve_image: true +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-12.04-x86_64-docker.yml b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-12.04-x86_64-docker.yml new file mode 100644 index 00000000..f0ec72b8 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-12.04-x86_64-docker.yml @@ -0,0 +1,15 @@ +HOSTS: + ubuntu-1204-x64: + default_apply_opts: + order: random + strict_variables: + platform: ubuntu-12.04-amd64 + hypervisor : docker + image: ubuntu:12.04 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get install -y wget' +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-12.04-x86_64-openstack.yml b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-12.04-x86_64-openstack.yml new file mode 100644 index 00000000..f81b04b7 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-12.04-x86_64-openstack.yml @@ -0,0 +1,14 @@ +HOSTS: + ubuntu-1204-x64: + default_apply_opts: + order: random + strict_variables: + platform: ubuntu-12.04-amd64 + hypervisor : openstack + flavor: m1.small + image: ubuntu-1204-latest + user: ubuntu +CONFIG: + type: foss + log_level: debug + openstack_network: default diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-docker.yml b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-docker.yml new file mode 100644 index 00000000..6fb9281e --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-docker.yml @@ -0,0 +1,15 @@ +HOSTS: + ubuntu-1404-x64: + default_apply_opts: + order: random + strict_variables: + platform: ubuntu-14.04-amd64 + hypervisor : docker + image: ubuntu:14.04 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get install -y wget' +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-openstack.yml b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-openstack.yml new file mode 100644 index 00000000..2eeb912d --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-openstack.yml @@ -0,0 +1,14 @@ +HOSTS: + ubuntu-1404-x64: + default_apply_opts: + order: random + strict_variables: + platform: ubuntu-14.04-amd64 + hypervisor : openstack + flavor: m1.small + image: ubuntu-1404-latest + user: ubuntu +CONFIG: + type: foss + log_level: debug + openstack_network: default diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-vagrant.yml b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-vagrant.yml new file mode 100644 index 00000000..3b376953 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.04-x86_64-vagrant.yml @@ -0,0 +1,11 @@ +HOSTS: + ubuntu-1404-x64: + default_apply_opts: + order: random + strict_variables: + platform: ubuntu-14.04-amd64 + hypervisor : vagrant + box : puppetlabs/ubuntu-14.04-64-nocm +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.10-x86_64-docker.yml b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.10-x86_64-docker.yml new file mode 100644 index 00000000..2be425c5 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.10-x86_64-docker.yml @@ -0,0 +1,15 @@ +HOSTS: + ubuntu-1410-x64: + default_apply_opts: + order: random + strict_variables: + platform: ubuntu-14.10-amd64 + hypervisor : docker + image: ubuntu:14.10 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get install -y wget' +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.10-x86_64-openstack.yml b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.10-x86_64-openstack.yml new file mode 100644 index 00000000..58a2acd2 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-14.10-x86_64-openstack.yml @@ -0,0 +1,14 @@ +HOSTS: + ubuntu-1410-x64: + default_apply_opts: + order: random + strict_variables: + platform: ubuntu-14.10-amd64 + hypervisor : openstack + flavor: m1.small + image: ubuntu-1410-latest + user: ubuntu +CONFIG: + type: foss + log_level: debug + openstack_network: default diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-15.04-x86_64-docker.yml b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-15.04-x86_64-docker.yml new file mode 100644 index 00000000..caed722c --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-15.04-x86_64-docker.yml @@ -0,0 +1,15 @@ +HOSTS: + ubuntu-1504-x64: + default_apply_opts: + order: random + strict_variables: + platform: ubuntu-15.04-amd64 + hypervisor : docker + image: ubuntu:15.04 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get install -y wget' +CONFIG: + type: foss + log_level: debug diff --git a/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-15.04-x86_64-openstack.yml b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-15.04-x86_64-openstack.yml new file mode 100644 index 00000000..22ef76c4 --- /dev/null +++ b/puppet/modules/systemd/spec/acceptance/nodesets/ubuntu-15.04-x86_64-openstack.yml @@ -0,0 +1,14 @@ +HOSTS: + ubuntu-1504-x64: + default_apply_opts: + order: random + strict_variables: + platform: ubuntu-15.04-amd64 + hypervisor : openstack + flavor: m1.small + image: ubuntu-1504-latest + user: ubuntu +CONFIG: + type: foss + log_level: debug + openstack_network: default diff --git a/puppet/modules/systemd/spec/spec.opts b/puppet/modules/systemd/spec/spec.opts new file mode 100644 index 00000000..91cd6427 --- /dev/null +++ b/puppet/modules/systemd/spec/spec.opts @@ -0,0 +1,6 @@ +--format +s +--colour +--loadby +mtime +--backtrace diff --git a/puppet/modules/systemd/spec/spec_helper.rb b/puppet/modules/systemd/spec/spec_helper.rb new file mode 100644 index 00000000..94d30d5c --- /dev/null +++ b/puppet/modules/systemd/spec/spec_helper.rb @@ -0,0 +1,42 @@ +require 'puppetlabs_spec_helper/module_spec_helper' +require 'rspec-puppet-facts' +include RspecPuppetFacts + + +RSpec.configure do |c| + c.include PuppetlabsSpec::Files + + c.before :each do + # Store any environment variables away to be restored later + @old_env = {} + ENV.each_key {|k| @old_env[k] = ENV[k]} + + c.strict_variables = Gem::Version.new(Puppet.version) >= Gem::Version.new('3.5') + Puppet.features.stubs(:root?).returns(true) + end + + c.after :each do + PuppetlabsSpec::Files.cleanup + end +end + +require 'pathname' +dir = Pathname.new(__FILE__).parent +Puppet[:modulepath] = File.join(dir, 'fixtures', 'modules') + +# There's no real need to make this version dependent, but it helps find +# regressions in Puppet +# +# 1. Workaround for issue #16277 where default settings aren't initialised from +# a spec and so the libdir is never initialised (3.0.x) +# 2. Workaround for 2.7.20 that now only loads types for the current node +# environment (#13858) so Puppet[:modulepath] seems to get ignored +# 3. Workaround for 3.5 where context hasn't been configured yet, +# ticket https://tickets.puppetlabs.com/browse/MODULES-823 +# +ver = Gem::Version.new(Puppet.version.split('-').first) +if Gem::Requirement.new("~> 2.7.20") =~ ver || Gem::Requirement.new("~> 3.0.0") =~ ver || Gem::Requirement.new("~> 3.5") =~ ver || Gem::Requirement.new("~> 4.0") + puts "augeasproviders: setting Puppet[:libdir] to work around broken type autoloading" + # libdir is only a single dir, so it can only workaround loading of one external module + Puppet[:libdir] = "#{Puppet[:modulepath]}/augeasproviders_core/lib" +end -- cgit v1.2.3 From f3f78ebaf5f3fd3233bc35596fefb51f6e5ed9d9 Mon Sep 17 00:00:00 2001 From: varac Date: Mon, 13 Jun 2016 20:11:23 +0200 Subject: Notify Exec[shorewall_check] not Service[shorew..] Latest shorewall module does `shorewall check` (executed by `Exec[shorewall_check]`) so every related resource change must notify this Exec instead of `Service[shorewall]` as before. --- puppet/modules/site_couchdb/manifests/init.pp | 2 +- puppet/modules/site_nickserver/manifests/init.pp | 2 +- puppet/modules/site_shorewall/manifests/defaults.pp | 7 ++++--- puppet/modules/site_shorewall/manifests/eip.pp | 3 ++- puppet/modules/site_shorewall/manifests/ip_forward.pp | 3 ++- puppet/modules/site_shorewall/manifests/mx.pp | 3 ++- puppet/modules/site_shorewall/manifests/obfsproxy.pp | 2 +- puppet/modules/site_shorewall/manifests/service/webapp_api.pp | 2 +- puppet/modules/site_shorewall/manifests/soledad.pp | 3 ++- puppet/modules/site_shorewall/manifests/sshd.pp | 2 +- puppet/modules/site_shorewall/manifests/stunnel/server.pp | 2 +- puppet/modules/site_shorewall/manifests/tor.pp | 2 +- puppet/modules/site_sshd/manifests/mosh.pp | 3 ++- 13 files changed, 21 insertions(+), 15 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_couchdb/manifests/init.pp b/puppet/modules/site_couchdb/manifests/init.pp index 554bf813..5a73ae87 100644 --- a/puppet/modules/site_couchdb/manifests/init.pp +++ b/puppet/modules/site_couchdb/manifests/init.pp @@ -42,7 +42,7 @@ class site_couchdb { include site_couchdb::plain Class['site_config::default'] - -> Service['shorewall'] + -> Exec['shorewall_check'] -> Exec['refresh_stunnel'] -> Class['couchdb'] -> Class['site_couchdb::setup'] diff --git a/puppet/modules/site_nickserver/manifests/init.pp b/puppet/modules/site_nickserver/manifests/init.pp index eb4415e7..ad97f829 100644 --- a/puppet/modules/site_nickserver/manifests/init.pp +++ b/puppet/modules/site_nickserver/manifests/init.pp @@ -149,7 +149,7 @@ class site_nickserver { file { '/etc/shorewall/macro.nickserver': content => "PARAM - - tcp ${nickserver_port}", - notify => Service['shorewall'], + notify => Exec['shorewall_check'], require => Package['shorewall']; } diff --git a/puppet/modules/site_shorewall/manifests/defaults.pp b/puppet/modules/site_shorewall/manifests/defaults.pp index ceb17868..725e0880 100644 --- a/puppet/modules/site_shorewall/manifests/defaults.pp +++ b/puppet/modules/site_shorewall/manifests/defaults.pp @@ -1,3 +1,4 @@ +# Configure basic firewall rules for shorewall class site_shorewall::defaults { include shorewall @@ -55,7 +56,7 @@ class site_shorewall::defaults { mode => '0644', source => 'puppet:///modules/site_shorewall/Debian/shorewall.service', require => Package['shorewall'], - notify => Service['shorewall'], + notify => Exec['shorewall_check'], } ~> Exec['systemctl-daemon-reload'] @@ -66,14 +67,14 @@ class site_shorewall::defaults { lens => 'Shellvars.lns', incl => '/etc/shorewall/shorewall.conf', require => Package['shorewall'], - notify => Service['shorewall']; + notify => Exec['shorewall_check']; # require that the interface exist 'shorewall_REQUIRE_INTERFACE': changes => 'set /files/etc/shorewall/shorewall.conf/REQUIRE_INTERFACE Yes', lens => 'Shellvars.lns', incl => '/etc/shorewall/shorewall.conf', require => Package['shorewall'], - notify => Service['shorewall']; + notify => Exec['shorewall_check']; # configure shorewall-init 'shorewall-init': changes => 'set /files/etc/default/shorewall-init/PRODUCTS shorewall', diff --git a/puppet/modules/site_shorewall/manifests/eip.pp b/puppet/modules/site_shorewall/manifests/eip.pp index 8fbba658..21934761 100644 --- a/puppet/modules/site_shorewall/manifests/eip.pp +++ b/puppet/modules/site_shorewall/manifests/eip.pp @@ -1,3 +1,4 @@ +# Configure shorewall on eip/vpn nodes class site_shorewall::eip { include site_shorewall::defaults @@ -9,7 +10,7 @@ class site_shorewall::eip { content => "PARAM - - tcp 1194 PARAM - - udp 1194 ", - notify => Service['shorewall'], + notify => Exec['shorewall_check'], require => Package['shorewall'] } diff --git a/puppet/modules/site_shorewall/manifests/ip_forward.pp b/puppet/modules/site_shorewall/manifests/ip_forward.pp index d53ee8a5..beb1f055 100644 --- a/puppet/modules/site_shorewall/manifests/ip_forward.pp +++ b/puppet/modules/site_shorewall/manifests/ip_forward.pp @@ -1,10 +1,11 @@ +# Configure ip forwarding for shorewall class site_shorewall::ip_forward { include augeas augeas { 'enable_ip_forwarding': changes => 'set /files/etc/shorewall/shorewall.conf/IP_FORWARDING Yes', lens => 'Shellvars.lns', incl => '/etc/shorewall/shorewall.conf', - notify => Service[shorewall], + notify => Exec['shorewall_check'], require => [ Class[augeas], Package[shorewall] ]; } } diff --git a/puppet/modules/site_shorewall/manifests/mx.pp b/puppet/modules/site_shorewall/manifests/mx.pp index 332f164e..2500668f 100644 --- a/puppet/modules/site_shorewall/manifests/mx.pp +++ b/puppet/modules/site_shorewall/manifests/mx.pp @@ -1,3 +1,4 @@ +# Configure leap-mx shorewall rules class site_shorewall::mx { include site_shorewall::defaults @@ -7,7 +8,7 @@ class site_shorewall::mx { # define macro for incoming services file { '/etc/shorewall/macro.leap_mx': content => "PARAM - - tcp ${smtpd_ports} ", - notify => Service['shorewall'], + notify => Exec['shorewall_check'], require => Package['shorewall'] } diff --git a/puppet/modules/site_shorewall/manifests/obfsproxy.pp b/puppet/modules/site_shorewall/manifests/obfsproxy.pp index 75846705..3c82dc40 100644 --- a/puppet/modules/site_shorewall/manifests/obfsproxy.pp +++ b/puppet/modules/site_shorewall/manifests/obfsproxy.pp @@ -10,7 +10,7 @@ class site_shorewall::obfsproxy { # define macro for incoming services file { '/etc/shorewall/macro.leap_obfsproxy': content => "PARAM - - tcp ${scram_port} ", - notify => Service['shorewall'], + notify => Exec['shorewall_check'], require => Package['shorewall'] } diff --git a/puppet/modules/site_shorewall/manifests/service/webapp_api.pp b/puppet/modules/site_shorewall/manifests/service/webapp_api.pp index d3a1aeed..e3ae4200 100644 --- a/puppet/modules/site_shorewall/manifests/service/webapp_api.pp +++ b/puppet/modules/site_shorewall/manifests/service/webapp_api.pp @@ -7,7 +7,7 @@ class site_shorewall::service::webapp_api { # define macro for incoming services file { '/etc/shorewall/macro.leap_webapp_api': content => "PARAM - - tcp ${api_port} ", - notify => Service['shorewall'], + notify => Exec['shorewall_check'], require => Package['shorewall'] } diff --git a/puppet/modules/site_shorewall/manifests/soledad.pp b/puppet/modules/site_shorewall/manifests/soledad.pp index 518d8689..5bee07af 100644 --- a/puppet/modules/site_shorewall/manifests/soledad.pp +++ b/puppet/modules/site_shorewall/manifests/soledad.pp @@ -1,3 +1,4 @@ +# Setup soledad server class site_shorewall::soledad { $soledad = hiera('soledad') @@ -8,7 +9,7 @@ class site_shorewall::soledad { # define macro for incoming services file { '/etc/shorewall/macro.leap_soledad': content => "PARAM - - tcp ${soledad_port}", - notify => Service['shorewall'], + notify => Exec['shorewall_check'], require => Package['shorewall'] } diff --git a/puppet/modules/site_shorewall/manifests/sshd.pp b/puppet/modules/site_shorewall/manifests/sshd.pp index e2332592..ba129002 100644 --- a/puppet/modules/site_shorewall/manifests/sshd.pp +++ b/puppet/modules/site_shorewall/manifests/sshd.pp @@ -9,7 +9,7 @@ class site_shorewall::sshd { # define macro for incoming sshd file { '/etc/shorewall/macro.leap_sshd': content => "PARAM - - tcp ${ssh_port}", - notify => Service['shorewall'], + notify => Exec['shorewall_check'], require => Package['shorewall'] } diff --git a/puppet/modules/site_shorewall/manifests/stunnel/server.pp b/puppet/modules/site_shorewall/manifests/stunnel/server.pp index 798cd631..dae4142a 100644 --- a/puppet/modules/site_shorewall/manifests/stunnel/server.pp +++ b/puppet/modules/site_shorewall/manifests/stunnel/server.pp @@ -8,7 +8,7 @@ define site_shorewall::stunnel::server($port) { file { "/etc/shorewall/macro.stunnel_server_${name}": content => "PARAM - - tcp ${port}", - notify => Service['shorewall'], + notify => Exec['shorewall_check'], require => Package['shorewall'] } shorewall::rule { diff --git a/puppet/modules/site_shorewall/manifests/tor.pp b/puppet/modules/site_shorewall/manifests/tor.pp index 324b4844..f4d5ed92 100644 --- a/puppet/modules/site_shorewall/manifests/tor.pp +++ b/puppet/modules/site_shorewall/manifests/tor.pp @@ -9,7 +9,7 @@ class site_shorewall::tor { # define macro for incoming services file { '/etc/shorewall/macro.leap_tor': content => "PARAM - - tcp ${tor_port} ", - notify => Service['shorewall'], + notify => Exec['shorewall_check'], require => Package['shorewall'] } diff --git a/puppet/modules/site_sshd/manifests/mosh.pp b/puppet/modules/site_sshd/manifests/mosh.pp index 49f56ca0..5282d239 100644 --- a/puppet/modules/site_sshd/manifests/mosh.pp +++ b/puppet/modules/site_sshd/manifests/mosh.pp @@ -1,3 +1,4 @@ +# setup mosh on server class site_sshd::mosh ( $ensure = present, $ports = '60000-61000' ) { package { 'mosh': @@ -7,7 +8,7 @@ class site_sshd::mosh ( $ensure = present, $ports = '60000-61000' ) { file { '/etc/shorewall/macro.mosh': ensure => $ensure, content => "PARAM - - udp ${ports}", - notify => Service['shorewall'], + notify => Exec['shorewall_check'], require => Package['shorewall']; } -- cgit v1.2.3 From 50d30b2aa77efc304f0cc5e4f6f561a8e770986b Mon Sep 17 00:00:00 2001 From: varac Date: Sat, 11 Jun 2016 22:58:26 +0200 Subject: Newest passenger module dont manage munin by default --- puppet/modules/site_webapp/manifests/apache.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_webapp/manifests/apache.pp b/puppet/modules/site_webapp/manifests/apache.pp index 80c7b29b..e559217d 100644 --- a/puppet/modules/site_webapp/manifests/apache.pp +++ b/puppet/modules/site_webapp/manifests/apache.pp @@ -18,7 +18,7 @@ class site_webapp::apache { include apache::module::removeip include site_webapp::common_vhost - class { 'passenger': use_munin => false } + class { 'passenger': } apache::vhost::file { 'api': -- cgit v1.2.3 From 68544ba2ffdfa988c060b3b4c5bd075f7304a022 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 11:11:56 -0400 Subject: Block MTAs that claim they are 'localhost'. Nobody should be claiming that they are localhost when they are connecting over smtpd Change-Id: Ifb7df855b4e12021c58b89b2053e31fb10806096 --- puppet/modules/site_postfix/templates/checks/helo_access.erb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_postfix/templates/checks/helo_access.erb b/puppet/modules/site_postfix/templates/checks/helo_access.erb index bac2c45a..e0708605 100644 --- a/puppet/modules/site_postfix/templates/checks/helo_access.erb +++ b/puppet/modules/site_postfix/templates/checks/helo_access.erb @@ -19,3 +19,5 @@ # Reject anybody that HELO's as being in our own domain(s) # anyone who identifies themselves as us is a virus/spammer <%= @domain %> 554 You are not in domain <%= @domain %> +localhost 554 You are not localhost + -- cgit v1.2.3 From bbdc193f05cb2f1624d6c7bbffd27f8060de35c8 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 12 Jul 2016 11:20:58 -0400 Subject: Block ip-based helo at MTA (#8139). Numeric helo is a very strong indicator of spam. When this is blocked, a very significant amount of spam stops. Change-Id: Ieb340190faf37638950d1aa60b52268659e0b7f6 --- puppet/modules/site_postfix/files/checks/helo_access.pcre | 2 ++ puppet/modules/site_postfix/manifests/mx/checks.pp | 7 +++++++ puppet/modules/site_postfix/manifests/mx/smtpd_checks.pp | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 puppet/modules/site_postfix/files/checks/helo_access.pcre (limited to 'puppet/modules') diff --git a/puppet/modules/site_postfix/files/checks/helo_access.pcre b/puppet/modules/site_postfix/files/checks/helo_access.pcre new file mode 100644 index 00000000..4ebd42e6 --- /dev/null +++ b/puppet/modules/site_postfix/files/checks/helo_access.pcre @@ -0,0 +1,2 @@ +!/[[:alpha:]]/ REJECT Numeric HELO is a sign of spam, please contact us if this is in error + diff --git a/puppet/modules/site_postfix/manifests/mx/checks.pp b/puppet/modules/site_postfix/manifests/mx/checks.pp index f406ad34..9678c205 100644 --- a/puppet/modules/site_postfix/manifests/mx/checks.pp +++ b/puppet/modules/site_postfix/manifests/mx/checks.pp @@ -1,3 +1,4 @@ +# management of specific MTA checks class site_postfix::mx::checks { file { @@ -13,6 +14,12 @@ class site_postfix::mx::checks { mode => '0644', owner => root, group => root; + + '/etc/postfix/checks/helo_checks.pcre': + source => 'puppet:///modules/site_postfix/checks/helo_access.pcre', + mode => '0644', + owner => root, + group => root; } exec { diff --git a/puppet/modules/site_postfix/manifests/mx/smtpd_checks.pp b/puppet/modules/site_postfix/manifests/mx/smtpd_checks.pp index 291d7ee4..162e6d86 100644 --- a/puppet/modules/site_postfix/manifests/mx/smtpd_checks.pp +++ b/puppet/modules/site_postfix/manifests/mx/smtpd_checks.pp @@ -28,7 +28,7 @@ class site_postfix::mx::smtpd_checks { 'smtps_relay_restrictions': value => 'permit_mynetworks, permit_tls_clientcerts, defer_unauth_destination'; 'smtps_helo_restrictions': - value => 'permit_mynetworks, check_helo_access hash:$checks_dir/helo_checks, permit'; + value => 'permit_mynetworks, check_helo_access hash:$checks_dir/helo_checks, check_helo_access pcre:$checks_dir/helo_checks.pcre, permit'; 'smtpd_sender_restrictions': value => 'permit_mynetworks, reject_non_fqdn_sender, reject_unknown_sender_domain, permit'; } -- cgit v1.2.3 From d6b064672d49e421e34f2165513178ffa7cee8ab Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 14 Jul 2016 11:04:19 -0400 Subject: Only use the 'main' repository for apt (#8253) Change-Id: If39222dc9ec68d1786c70c4b82b740e0a06773c4 --- puppet/modules/site_apt/manifests/init.pp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_apt/manifests/init.pp b/puppet/modules/site_apt/manifests/init.pp index 455425c1..26bd2c6a 100644 --- a/puppet/modules/site_apt/manifests/init.pp +++ b/puppet/modules/site_apt/manifests/init.pp @@ -25,7 +25,8 @@ class site_apt { debian_url => $apt_url_basic, security_url => $apt_url_security, backports_url => $apt_url_backports, - use_next_release => $use_next_release + use_next_release => $use_next_release, + repos => 'main' } # enable http://deb.leap.se debian package repository -- cgit v1.2.3 From d6719731dce8ee7e048a16a447a426abcaa44f24 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 21 Jul 2016 12:13:24 -0700 Subject: remove openvpn submodule --- puppet/modules/openvpn/.fixtures.yml | 6 - puppet/modules/openvpn/.gitignore | 3 - puppet/modules/openvpn/.gitrepo | 11 - puppet/modules/openvpn/.rvmrc | 38 ---- puppet/modules/openvpn/.travis.yml | 29 --- puppet/modules/openvpn/Gemfile | 7 - puppet/modules/openvpn/Gemfile.lock | 36 ---- puppet/modules/openvpn/LICENSE | 177 ---------------- puppet/modules/openvpn/Modulefile | 11 - puppet/modules/openvpn/Rakefile | 2 - puppet/modules/openvpn/Readme.markdown | 54 ----- puppet/modules/openvpn/Vagrantfile | 42 ---- puppet/modules/openvpn/manifests/client.pp | 187 ----------------- .../openvpn/manifests/client_specific_config.pp | 79 ------- puppet/modules/openvpn/manifests/config.pp | 52 ----- puppet/modules/openvpn/manifests/init.pp | 43 ---- puppet/modules/openvpn/manifests/install.pp | 46 ---- puppet/modules/openvpn/manifests/params.pp | 37 ---- puppet/modules/openvpn/manifests/server.pp | 233 --------------------- puppet/modules/openvpn/manifests/service.pp | 36 ---- .../openvpn/spec/classes/openvpn_config_spec.rb | 15 -- .../openvpn/spec/classes/openvpn_init_spec.rb | 9 - .../openvpn/spec/classes/openvpn_install_spec.rb | 11 - .../openvpn/spec/classes/openvpn_service_spec.rb | 13 -- .../openvpn/spec/defines/openvpn_client_spec.rb | 88 -------- .../defines/openvpn_client_specific_config_spec.rb | 40 ---- .../openvpn/spec/defines/openvpn_server_spec.rb | 165 --------------- puppet/modules/openvpn/spec/spec_helper.rb | 2 - puppet/modules/openvpn/templates/client.erb | 26 --- .../openvpn/templates/client_specific_config.erb | 10 - .../openvpn/templates/etc-default-openvpn.erb | 20 -- puppet/modules/openvpn/templates/server.erb | 37 ---- puppet/modules/openvpn/templates/vars.erb | 68 ------ puppet/modules/openvpn/vagrant/client.pp | 5 - puppet/modules/openvpn/vagrant/server.pp | 23 -- 35 files changed, 1661 deletions(-) delete mode 100644 puppet/modules/openvpn/.fixtures.yml delete mode 100644 puppet/modules/openvpn/.gitignore delete mode 100644 puppet/modules/openvpn/.gitrepo delete mode 100644 puppet/modules/openvpn/.rvmrc delete mode 100644 puppet/modules/openvpn/.travis.yml delete mode 100644 puppet/modules/openvpn/Gemfile delete mode 100644 puppet/modules/openvpn/Gemfile.lock delete mode 100644 puppet/modules/openvpn/LICENSE delete mode 100644 puppet/modules/openvpn/Modulefile delete mode 100644 puppet/modules/openvpn/Rakefile delete mode 100644 puppet/modules/openvpn/Readme.markdown delete mode 100644 puppet/modules/openvpn/Vagrantfile delete mode 100644 puppet/modules/openvpn/manifests/client.pp delete mode 100644 puppet/modules/openvpn/manifests/client_specific_config.pp delete mode 100644 puppet/modules/openvpn/manifests/config.pp delete mode 100644 puppet/modules/openvpn/manifests/init.pp delete mode 100644 puppet/modules/openvpn/manifests/install.pp delete mode 100644 puppet/modules/openvpn/manifests/params.pp delete mode 100644 puppet/modules/openvpn/manifests/server.pp delete mode 100644 puppet/modules/openvpn/manifests/service.pp delete mode 100644 puppet/modules/openvpn/spec/classes/openvpn_config_spec.rb delete mode 100644 puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb delete mode 100644 puppet/modules/openvpn/spec/classes/openvpn_install_spec.rb delete mode 100644 puppet/modules/openvpn/spec/classes/openvpn_service_spec.rb delete mode 100644 puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb delete mode 100644 puppet/modules/openvpn/spec/defines/openvpn_client_specific_config_spec.rb delete mode 100644 puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb delete mode 100644 puppet/modules/openvpn/spec/spec_helper.rb delete mode 100644 puppet/modules/openvpn/templates/client.erb delete mode 100644 puppet/modules/openvpn/templates/client_specific_config.erb delete mode 100644 puppet/modules/openvpn/templates/etc-default-openvpn.erb delete mode 100644 puppet/modules/openvpn/templates/server.erb delete mode 100644 puppet/modules/openvpn/templates/vars.erb delete mode 100644 puppet/modules/openvpn/vagrant/client.pp delete mode 100644 puppet/modules/openvpn/vagrant/server.pp (limited to 'puppet/modules') diff --git a/puppet/modules/openvpn/.fixtures.yml b/puppet/modules/openvpn/.fixtures.yml deleted file mode 100644 index 1125ecca..00000000 --- a/puppet/modules/openvpn/.fixtures.yml +++ /dev/null @@ -1,6 +0,0 @@ -fixtures: - repositories: - concat: git://github.com/ripienaar/puppet-concat.git - symlinks: - openvpn: "#{source_dir}" - diff --git a/puppet/modules/openvpn/.gitignore b/puppet/modules/openvpn/.gitignore deleted file mode 100644 index 6fd248b3..00000000 --- a/puppet/modules/openvpn/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -pkg -spec/fixtures -.vagrant diff --git a/puppet/modules/openvpn/.gitrepo b/puppet/modules/openvpn/.gitrepo deleted file mode 100644 index 0c191cd8..00000000 --- a/puppet/modules/openvpn/.gitrepo +++ /dev/null @@ -1,11 +0,0 @@ -; DO NOT EDIT (unless you know what you are doing) -; -; This subdirectory is a git "subrepo", and this file is maintained by the -; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme -; -[subrepo] - remote = https://leap.se/git/puppet_openvpn - branch = master - commit = 26d4edc669853a268a65d2cbbfb42c19f1333de7 - parent = 7ce3190986cf8e5fe037a7ccd4c1076505b117f4 - cmdver = 0.3.0 diff --git a/puppet/modules/openvpn/.rvmrc b/puppet/modules/openvpn/.rvmrc deleted file mode 100644 index 6fbfb7f1..00000000 --- a/puppet/modules/openvpn/.rvmrc +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - -# This is an RVM Project .rvmrc file, used to automatically load the ruby -# development environment upon cd'ing into the directory - -# First we specify our desired [@], the @gemset name is optional, -# Only full ruby name is supported here, for short names use: -# echo "rvm use 1.9.3" > .rvmrc -environment_id="ruby-1.9.3-p194@puppet" - -# Uncomment the following lines if you want to verify rvm version per project -# rvmrc_rvm_version="1.15.8 (stable)" # 1.10.1 seams as a safe start -# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || { -# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading." -# return 1 -# } - -# First we attempt to load the desired environment directly from the environment -# file. This is very fast and efficient compared to running through the entire -# CLI and selector. If you want feedback on which environment was used then -# insert the word 'use' after --create as this triggers verbose mode. -if [[ -d "${rvm_path:-$HOME/.rvm}/environments" - && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]] -then - \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id" - [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] && - \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true - if [[ $- == *i* ]] # check for interactive shells - then echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green - else echo "Using: $GEM_HOME" # don't use colors in non-interactive shells - fi -else - # If the environment file has not yet been created, use the RVM CLI to select. - rvm --create use "$environment_id" || { - echo "Failed to create RVM environment '${environment_id}'." - return 1 - } -fi diff --git a/puppet/modules/openvpn/.travis.yml b/puppet/modules/openvpn/.travis.yml deleted file mode 100644 index da5c389d..00000000 --- a/puppet/modules/openvpn/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: ruby -bundler_args: --without development -script: "bundle exec rake spec SPEC_OPTS='--format documentation'" -rvm: - - 1.8.7 - - 1.9.3 - - 2.0.0 -script: - - "rake lint" - - "rake spec SPEC_OPTS='--format documentation'" -env: - - PUPPET_VERSION="~> 2.7.0" - - PUPPET_VERSION="~> 3.0.0" - - PUPPET_VERSION="~> 3.1.0" - - PUPPET_VERSION="~> 3.2.0" -matrix: - exclude: - - rvm: 1.9.3 - env: PUPPET_VERSION="~> 2.7.0" - - rvm: 2.0.0 - env: PUPPET_VERSION="~> 2.7.0" - - rvm: 2.0.0 - env: PUPPET_VERSION="~> 3.0.0" - - rvm: 2.0.0 - env: PUPPET_VERSION="~> 3.1.0" -notifications: - email: false - on_success: always - on_failure: always diff --git a/puppet/modules/openvpn/Gemfile b/puppet/modules/openvpn/Gemfile deleted file mode 100644 index 68e10e7d..00000000 --- a/puppet/modules/openvpn/Gemfile +++ /dev/null @@ -1,7 +0,0 @@ -source :rubygems - -puppetversion = ENV['PUPPET_VERSION'] -gem 'puppet', puppetversion, :require => false -gem 'puppet-lint' -gem 'rspec-puppet' -gem 'puppetlabs_spec_helper' diff --git a/puppet/modules/openvpn/Gemfile.lock b/puppet/modules/openvpn/Gemfile.lock deleted file mode 100644 index 9fce3f98..00000000 --- a/puppet/modules/openvpn/Gemfile.lock +++ /dev/null @@ -1,36 +0,0 @@ -GEM - remote: http://rubygems.org/ - specs: - diff-lcs (1.1.3) - facter (1.6.17) - hiera (1.0.0) - metaclass (0.0.1) - mocha (0.13.1) - metaclass (~> 0.0.1) - puppet (3.0.2) - facter (~> 1.6.11) - hiera (~> 1.0.0) - puppetlabs_spec_helper (0.4.0) - mocha (>= 0.10.5) - rake - rspec (>= 2.9.0) - rspec-puppet (>= 0.1.1) - rake (10.0.3) - rspec (2.12.0) - rspec-core (~> 2.12.0) - rspec-expectations (~> 2.12.0) - rspec-mocks (~> 2.12.0) - rspec-core (2.12.2) - rspec-expectations (2.12.1) - diff-lcs (~> 1.1.3) - rspec-mocks (2.12.1) - rspec-puppet (0.1.5) - rspec - -PLATFORMS - ruby - -DEPENDENCIES - puppet - puppetlabs_spec_helper - rspec-puppet diff --git a/puppet/modules/openvpn/LICENSE b/puppet/modules/openvpn/LICENSE deleted file mode 100644 index f433b1a5..00000000 --- a/puppet/modules/openvpn/LICENSE +++ /dev/null @@ -1,177 +0,0 @@ - - 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 diff --git a/puppet/modules/openvpn/Modulefile b/puppet/modules/openvpn/Modulefile deleted file mode 100644 index 679e7e64..00000000 --- a/puppet/modules/openvpn/Modulefile +++ /dev/null @@ -1,11 +0,0 @@ -name 'luxflux-openvpn' -version '2.1.0' -source 'https://github.com/luxflux/puppet-openvpn' -author 'luxflux' -license 'Apache 2.0' -summary 'OpenVPN server puppet module' -description 'Puppet module to manage OpenVPN servers' -project_page 'https://github.com/luxflux/puppet-openvpn' - -## Add dependencies, if any: -dependency 'ripienaar/concat', '0.2.0' diff --git a/puppet/modules/openvpn/Rakefile b/puppet/modules/openvpn/Rakefile deleted file mode 100644 index 14f1c246..00000000 --- a/puppet/modules/openvpn/Rakefile +++ /dev/null @@ -1,2 +0,0 @@ -require 'rubygems' -require 'puppetlabs_spec_helper/rake_tasks' diff --git a/puppet/modules/openvpn/Readme.markdown b/puppet/modules/openvpn/Readme.markdown deleted file mode 100644 index 6bcf49ea..00000000 --- a/puppet/modules/openvpn/Readme.markdown +++ /dev/null @@ -1,54 +0,0 @@ -# OpenVPN Puppet module - -Puppet module to manage OpenVPN servers - -## Features: - -* Client-specific rules and access policies -* Generated client configurations and SSL-Certificates -* Downloadable client configurations and SSL-Certificates for easy client configuration -* Support for multiple server instances - -Tested on Ubuntu Precise Pangolin, CentOS 6, RedHat 6. - - -## Dependencies - - [puppet-concat](https://github.com/ripienaar/puppet-concat) - - -## Example - -```puppet - # add a server instance - openvpn::server { 'winterthur': - country => 'CH', - province => 'ZH', - city => 'Winterthur', - organization => 'example.org', - email => 'root@example.org', - server => '10.200.200.0 255.255.255.0' - } - - # define clients - openvpn::client { 'client1': - server => 'winterthur' - } - openvpn::client { 'client2': - server => 'winterthur' - } - - openvpn::client_specific_config { 'client1': - server => 'winterthur', - ifconfig => '10.200.200.50 255.255.255.0' - } -``` - -Don't forget the [sysctl](https://github.com/luxflux/puppet-sysctl) directive ```net.ipv4.ip_forward```! - - -# Contributors - -These fine folks helped to get this far with this module: -* [@jlambert121](https://github.com/jlambert121) -* [@jlk](https://github.com/jlk) -* [@elisiano](https://github.com/elisiano) diff --git a/puppet/modules/openvpn/Vagrantfile b/puppet/modules/openvpn/Vagrantfile deleted file mode 100644 index 88875ff8..00000000 --- a/puppet/modules/openvpn/Vagrantfile +++ /dev/null @@ -1,42 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -def server_config(config) - config.vm.provision :puppet, :module_path => '..' do |puppet| - puppet.manifests_path = "vagrant" - puppet.manifest_file = "server.pp" - end -end - -def client_config(config) - config.vm.provision :puppet, :module_path => '..' do |puppet| - puppet.manifests_path = "vagrant" - puppet.manifest_file = "client.pp" - end -end - -Vagrant::Config.run do |config| - - config.vm.define :server_ubuntu do |c| - c.vm.box = 'precise64' - server_config c - c.vm.network :hostonly, '10.255.255.10' - end - - config.vm.define :server_centos do |c| - c.vm.box = 'centos63' - - c.vm.provision :shell, :inline => 'if [ ! -f rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm ]; then wget -q http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm; fi' - c.vm.provision :shell, :inline => 'yum install -y rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm || exit 0' - - server_config c - c.vm.network :hostonly, '10.255.255.11' - end - - config.vm.define :client_ubuntu do |c| - c.vm.box = 'precise64' - client_config c - c.vm.network :hostonly, '10.255.255.20' - end - -end diff --git a/puppet/modules/openvpn/manifests/client.pp b/puppet/modules/openvpn/manifests/client.pp deleted file mode 100644 index 92c6aa4e..00000000 --- a/puppet/modules/openvpn/manifests/client.pp +++ /dev/null @@ -1,187 +0,0 @@ -# == Define: openvpn::client -# -# This define creates the client certs for a specified openvpn server as well -# as creating a tarball that can be directly imported into openvpn clients -# -# -# === Parameters -# -# [*server*] -# String. Name of the corresponding openvpn endpoint -# Required -# -# [*compression*] -# String. Which compression algorithim to use -# Default: comp-lzo -# Options: comp-lzo or '' (disable compression) -# -# [*dev*] -# String. Device method -# Default: tun -# Options: tun (routed connections), tap (bridged connections) -# -# [*mute*] -# Integer. Set log mute level -# Default: 20 -# -# [*mute_replay_warnings*] -# Boolean. Silence duplicate packet warnings (common on wireless networks) -# Default: true -# -# [*nobind*] -# Boolean. Whether or not to bind to a specific port number -# Default: true -# -# [*persist_key*] -# Boolean. Try to retain access to resources that may be unavailable -# because of privilege downgrades -# Default: true -# -# [*persist_tun*] -# Boolean. Try to retain access to resources that may be unavailable -# because of privilege downgrades -# Default: true -# -# [*port*] -# Integer. The port the openvpn server service is running on -# Default: 1194 -# -# [*proto*] -# String. What IP protocol is being used. -# Default: tcp -# Options: tcp or udp -# -# [*remote_host*] -# String. The IP or hostname of the openvpn server service -# Default: FQDN -# -# [*resolv_retry*] -# Integer/String. How many seconds should the openvpn client try to resolve -# the server's hostname -# Default: infinite -# Options: Integer or infinite -# -# [*verb*] -# Integer. Level of logging verbosity -# Default: 3 -# -# -# === Examples -# -# openvpn::client { -# 'my_user': -# server => 'contractors', -# remote_host => 'vpn.mycompany.com' -# } -# -# * Removal: -# Manual process right now, todo for the future -# -# -# === Authors -# -# * Raffael Schmid -# * John Kinsella -# * Justin Lambert -# -# === License -# -# Copyright 2013 Raffael Schmid, -# -# 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. -# -define openvpn::client( - $server, - $compression = 'comp-lzo', - $dev = 'tun', - $mute = '20', - $mute_replay_warnings = true, - $nobind = true, - $persist_key = true, - $persist_tun = true, - $port = '1194', - $proto = 'tcp', - $remote_host = $::fqdn, - $resolv_retry = 'infinite', - $verb = '3', -) { - - Openvpn::Server[$server] -> - Openvpn::Client[$name] - - exec { - "generate certificate for ${name} in context of ${server}": - command => ". ./vars && ./pkitool ${name}", - cwd => "/etc/openvpn/${server}/easy-rsa", - creates => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt", - provider => 'shell'; - } - - file { - [ "/etc/openvpn/${server}/download-configs/${name}", - "/etc/openvpn/${server}/download-configs/${name}/keys"]: - ensure => directory; - - "/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt": - ensure => link, - target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt", - require => Exec["generate certificate for ${name} in context of ${server}"]; - - "/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key": - ensure => link, - target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.key", - require => Exec["generate certificate for ${name} in context of ${server}"]; - - "/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt": - ensure => link, - target => "/etc/openvpn/${server}/easy-rsa/keys/ca.crt", - require => Exec["generate certificate for ${name} in context of ${server}"]; - - "/etc/openvpn/${server}/download-configs/${name}/${name}.conf": - owner => root, - group => root, - mode => '0444', - content => template('openvpn/client.erb'), - notify => Exec["tar the thing ${server} with ${name}"]; - } - - exec { - "tar the thing ${server} with ${name}": - cwd => "/etc/openvpn/${server}/download-configs/", - command => "/bin/rm ${name}.tar.gz; tar --exclude=\\*.conf.d -chzvf ${name}.tar.gz ${name}", - refreshonly => true, - require => [ File["/etc/openvpn/${server}/download-configs/${name}/${name}.conf"], - File["/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt"], - File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key"], - File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt"] - ], - notify => Exec["generate ${name}.ovpn in ${server}"]; - } - - exec { - "generate ${name}.ovpn in ${server}": - cwd => "/etc/openvpn/${server}/download-configs/", - command => "/bin/rm ${name}.ovpn; cat ${name}/${name}.conf|perl -lne 'if(m|^ca keys/ca.crt|){ chomp(\$ca=`cat ${name}/keys/ca.crt`); print \"\n\$ca\n\"} elsif(m|^cert keys/${name}.crt|) { chomp(\$crt=`cat ${name}/keys/${name}.crt`); print \"\n\$crt\n\"} elsif(m|^key keys/${name}.key|){ chomp(\$key=`cat ${name}/keys/${name}.key`); print \"\n\$key\n\"} else { print} ' > ${name}.ovpn", - refreshonly => true, - require => [ File["/etc/openvpn/${server}/download-configs/${name}/${name}.conf"], - File["/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt"], - File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key"], - File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt"], - ], - } - - file { "/etc/openvpn/${server}/download-configs/${name}.ovpn": - mode => '0400', - require => Exec["generate ${name}.ovpn in ${server}"], - } -} diff --git a/puppet/modules/openvpn/manifests/client_specific_config.pp b/puppet/modules/openvpn/manifests/client_specific_config.pp deleted file mode 100644 index 4287421a..00000000 --- a/puppet/modules/openvpn/manifests/client_specific_config.pp +++ /dev/null @@ -1,79 +0,0 @@ -# == Define: openvpn::client_specific_config -# -# This define configures options which will be pushed by the server to a -# specific client only. This feature is explained here: -# http://openvpn.net/index.php/open-source/documentation/howto.html#policy -# -# === Parameters -# -# All the parameters are explained in the openvpn documentation: -# http://openvpn.net/index.php/open-source/documentation/howto.html#policy -# -# [*server*] -# String. Name of the corresponding openvpn endpoint -# Required -# -# [*iroute*] -# Array. Array of iroute combinations. -# Default: [] -# -# [*ifconfig*] -# String. IP configuration to push to the client. -# Default: false -# -# [*dhcp_options] -# Array. DHCP options to push to the client. -# Default: [] -# -# -# === Examples -# -# openvpn::client_specific_config { -# 'vpn_client': -# server => 'contractors', -# iroute => ['10.0.1.0 255.255.255.0'], -# ifconfig => '10.10.10.1 10.10.10.2', -# dhcp_options => ['DNS 8.8.8.8'] -# } -# -# * Removal: -# Manual process right now, todo for the future -# -# -# === Authors -# -# * Raffael Schmid -# -# === License -# -# Copyright 2013 Raffael Schmid, -# -# 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. -# -define openvpn::client_specific_config( - $server, - $iroute = [], - $ifconfig = false, - $dhcp_options = [] -) { - - Openvpn::Server[$server] -> - Openvpn::Client[$name] -> - Openvpn::Client_specific_config[$name] - - file { "/etc/openvpn/${server}/client-configs/${name}": - ensure => present, - content => template('openvpn/client_specific_config.erb') - } - -} diff --git a/puppet/modules/openvpn/manifests/config.pp b/puppet/modules/openvpn/manifests/config.pp deleted file mode 100644 index 32b32094..00000000 --- a/puppet/modules/openvpn/manifests/config.pp +++ /dev/null @@ -1,52 +0,0 @@ -# == Class: openvpn::config -# -# This class sets up the openvpn enviornment as well as the default config file -# -# -# === Examples -# -# This class should not be directly invoked -# -# === Authors -# -# * Raffael Schmid -# * John Kinsella -# * Justin Lambert -# -# === License -# -# Copyright 2013 Raffael Schmid, -# -# 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. -# -class openvpn::config { - - if $::osfamily == 'Debian' { - include concat::setup - - concat { - '/etc/default/openvpn': - owner => root, - group => root, - mode => 644, - warn => true; - } - - concat::fragment { - 'openvpn.default.header': - content => template('openvpn/etc-default-openvpn.erb'), - target => '/etc/default/openvpn', - order => 01; - } - } -} diff --git a/puppet/modules/openvpn/manifests/init.pp b/puppet/modules/openvpn/manifests/init.pp deleted file mode 100644 index 7e07f025..00000000 --- a/puppet/modules/openvpn/manifests/init.pp +++ /dev/null @@ -1,43 +0,0 @@ -# == Class: openvpn -# -# This module installs the openvpn service, configures vpn endpoints, generates -# client certificates, and generates client config files -# -# -# === Examples -# -# * Installation: -# class { 'openvpn': } -# -# -# === Authors -# -# * Raffael Schmid -# * John Kinsella -# * Justin Lambert -# -# === License -# -# Copyright 2013 Raffael Schmid, -# -# 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. -# -class openvpn { - - class {'openvpn::params': } -> - class {'openvpn::install': } -> - class {'openvpn::config': } ~> - class {'openvpn::service': } -> - Class['openvpn'] - -} diff --git a/puppet/modules/openvpn/manifests/install.pp b/puppet/modules/openvpn/manifests/install.pp deleted file mode 100644 index a230373a..00000000 --- a/puppet/modules/openvpn/manifests/install.pp +++ /dev/null @@ -1,46 +0,0 @@ -# == Class: openvpn -# -# This module installs the openvpn service, configures vpn endpoints, generates -# client certificates, and generates client config files -# -# -# === Examples -# -# This class should not be directly invoked -# -# -# === Authors -# -# * Raffael Schmid -# * John Kinsella -# * Justin Lambert -# -# === License -# -# Copyright 2013 Raffael Schmid, -# -# 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. -# -class openvpn::install { - - package { - 'openvpn': - ensure => installed; - } - - file { - [ '/etc/openvpn', '/etc/openvpn/keys' ]: - ensure => directory, - require => Package['openvpn']; - } -} diff --git a/puppet/modules/openvpn/manifests/params.pp b/puppet/modules/openvpn/manifests/params.pp deleted file mode 100644 index 33495270..00000000 --- a/puppet/modules/openvpn/manifests/params.pp +++ /dev/null @@ -1,37 +0,0 @@ -# === License -# -# Copyright 2013 Raffael Schmid, -# -# 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. -# -class openvpn::params { - - $group = $::osfamily ? { - 'RedHat' => 'nobody', - default => 'nogroup' - } - - $easyrsa_source = $::osfamily ? { - 'RedHat' => $::operatingsystemmajrelease ? { - 6 => '/usr/share/openvpn/easy-rsa/2.0', - default => '/usr/share/doc/openvpn-2.2.2/easy-rsa/2.0' - }, - default => '/usr/share/doc/openvpn/examples/easy-rsa/2.0' - } - - $link_openssl_cnf = $::osfamily ? { - /(Debian|RedHat)/ => true, - default => false - } - -} diff --git a/puppet/modules/openvpn/manifests/server.pp b/puppet/modules/openvpn/manifests/server.pp deleted file mode 100644 index 649048c4..00000000 --- a/puppet/modules/openvpn/manifests/server.pp +++ /dev/null @@ -1,233 +0,0 @@ -# == Define: openvpn::server -# -# This define creates the openvpn server instance and ssl certificates -# -# -# === Parameters -# -# [*country*] -# String. Country to be used for the SSL certificate -# -# [*province*] -# String. Province to be used for the SSL certificate -# -# [*city*] -# String. City to be used for the SSL certificate -# -# [*organization*] -# String. Organization to be used for the SSL certificate -# -# [*email*] -# String. Email address to be used for the SSL certificate -# -# [*compression*] -# String. Which compression algorithim to use -# Default: comp-lzo -# Options: comp-lzo or '' (disable compression) -# -# [*dev*] -# String. Device method -# Default: tun -# Options: tun (routed connections), tap (bridged connections) -# -# [*user*] -# String. Group to drop privileges to after startup -# Default: nobody -# -# [*group*] -# String. User to drop privileges to after startup -# Default: depends on your $::osfamily -# -# [*ipp*] -# Boolean. Persist ifconfig information to a file to retain client IP -# addresses between sessions -# Default: false -# -# [*local*] -# String. Interface for openvpn to bind to. -# Default: $::ipaddress_eth0 -# Options: An IP address or '' to bind to all ip addresses -# -# [*logfile*] -# String. Logfile for this openvpn server -# Default: false -# Options: false (syslog) or log file name -# -# [*port*] -# Integer. The port the openvpn server service is running on -# Default: 1194 -# -# [*proto*] -# String. What IP protocol is being used. -# Default: tcp -# Options: tcp or udp -# -# [*status_log*] -# String. Logfile for periodic dumps of the vpn service status -# Default: "${name}/openvpn-status.log" -# -# [*server*] -# String. Network to assign client addresses out of -# Default: None. Required in tun mode, not in tap mode -# -# [*push*] -# Array. Options to push out to the client. This can include routes, DNS -# servers, DNS search domains, and many other options. -# Default: [] -# -# -# === Examples -# -# openvpn::client { -# 'my_user': -# server => 'contractors', -# remote_host => 'vpn.mycompany.com' -# } -# -# * Removal: -# Manual process right now, todo for the future -# -# -# === Authors -# -# * Raffael Schmid -# * John Kinsella -# * Justin Lambert -# -# === License -# -# Copyright 2013 Raffael Schmid, -# -# 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. -# -define openvpn::server( - $country, - $province, - $city, - $organization, - $email, - $compression = 'comp-lzo', - $dev = 'tun0', - $user = 'nobody', - $group = false, - $ipp = false, - $ip_pool = [], - $local = $::ipaddress_eth0, - $logfile = false, - $port = '1194', - $proto = 'tcp', - $status_log = "${name}/openvpn-status.log", - $server = '', - $push = [] -) { - - include openvpn - Class['openvpn::install'] -> - Openvpn::Server[$name] ~> - Class['openvpn::service'] - - $tls_server = $proto ? { - /tcp/ => true, - default => false - } - - $group_to_set = $group ? { - false => $openvpn::params::group, - default => $group - } - - file { - ["/etc/openvpn/${name}", "/etc/openvpn/${name}/client-configs", "/etc/openvpn/${name}/download-configs" ]: - ensure => directory; - } - - exec { - "copy easy-rsa to openvpn config folder ${name}": - command => "/bin/cp -r ${openvpn::params::easyrsa_source} /etc/openvpn/${name}/easy-rsa", - creates => "/etc/openvpn/${name}/easy-rsa", - notify => Exec["fix_easyrsa_file_permissions_${name}"], - require => File["/etc/openvpn/${name}"]; - } - - exec { - "fix_easyrsa_file_permissions_${name}": - refreshonly => true, - command => "/bin/chmod 755 /etc/openvpn/${name}/easy-rsa/*"; - } - - file { - "/etc/openvpn/${name}/easy-rsa/vars": - ensure => present, - content => template('openvpn/vars.erb'), - require => Exec["copy easy-rsa to openvpn config folder ${name}"]; - } - - file { - "/etc/openvpn/${name}/easy-rsa/openssl.cnf": - require => Exec["copy easy-rsa to openvpn config folder ${name}"]; - } - - if $openvpn::params::link_openssl_cnf == true { - File["/etc/openvpn/${name}/easy-rsa/openssl.cnf"] { - ensure => link, - target => "/etc/openvpn/${name}/easy-rsa/openssl-1.0.0.cnf" - } - } - - exec { - "generate dh param ${name}": - command => '. ./vars && ./clean-all && ./build-dh', - cwd => "/etc/openvpn/${name}/easy-rsa", - creates => "/etc/openvpn/${name}/easy-rsa/keys/dh1024.pem", - provider => 'shell', - require => File["/etc/openvpn/${name}/easy-rsa/vars"]; - - "initca ${name}": - command => '. ./vars && ./pkitool --initca', - cwd => "/etc/openvpn/${name}/easy-rsa", - creates => "/etc/openvpn/${name}/easy-rsa/keys/ca.key", - provider => 'shell', - require => [ Exec["generate dh param ${name}"], File["/etc/openvpn/${name}/easy-rsa/openssl.cnf"] ]; - - "generate server cert ${name}": - command => '. ./vars && ./pkitool --server server', - cwd => "/etc/openvpn/${name}/easy-rsa", - creates => "/etc/openvpn/${name}/easy-rsa/keys/server.key", - provider => 'shell', - require => Exec["initca ${name}"]; - } - - file { - "/etc/openvpn/${name}/keys": - ensure => link, - target => "/etc/openvpn/${name}/easy-rsa/keys", - require => Exec["copy easy-rsa to openvpn config folder ${name}"]; - } - - if $::osfamily == 'Debian' { - concat::fragment { - "openvpn.default.autostart.${name}": - content => "AUTOSTART=\"\$AUTOSTART ${name}\"\n", - target => '/etc/default/openvpn', - order => 10; - } - } - - file { - "/etc/openvpn/${name}.conf": - owner => root, - group => root, - mode => '0444', - content => template('openvpn/server.erb'); - } -} diff --git a/puppet/modules/openvpn/manifests/service.pp b/puppet/modules/openvpn/manifests/service.pp deleted file mode 100644 index 54e8db7d..00000000 --- a/puppet/modules/openvpn/manifests/service.pp +++ /dev/null @@ -1,36 +0,0 @@ -# == Class: openvpn::config -# -# This class maintains the openvpn service -# -# -# === Examples -# -# This class should not be directly invoked -# -# === Authors -# -# * Raffael Schmid -# * John Kinsella -# * Justin Lambert -# -# === License -# -# Copyright 2013 Raffael Schmid, -# -# 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 -# -# lied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -class openvpn::service { - service { - 'openvpn': - ensure => running, - enable => true, - hasrestart => true, - hasstatus => true; - } -} diff --git a/puppet/modules/openvpn/spec/classes/openvpn_config_spec.rb b/puppet/modules/openvpn/spec/classes/openvpn_config_spec.rb deleted file mode 100644 index bbb63a77..00000000 --- a/puppet/modules/openvpn/spec/classes/openvpn_config_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spec_helper' - -describe 'openvpn::config', :type => :class do - - it { should create_class('openvpn::config') } - - context "on Debian based machines" do - let (:facts) { { :osfamily => 'Debian', :concat_basedir => '/var/lib/puppet/concat' } } - - it { should contain_class('concat::setup') } - it { should contain_concat('/etc/default/openvpn') } - it { should contain_concat__fragment('openvpn.default.header') } - end - -end diff --git a/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb b/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb deleted file mode 100644 index 45dcc9bf..00000000 --- a/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'spec_helper' - -describe 'openvpn', :type => :class do - - let (:facts) { { :concat_basedir => '/var/lib/puppet/concat' } } - - it { should create_class('openvpn') } - -end diff --git a/puppet/modules/openvpn/spec/classes/openvpn_install_spec.rb b/puppet/modules/openvpn/spec/classes/openvpn_install_spec.rb deleted file mode 100644 index cdb31358..00000000 --- a/puppet/modules/openvpn/spec/classes/openvpn_install_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'spec_helper' - -describe 'openvpn::install', :type => :class do - - it { should create_class('openvpn::install') } - it { should contain_package('openvpn') } - - it { should contain_file('/etc/openvpn').with('ensure' => 'directory') } - it { should contain_file('/etc/openvpn/keys').with('ensure' => 'directory') } - -end diff --git a/puppet/modules/openvpn/spec/classes/openvpn_service_spec.rb b/puppet/modules/openvpn/spec/classes/openvpn_service_spec.rb deleted file mode 100644 index f427e7f1..00000000 --- a/puppet/modules/openvpn/spec/classes/openvpn_service_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'spec_helper' - -describe 'openvpn::service', :type => :class do - - let (:facts) { { :concat_basedir => '/var/lib/puppet/concat' } } - - it { should create_class('openvpn::service') } - it { should contain_service('openvpn').with( - 'ensure' => 'running', - 'enable' => true - ) } - -end diff --git a/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb deleted file mode 100644 index a4b580e8..00000000 --- a/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb +++ /dev/null @@ -1,88 +0,0 @@ -require 'spec_helper' - -describe 'openvpn::client', :type => :define do - let(:title) { 'test_client' } - let(:params) { { 'server' => 'test_server' } } - let(:facts) { { :fqdn => 'somehost', :concat_basedir => '/var/lib/puppet/concat' } } - let(:pre_condition) do - 'openvpn::server { "test_server": - country => "CO", - province => "ST", - city => "Some City", - organization => "example.org", - email => "testemail@example.org" - }' - end - - it { should contain_exec('generate certificate for test_client in context of test_server') } - - [ 'test_client', 'test_client/keys'].each do |directory| - it { should contain_file("/etc/openvpn/test_server/download-configs/#{directory}") } - end - - [ 'test_client.crt', 'test_client.key', 'ca.crt' ].each do |file| - it { should contain_file("/etc/openvpn/test_server/download-configs/test_client/keys/#{file}").with( - 'ensure' => 'link', - 'target' => "/etc/openvpn/test_server/easy-rsa/keys/#{file}" - )} - end - - it { should contain_exec('tar the thing test_server with test_client').with( - 'cwd' => '/etc/openvpn/test_server/download-configs/', - 'command' => '/bin/rm test_client.tar.gz; tar --exclude=\*.conf.d -chzvf test_client.tar.gz test_client' - ) } - - context "setting the minimum parameters" do - let(:params) { { 'server' => 'test_server' } } - let(:facts) { { :fqdn => 'somehost', :concat_basedir => '/var/lib/puppet/concat' } } - - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^client$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^ca\s+keys\/ca\.crt$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^cert\s+keys\/test_client.crt$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^key\s+keys\/test_client\.key$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^dev\s+tun$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^proto\s+tcp$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^remote\s+somehost\s+1194$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^comp-lzo$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^resolv-retry\s+infinite$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^nobind$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^persist-key$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^persist-tun$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^mute-replay-warnings$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^ns\-cert\-type\s+server$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^verb\s+3$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^mute\s+20$/)} - end - - context "setting all of the parameters" do - let(:params) { { - 'server' => 'test_server', - 'compression' => 'comp-something', - 'dev' => 'tap', - 'mute' => 10, - 'mute_replay_warnings' => false, - 'nobind' => false, - 'persist_key' => false, - 'persist_tun' => false, - 'port' => '123', - 'proto' => 'udp', - 'remote_host' => 'somewhere', - 'resolv_retry' => '2m', - 'verb' => '1' - } } - let(:facts) { { :fqdn => 'somehost', :concat_basedir => '/var/lib/puppet/concat' } } - - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^client$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^ca\s+keys\/ca\.crt$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^cert\s+keys\/test_client.crt$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^key\s+keys\/test_client\.key$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^dev\s+tap$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^proto\s+udp$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^remote\s+somewhere\s+123$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^comp-something$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^resolv-retry\s+2m$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^verb\s+1$/)} - it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^mute\s+10$/)} - end - -end diff --git a/puppet/modules/openvpn/spec/defines/openvpn_client_specific_config_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_client_specific_config_spec.rb deleted file mode 100644 index cfdab389..00000000 --- a/puppet/modules/openvpn/spec/defines/openvpn_client_specific_config_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'spec_helper' - -describe 'openvpn::client_specific_config', :type => :define do - let(:title) { 'test_client' } - let(:params) { { 'server' => 'test_server' } } - let(:facts) { { :fqdn => 'somehost', :concat_basedir => '/var/lib/puppet/concat' } } - let(:pre_condition) do - [ - 'openvpn::server { "test_server": - country => "CO", - province => "ST", - city => "Some City", - organization => "example.org", - email => "testemail@example.org" - }', - 'openvpn::client { "test_client": - server => "test_server" - }' - ].join - end - - it { should contain_file('/etc/openvpn/test_server/client-configs/test_client') } - - describe "setting no paramter at all" do - it { should contain_file('/etc/openvpn/test_server/client-configs/test_client').with_content(/\A\n\z/) } - end - - describe "setting all parameters" do - let(:params) do - {:server => 'test_server', - :iroute => ['10.0.1.0 255.255.255.0'], - :ifconfig => '10.10.10.2 255.255.255.0', - :dhcp_options => ['DNS 8.8.8.8']} - end - - it { should contain_file('/etc/openvpn/test_server/client-configs/test_client').with_content(/^iroute 10.0.1.0 255.255.255.0$/) } - it { should contain_file('/etc/openvpn/test_server/client-configs/test_client').with_content(/^ifconfig-push 10.10.10.2 255.255.255.0$/) } - it { should contain_file('/etc/openvpn/test_server/client-configs/test_client').with_content(/^push dhcp-option DNS 8.8.8.8$/) } - end -end diff --git a/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb deleted file mode 100644 index 467be6aa..00000000 --- a/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb +++ /dev/null @@ -1,165 +0,0 @@ -require 'spec_helper' - -describe 'openvpn::server', :type => :define do - - let(:title) { 'test_server' } - - context "creating a server with the minimum parameters" do - let(:params) { { - 'country' => 'CO', - 'province' => 'ST', - 'city' => 'Some City', - 'organization' => 'example.org', - 'email' => 'testemail@example.org' - } } - - let (:facts) { { - :ipaddress_eth0 => '1.2.3.4', - :network_eth0 => '1.2.3.0', - :netmask_eth0 => '255.255.255.0', - :concat_basedir => '/var/lib/puppet/concat', - :osfamily => 'anything_else' - } } - - # Files associated with a server config - it { should contain_file('/etc/openvpn/test_server').with('ensure' => 'directory')} - it { should contain_file('/etc/openvpn/test_server/client-configs').with('ensure' => 'directory')} - it { should contain_file('/etc/openvpn/test_server/download-configs').with('ensure' => 'directory')} - it { should contain_file('/etc/openvpn/test_server/easy-rsa/vars')} - it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf')} - it { should contain_file('/etc/openvpn/test_server/keys').with( - 'ensure' => 'link', - 'target' => '/etc/openvpn/test_server/easy-rsa/keys' - )} - - # Execs to working with certificates - it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with( - 'command' => '/bin/cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa' - )} - it { should contain_exec('generate dh param test_server') } - it { should contain_exec('initca test_server') } - it { should contain_exec('generate server cert test_server') } - - # VPN server config file itself - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^mode\s+server$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^client\-config\-dir\s+\/etc\/openvpn\/test_server\/client\-configs$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^ca\s+\/etc\/openvpn\/test_server\/keys\/ca.crt$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^cert\s+\/etc\/openvpn\/test_server\/keys\/server.crt$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^key\s+\/etc\/openvpn\/test_server\/keys\/server.key$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^dh\s+\/etc\/openvpn\/test_server\/keys\/dh1024.pem$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^proto\s+tcp-server$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^tls-server$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^port\s+1194$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^comp-lzo$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^group\s+nogroup$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^user\s+nobody$/) } - it { should_not contain_file('/etc/openvpn/test_server.conf').with_content(/^log\-append\s+test_server\/openvpn\.log$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^status\s+test_server\/openvpn\-status\.log$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^dev\s+tun0$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^local\s+1\.2\.3\.4$/) } - it { should_not contain_file('/etc/openvpn/test_server.conf').with_content(/^ifconfig-pool-persist/) } - end - - context "creating a server setting all parameters" do - let(:params) { { - 'country' => 'CO', - 'province' => 'ST', - 'city' => 'Some City', - 'organization' => 'example.org', - 'email' => 'testemail@example.org', - 'compression' => 'fake_compression', - 'port' => '123', - 'proto' => 'udp', - 'group' => 'someone', - 'user' => 'someone', - 'logfile' => '/var/log/openvpn/test_server.log', - 'status_log' => '/var/log/openvpn/test_server_status.log', - 'dev' => 'tun1', - 'local' => '2.3.4.5', - 'ipp' => true, - 'server' => '2.3.4.0 255.255.0.0', - 'push' => [ 'dhcp-option DNS 172.31.0.30', 'route 172.31.0.0 255.255.0.0' ] - } } - - let (:facts) { { - :ipaddress_eth0 => '1.2.3.4', - :network_eth0 => '1.2.3.0', - :netmask_eth0 => '255.255.255.0', - :concat_basedir => '/var/lib/puppet/concat' - } } - - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^mode\s+server$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^client\-config\-dir\s+\/etc\/openvpn\/test_server\/client\-configs$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^ca\s+\/etc\/openvpn\/test_server\/keys\/ca.crt$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^cert\s+\/etc\/openvpn\/test_server\/keys\/server.crt$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^key\s+\/etc\/openvpn\/test_server\/keys\/server.key$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^dh\s+\/etc\/openvpn\/test_server\/keys\/dh1024.pem$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^proto\s+udp$/) } - it { should_not contain_file('/etc/openvpn/test_server.conf').with_content(/^proto\s+tls-server$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^port\s+123$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^fake_compression$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^group\s+someone$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^user\s+someone$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^log\-append\s+\/var\/log\/openvpn\/test_server\.log$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^status\s+\/var\/log\/openvpn\/test_server_status\.log$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^dev\s+tun1$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^local\s+2\.3\.4\.5$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^server\s+2\.3\.4\.0\s+255\.255\.0\.0$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^push\s+dhcp-option\s+DNS\s+172\.31\.0\.30$/) } - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^push\s+route\s+172\.31\.0\.0\s+255\.255\.0\.0$/) } - end - - context "when RedHat based machine" do - let(:params) { { - 'country' => 'CO', - 'province' => 'ST', - 'city' => 'Some City', - 'organization' => 'example.org', - 'email' => 'testemail@example.org' - } } - - let(:facts) { { :osfamily => 'RedHat', :concat_basedir => '/var/lib/puppet/concat' } } - - it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf').with( - 'ensure' => 'link', - 'target' => '/etc/openvpn/test_server/easy-rsa/openssl-1.0.0.cnf' - )} - - it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with( - 'command' => '/bin/cp -r /usr/share/doc/openvpn-2.2.2/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa' - )} - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^group\s+nobody$/) } - - end - - context "when Debian based machine" do - let(:params) { { - 'country' => 'CO', - 'province' => 'ST', - 'city' => 'Some City', - 'organization' => 'example.org', - 'email' => 'testemail@example.org' - } } - - let(:facts) { { :osfamily => 'Debian', :concat_basedir => '/var/lib/puppet/concat' } } - - it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf').with( - 'ensure' => 'link', - 'target' => '/etc/openvpn/test_server/easy-rsa/openssl-1.0.0.cnf' - )} - - it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with( - 'command' => '/bin/cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa' - )} - - # Configure to start vpn session - it { should contain_concat__fragment('openvpn.default.autostart.test_server').with( - 'content' => "AUTOSTART=\"$AUTOSTART test_server\"\n", - 'target' => '/etc/default/openvpn' - )} - - it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^group\s+nogroup$/) } - - end - -end diff --git a/puppet/modules/openvpn/spec/spec_helper.rb b/puppet/modules/openvpn/spec/spec_helper.rb deleted file mode 100644 index dc7e9f4a..00000000 --- a/puppet/modules/openvpn/spec/spec_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'rubygems' -require 'puppetlabs_spec_helper/module_spec_helper' diff --git a/puppet/modules/openvpn/templates/client.erb b/puppet/modules/openvpn/templates/client.erb deleted file mode 100644 index 021ed617..00000000 --- a/puppet/modules/openvpn/templates/client.erb +++ /dev/null @@ -1,26 +0,0 @@ -client -ca keys/ca.crt -cert keys/<%= scope.lookupvar('name') %>.crt -key keys/<%= scope.lookupvar('name') %>.key -dev <%= scope.lookupvar('dev') %> -proto <%= scope.lookupvar('proto') %> -remote <%= scope.lookupvar('remote_host') %> <%= scope.lookupvar('port') %> -<% if scope.lookupvar('compression') != '' -%> -<%= scope.lookupvar('compression') %> -<% end -%> -resolv-retry <%= scope.lookupvar('resolv_retry') %> -<% if scope.lookupvar('nobind') -%> -nobind -<% end -%> -<% if scope.lookupvar('persist_key') -%> -persist-key -<% end -%> -<% if scope.lookupvar('persist_tun') -%> -persist-tun -<% end -%> -<% if scope.lookupvar('mute_replay_warnings') -%> -mute-replay-warnings -<% end -%> -ns-cert-type server -verb <%= scope.lookupvar('verb') %> -mute <%= scope.lookupvar('mute') %> diff --git a/puppet/modules/openvpn/templates/client_specific_config.erb b/puppet/modules/openvpn/templates/client_specific_config.erb deleted file mode 100644 index 62cc0e7a..00000000 --- a/puppet/modules/openvpn/templates/client_specific_config.erb +++ /dev/null @@ -1,10 +0,0 @@ -<% scope.lookupvar('iroute').each do |route| -%> -iroute <%= route %> -<% end -%> -<% if ifconfig = scope.lookupvar('ifconfig') -%> -ifconfig-push <%= ifconfig %> -<% end -%> -<% scope.lookupvar('dhcp_options').each do |option| -%> -push dhcp-option <%= option %> -<% end -%> - diff --git a/puppet/modules/openvpn/templates/etc-default-openvpn.erb b/puppet/modules/openvpn/templates/etc-default-openvpn.erb deleted file mode 100644 index 310e462e..00000000 --- a/puppet/modules/openvpn/templates/etc-default-openvpn.erb +++ /dev/null @@ -1,20 +0,0 @@ -# This is the configuration file for /etc/init.d/openvpn - -# -# Start only these VPNs automatically via init script. -# Allowed values are "all", "none" or space separated list of -# names of the VPNs. If empty, "all" is assumed. -# -#AUTOSTART="all" -#AUTOSTART="none" -#AUTOSTART="home office" -# -# Refresh interval (in seconds) of default status files -# located in /var/run/openvpn.$NAME.status -# Defaults to 10, 0 disables status file generation -# -#STATUSREFRESH=10 -#STATUSREFRESH=0 -# Optional arguments to openvpn's command line -OPTARGS="" -AUTOSTART="" diff --git a/puppet/modules/openvpn/templates/server.erb b/puppet/modules/openvpn/templates/server.erb deleted file mode 100644 index 6ef13263..00000000 --- a/puppet/modules/openvpn/templates/server.erb +++ /dev/null @@ -1,37 +0,0 @@ -mode server -client-config-dir /etc/openvpn/<%= scope.lookupvar('name') %>/client-configs -ca /etc/openvpn/<%= scope.lookupvar('name') %>/keys/ca.crt -cert /etc/openvpn/<%= scope.lookupvar('name') %>/keys/server.crt -key /etc/openvpn/<%= scope.lookupvar('name') %>/keys/server.key -dh /etc/openvpn/<%= scope.lookupvar('name') %>/keys/dh1024.pem -<% if scope.lookupvar('proto') == 'tcp' -%> -proto <%= scope.lookupvar('proto') %>-server -<% else -%> -proto <%= scope.lookupvar('proto') %> -<% end -%> -port <%= scope.lookupvar('port') %> -<% if scope.lookupvar('tls_server') -%> -tls-server -<% end -%> -<% if scope.lookupvar('compression') != '' -%> -<%= scope.lookupvar('compression') %> -<% end -%> -group <%= scope.lookupvar('group_to_set') %> -user <%= scope.lookupvar('user') %> -<% if scope.lookupvar('logfile') -%> -log-append <%= scope.lookupvar('logfile') %> -<% end -%> -status <%= scope.lookupvar('status_log') %> -dev <%= scope.lookupvar('dev') %> -<% if scope.lookupvar('local') != '' -%> -local <%= scope.lookupvar('local') %> -<% end -%> -<% if scope.lookupvar('ipp') -%> -ifconfig-pool-persist <%= scope.lookupvar('name') %>/vpn-ipp.txt -<% end -%> -<% if scope.lookupvar('server') != '' -%> -server <%= scope.lookupvar('server') %> -<% end -%> -<% scope.lookupvar('push').each do |item| -%> -push <%= item %> -<% end -%> diff --git a/puppet/modules/openvpn/templates/vars.erb b/puppet/modules/openvpn/templates/vars.erb deleted file mode 100644 index 20448b8b..00000000 --- a/puppet/modules/openvpn/templates/vars.erb +++ /dev/null @@ -1,68 +0,0 @@ -# easy-rsa parameter settings - -# NOTE: If you installed from an RPM, -# don't edit this file in place in -# /usr/share/openvpn/easy-rsa -- -# instead, you should copy the whole -# easy-rsa directory to another location -# (such as /etc/openvpn) so that your -# edits will not be wiped out by a future -# OpenVPN package upgrade. - -# This variable should point to -# the top level of the easy-rsa -# tree. -export EASY_RSA="/etc/openvpn/<%= @name %>/easy-rsa" - -# -# This variable should point to -# the requested executables -# -export OPENSSL="openssl" -export PKCS11TOOL="pkcs11-tool" -export GREP="grep" - - -# This variable should point to -# the openssl.cnf file included -# with easy-rsa. -export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA` - -# Edit this variable to point to -# your soon-to-be-created key -# directory. -# -# WARNING: clean-all will do -# a rm -rf on this directory -# so make sure you define -# it correctly! -export KEY_DIR="$EASY_RSA/keys" - -# Issue rm -rf warning -echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR - -# PKCS11 fixes -export PKCS11_MODULE_PATH="dummy" -export PKCS11_PIN="dummy" - -# Increase this to 2048 if you -# are paranoid. This will slow -# down TLS negotiation performance -# as well as the one-time DH parms -# generation process. -export KEY_SIZE=1024 - -# In how many days should the root CA key expire? -export CA_EXPIRE=3650 - -# In how many days should certificates expire? -export KEY_EXPIRE=3650 - -# These are the default values for fields -# which will be placed in the certificate. -# Don't leave any of these fields blank. -export KEY_COUNTRY="<%= @country %>" -export KEY_PROVINCE="<%= @province %>" -export KEY_CITY="<%= @city %>" -export KEY_ORG="<%= @organization %>" -export KEY_EMAIL="<%= @email %>" diff --git a/puppet/modules/openvpn/vagrant/client.pp b/puppet/modules/openvpn/vagrant/client.pp deleted file mode 100644 index 7ebeb1d7..00000000 --- a/puppet/modules/openvpn/vagrant/client.pp +++ /dev/null @@ -1,5 +0,0 @@ -node default { - - package { 'openvpn': ensure => installed; } - -} diff --git a/puppet/modules/openvpn/vagrant/server.pp b/puppet/modules/openvpn/vagrant/server.pp deleted file mode 100644 index a95def06..00000000 --- a/puppet/modules/openvpn/vagrant/server.pp +++ /dev/null @@ -1,23 +0,0 @@ -node default { - openvpn::server { 'winterthur': - country => 'CH', - province => 'ZH', - city => 'Winterthur', - organization => 'example.org', - email => 'root@example.org', - server => '10.200.200.0 255.255.255.0' - } - - openvpn::client { 'client1': - server => 'winterthur'; - } - - openvpn::client_specific_config { 'client1': - server => 'winterthur', - ifconfig => '10.200.200.100 255.255.255.0' - } - - openvpn::client { 'client2': - server => 'winterthur'; - } -} -- cgit v1.2.3 From 2df23a682b9a1a99502c79d7112dcefeecf63619 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 21 Jul 2016 12:13:33 -0700 Subject: git subrepo clone https://leap.se/git/puppet_openvpn puppet/modules/openvpn subrepo: subdir: "puppet/modules/openvpn" merged: "ba7ec7a" upstream: origin: "https://leap.se/git/puppet_openvpn" branch: "master" commit: "ba7ec7a" git-subrepo: version: "0.3.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "cb2995b" --- puppet/modules/openvpn/.fixtures.yml | 6 + puppet/modules/openvpn/.gitignore | 2 + puppet/modules/openvpn/.gitrepo | 11 ++ puppet/modules/openvpn/Modulefile | 11 ++ puppet/modules/openvpn/Rakefile | 2 + puppet/modules/openvpn/Readme.markdown | 123 +++++++++++++++++ puppet/modules/openvpn/manifests/client.pp | 142 +++++++++++++++++++ puppet/modules/openvpn/manifests/init.pp | 45 ++++++ puppet/modules/openvpn/manifests/option.pp | 24 ++++ puppet/modules/openvpn/manifests/server.pp | 153 +++++++++++++++++++++ .../openvpn/spec/classes/openvpn_init_spec.rb | 20 +++ .../openvpn/spec/defines/openvpn_client_spec.rb | 116 ++++++++++++++++ .../openvpn/spec/defines/openvpn_option_spec.rb | 42 ++++++ .../openvpn/spec/defines/openvpn_server_spec.rb | 109 +++++++++++++++ puppet/modules/openvpn/spec/spec_helper.rb | 2 + .../openvpn/templates/etc-default-openvpn.erb | 20 +++ puppet/modules/openvpn/templates/vars.erb | 69 ++++++++++ 17 files changed, 897 insertions(+) create mode 100644 puppet/modules/openvpn/.fixtures.yml create mode 100644 puppet/modules/openvpn/.gitignore create mode 100644 puppet/modules/openvpn/.gitrepo create mode 100644 puppet/modules/openvpn/Modulefile create mode 100644 puppet/modules/openvpn/Rakefile create mode 100644 puppet/modules/openvpn/Readme.markdown create mode 100644 puppet/modules/openvpn/manifests/client.pp create mode 100644 puppet/modules/openvpn/manifests/init.pp create mode 100644 puppet/modules/openvpn/manifests/option.pp create mode 100644 puppet/modules/openvpn/manifests/server.pp create mode 100644 puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb create mode 100644 puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb create mode 100644 puppet/modules/openvpn/spec/defines/openvpn_option_spec.rb create mode 100644 puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb create mode 100644 puppet/modules/openvpn/spec/spec_helper.rb create mode 100644 puppet/modules/openvpn/templates/etc-default-openvpn.erb create mode 100644 puppet/modules/openvpn/templates/vars.erb (limited to 'puppet/modules') diff --git a/puppet/modules/openvpn/.fixtures.yml b/puppet/modules/openvpn/.fixtures.yml new file mode 100644 index 00000000..1125ecca --- /dev/null +++ b/puppet/modules/openvpn/.fixtures.yml @@ -0,0 +1,6 @@ +fixtures: + repositories: + concat: git://github.com/ripienaar/puppet-concat.git + symlinks: + openvpn: "#{source_dir}" + diff --git a/puppet/modules/openvpn/.gitignore b/puppet/modules/openvpn/.gitignore new file mode 100644 index 00000000..12c29e7d --- /dev/null +++ b/puppet/modules/openvpn/.gitignore @@ -0,0 +1,2 @@ +pkg +spec/fixtures diff --git a/puppet/modules/openvpn/.gitrepo b/puppet/modules/openvpn/.gitrepo new file mode 100644 index 00000000..54c861da --- /dev/null +++ b/puppet/modules/openvpn/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_openvpn + branch = master + commit = ba7ec7abd25cd4c5031e11cd3ae17872ef31b24b + parent = d6719731dce8ee7e048a16a447a426abcaa44f24 + cmdver = 0.3.0 diff --git a/puppet/modules/openvpn/Modulefile b/puppet/modules/openvpn/Modulefile new file mode 100644 index 00000000..55b6eba0 --- /dev/null +++ b/puppet/modules/openvpn/Modulefile @@ -0,0 +1,11 @@ +name 'luxflux-openvpn' +version '1.0.2' +source 'https://github.com/luxflux/puppet-openvpn' +author 'luxflux' +license 'UNKNOWN' +summary 'UNKNOWN' +description 'UNKNOWN' +project_page 'UNKNOWN' + +## Add dependencies, if any: +dependency 'ripienaar/concat' diff --git a/puppet/modules/openvpn/Rakefile b/puppet/modules/openvpn/Rakefile new file mode 100644 index 00000000..14f1c246 --- /dev/null +++ b/puppet/modules/openvpn/Rakefile @@ -0,0 +1,2 @@ +require 'rubygems' +require 'puppetlabs_spec_helper/rake_tasks' diff --git a/puppet/modules/openvpn/Readme.markdown b/puppet/modules/openvpn/Readme.markdown new file mode 100644 index 00000000..d2a1f67b --- /dev/null +++ b/puppet/modules/openvpn/Readme.markdown @@ -0,0 +1,123 @@ +# OpenVPN Puppet module + +OpenVPN module for puppet including client config/cert creation (tarball to download) + +## Dependencies + - [puppet-concat](https://github.com/ripienaar/puppet-concat) + +## Supported OS + - Debian Squeeze (should, as it works on Ubuntu Lucid) + - Ubuntu 10.4, 12.04 (other untested) + - CentOS + +## Example + + # add a server instance + openvpn::server { + "server1": + country => "CH", + province => "ZH", + city => "Winterthur", + organization => "example.org", + email => "root@example.org"; + } + + # configure server + openvpn::option { + "dev server1": + key => "dev", + value => "tun0", + server => "server1"; + "script-security server1": + key => "script-security", + value => "3", + server => "server1"; + "daemon server1": + key => "daemon", + server => "server1"; + "keepalive server1": + key => "keepalive", + value => "10 60", + server => "server1"; + "ping-timer-rem server1": + key => "ping-timer-rem", + server => "server1"; + "persist-tun server1": + key => "persist-tun", + server => "server1"; + "persist-key server1": + key => "persist-key", + server => "server1"; + "proto server1": + key => "proto", + value => "tcp-server", + server => "server1"; + "cipher server1": + key => "cipher", + value => "BF-CBC", + server => "server1"; + "local server1": + key => "local", + value => $ipaddress, + server => "server1"; + "tls-server server1": + key => "tls-server", + server => "server1"; + "server server1": + key => "server", + value => "10.10.10.0 255.255.255.0", + server => "server1"; + "lport server1": + key => "lport", + value => "1194", + server => "server1"; + "management server1": + key => "management", + value => "/var/run/openvpn-server1.sock unix", + server => "server1"; + "comp-lzo server1": + key => "comp-lzo", + server => "server1"; + "topology server1": + key => "topology", + value => "subnet", + server => "server1"; + "client-to-client server1": + key => "client-to-client", + server => "server1"; + } + + + # define clients + openvpn::client { + [ "client1.example.org", "client2.example.org" ]: + server => "server1"; + } + + # add options to the client-config-dir file + openvpn::option { + "iroute server1 client1.example.org home network": + key => "iroute", + value => "192.168.0.0 255.255.255.0", + client => "client1.example.org", + server => "server1", + csc => true; + } + + # add an option to the client config + openvpn::option { + "ifconfig server1 client2.example.org": + key => "ifconfig-push", + value => "10.10.10.2 255.255.255.0", + client => "client2.example.org", + server => "server1"; + } + +Don't forget the [sysctl](https://github.com/luxflux/puppet-sysctl) directive ```net.ipv4.ip_forward```! + + +# Contributors + +These fine folks helped to get this far with this module: +* [@jlk](https://github.com/jlk) +* [@jlambert121](https://github.com/jlambert121) diff --git a/puppet/modules/openvpn/manifests/client.pp b/puppet/modules/openvpn/manifests/client.pp new file mode 100644 index 00000000..ed11b3a9 --- /dev/null +++ b/puppet/modules/openvpn/manifests/client.pp @@ -0,0 +1,142 @@ +# client.pp + +define openvpn::client($server, $remote_host = $::fqdn) { + exec { + "generate certificate for ${name} in context of ${server}": + command => ". ./vars && ./pkitool ${name}", + cwd => "/etc/openvpn/${server}/easy-rsa", + creates => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt", + provider => 'shell', + require => Exec["generate server cert ${server}"]; + } + + file { + "/etc/openvpn/${server}/download-configs/${name}": + ensure => directory, + require => File["/etc/openvpn/${server}/download-configs"]; + + "/etc/openvpn/${server}/download-configs/${name}/keys": + ensure => directory, + require => File["/etc/openvpn/${server}/download-configs/${name}"]; + + "/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt": + ensure => link, + target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt", + require => [ Exec["generate certificate for ${name} in context of ${server}"], + File["/etc/openvpn/${server}/download-configs/${name}/keys"] ]; + + "/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key": + ensure => link, + target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.key", + require => [ Exec["generate certificate for ${name} in context of ${server}"], + File["/etc/openvpn/${server}/download-configs/${name}/keys"] ]; + + "/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt": + ensure => link, + target => "/etc/openvpn/${server}/easy-rsa/keys/ca.crt", + require => [ Exec["generate certificate for ${name} in context of ${server}"], + File["/etc/openvpn/${server}/download-configs/${name}/keys"] ]; + } + + + openvpn::option { + "ca ${server} with ${name}": + key => 'ca', + value => 'keys/ca.crt', + client => $name, + server => $server; + "cert ${server} with ${name}": + key => 'cert', + value => "keys/${name}.crt", + client => $name, + server => $server; + "key ${server} with ${name}": + key => 'key', + value => "keys/${name}.key", + client => $name, + server => $server; + "client ${server} with ${name}": + key => 'client', + client => $name, + server => $server; + "dev ${server} with ${name}": + key => 'dev', + value => 'tun', + client => $name, + server => $server; + "proto ${server} with ${name}": + key => 'proto', + value => 'tcp', + client => $name, + server => $server; + "remote ${server} with ${name}": + key => 'remote', + value => "${remote_host} 1194", + client => $name, + server => $server; + "resolv-retry ${server} with ${name}": + key => 'resolv-retry', + value => 'infinite', + client => $name, + server => $server; + "nobind ${server} with ${name}": + key => 'nobind', + client => $name, + server => $server; + "persist-key ${server} with ${name}": + key => 'persist-key', + client => $name, + server => $server; + "persist-tun ${server} with ${name}": + key => 'persist-tun', + client => $name, + server => $server; + "mute-replay-warnings ${server} with ${name}": + key => 'mute-replay-warnings', + client => $name, + server => $server; + "ns-cert-type ${server} with ${name}": + key => 'ns-cert-type', + value => 'server', + client => $name, + server => $server; + "comp-lzo ${server} with ${name}": + key => 'comp-lzo', + client => $name, + server => $server; + "verb ${server} with ${name}": + key => 'verb', + value => '3', + client => $name, + server => $server; + "mute ${server} with ${name}": + key => 'mute', + value => '20', + client => $name, + server => $server; + } + + exec { + "tar the thing ${server} with ${name}": + cwd => "/etc/openvpn/${server}/download-configs/", + command => "/bin/rm ${name}.tar.gz; tar --exclude=\\*.conf.d -chzvf ${name}.tar.gz ${name}", + refreshonly => true, + require => [ File["/etc/openvpn/${server}/download-configs/${name}/${name}.conf"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt"] ]; + } + + + concat { + [ "/etc/openvpn/${server}/client-configs/${name}", "/etc/openvpn/${server}/download-configs/${name}/${name}.conf" ]: + owner => root, + group => root, + mode => 644, + warn => true, + force => true, + notify => Exec["tar the thing ${server} with ${name}"], + require => [ File['/etc/openvpn'], File["/etc/openvpn/${server}/download-configs/${name}"] ]; + } + +} diff --git a/puppet/modules/openvpn/manifests/init.pp b/puppet/modules/openvpn/manifests/init.pp new file mode 100644 index 00000000..a3dd70c0 --- /dev/null +++ b/puppet/modules/openvpn/manifests/init.pp @@ -0,0 +1,45 @@ +# openvpn.pp + +class openvpn { + package { + 'openvpn': + ensure => installed; + } + service { + 'openvpn': + ensure => running, + enable => true, + hasrestart => true, + hasstatus => true, + require => Exec['concat_/etc/default/openvpn']; + } + file { + '/etc/openvpn': + ensure => directory, + require => Package['openvpn']; + } + file { + '/etc/openvpn/keys': + ensure => directory, + require => File['/etc/openvpn']; + } + + include concat::setup + + concat { + '/etc/default/openvpn': + owner => root, + group => root, + mode => 644, + warn => true, + notify => Service['openvpn']; + } + + concat::fragment { + 'openvpn.default.header': + content => template('openvpn/etc-default-openvpn.erb'), + target => '/etc/default/openvpn', + order => 01; + } + +} diff --git a/puppet/modules/openvpn/manifests/option.pp b/puppet/modules/openvpn/manifests/option.pp new file mode 100644 index 00000000..eb3d5a72 --- /dev/null +++ b/puppet/modules/openvpn/manifests/option.pp @@ -0,0 +1,24 @@ +# option.pp + +define openvpn::option($key, $server, $value = '', $client = '', $csc = false) { + $content = $value ? { + '' => $key, + default => "${key} ${value}" + } + + if $client == '' { + $path = "/etc/openvpn/${server}.conf" + } else { + if $csc { + $path = "/etc/openvpn/${server}/client-configs/${client}" + } else { + $path = "/etc/openvpn/${server}/download-configs/${client}/${client}.conf" + } + } + + concat::fragment { + "openvpn.${server}.${client}.${name}": + target => $path, + content => "${content}\n"; + } +} diff --git a/puppet/modules/openvpn/manifests/server.pp b/puppet/modules/openvpn/manifests/server.pp new file mode 100644 index 00000000..bfcaad83 --- /dev/null +++ b/puppet/modules/openvpn/manifests/server.pp @@ -0,0 +1,153 @@ +# server.pp + +define openvpn::server($country, $province, $city, $organization, $email) { + include openvpn + + $easyrsa_source = $::osfamily ? { + 'RedHat' => '/usr/share/doc/openvpn-2.2.2/easy-rsa/2.0', + default => '/usr/share/doc/openvpn/examples/easy-rsa/2.0' + } + + $link_openssl_cnf = $::osfamily ? { + /(Debian|RedHat)/ => true, + default => false + } + + file { + "/etc/openvpn/${name}": + ensure => directory, + require => Package['openvpn']; + } + file { + "/etc/openvpn/${name}/client-configs": + ensure => directory, + require => File["/etc/openvpn/${name}"]; + "/etc/openvpn/${name}/download-configs": + ensure => directory, + require => File["/etc/openvpn/${name}"]; + } + + openvpn::option { + "client-config-dir ${name}": + key => 'client-config-dir', + value => "/etc/openvpn/${name}/client-configs", + server => $name, + require => File["/etc/openvpn/${name}"]; + "mode ${name}": + key => 'mode', + value => 'server', + server => $name; + } + + exec { + "copy easy-rsa to openvpn config folder ${name}": + command => "/bin/cp -r ${easyrsa_source} /etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa", + notify => Exec['fix_easyrsa_file_permissions'], + require => File["/etc/openvpn/${name}"]; + } + exec { + 'fix_easyrsa_file_permissions': + refreshonly => true, + command => "/bin/chmod 755 /etc/openvpn/${name}/easy-rsa/*"; + } + file { + "/etc/openvpn/${name}/easy-rsa/vars": + ensure => present, + content => template('openvpn/vars.erb'), + require => Exec["copy easy-rsa to openvpn config folder ${name}"]; + } + + file { + "/etc/openvpn/${name}/easy-rsa/openssl.cnf": + require => Exec["copy easy-rsa to openvpn config folder ${name}"]; + } + if $link_openssl_cnf == true { + File["/etc/openvpn/${name}/easy-rsa/openssl.cnf"] { + ensure => link, + target => "/etc/openvpn/${name}/easy-rsa/openssl-1.0.0.cnf" + } + } + + exec { + "generate dh param ${name}": + command => '. ./vars && ./clean-all && ./build-dh', + cwd => "/etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa/keys/dh1024.pem", + provider => 'shell', + require => File["/etc/openvpn/${name}/easy-rsa/vars"]; + + "initca ${name}": + command => '. ./vars && ./pkitool --initca', + cwd => "/etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa/keys/ca.key", + provider => 'shell', + require => [ Exec["generate dh param ${name}"], File["/etc/openvpn/${name}/easy-rsa/openssl.cnf"] ]; + + "generate server cert ${name}": + command => '. ./vars && ./pkitool --server server', + cwd => "/etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa/keys/server.key", + provider => 'shell', + require => Exec["initca ${name}"]; + } + + file { + "/etc/openvpn/${name}/keys": + ensure => link, + target => "/etc/openvpn/${name}/easy-rsa/keys", + require => Exec["copy easy-rsa to openvpn config folder ${name}"]; + } + + openvpn::option { + "ca ${name}": + key => 'ca', + value => "/etc/openvpn/${name}/keys/ca.crt", + require => Exec["initca ${name}"], + server => $name; + "cert ${name}": + key => 'cert', + value => "/etc/openvpn/${name}/keys/server.crt", + require => Exec["generate server cert ${name}"], + server => $name; + "key ${name}": + key => 'key', + value => "/etc/openvpn/${name}/keys/server.key", + require => Exec["generate server cert ${name}"], + server => $name; + "dh ${name}": + key => 'dh', + value => "/etc/openvpn/${name}/keys/dh1024.pem", + require => Exec["generate dh param ${name}"], + server => $name; + + "proto ${name}": + key => 'proto', + value => 'tcp', + require => Exec["generate dh param ${name}"], + server => $name; + + "comp-lzo ${name}": + key => 'comp-lzo', + require => Exec["generate dh param ${name}"], + server => $name; + } + + concat::fragment { + "openvpn.default.autostart.${name}": + content => "AUTOSTART=\"\$AUTOSTART ${name}\"\n", + target => '/etc/default/openvpn', + order => 10; + } + + concat { + "/etc/openvpn/${name}.conf": + owner => root, + group => root, + mode => 644, + warn => true, + require => File['/etc/openvpn'], + notify => Service['openvpn']; + } + +} diff --git a/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb b/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb new file mode 100644 index 00000000..cdfdea19 --- /dev/null +++ b/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe 'openvpn', :type => :class do + + let (:facts) { { :concat_basedir => '/var/lib/puppet/concat' } } + + it { should create_class('openvpn') } + it { should contain_class('concat::setup') } + it { should contain_package('openvpn') } + it { should contain_service('openvpn').with( + 'ensure' => 'running', + 'enable' => true + ) } + + it { should contain_file('/etc/openvpn').with('ensure' => 'directory') } + it { should contain_file('/etc/openvpn/keys').with('ensure' => 'directory') } + + it { should contain_concat__fragment('openvpn.default.header') } + +end diff --git a/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb new file mode 100644 index 00000000..da71d63d --- /dev/null +++ b/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb @@ -0,0 +1,116 @@ +require 'spec_helper' + +describe 'openvpn::client', :type => :define do + let(:title) { 'test_client' } + let(:params) { { 'server' => 'test_server' } } + let(:facts) { { :fqdn => 'somehost', :concat_basedir => '/var/lib/puppet/concat' } } + + it { should contain_exec('generate certificate for test_client in context of test_server') } + + [ 'test_client', 'test_client/keys'].each do |directory| + it { should contain_file("/etc/openvpn/test_server/download-configs/#{directory}") } + end + + [ 'test_client.crt', 'test_client.key', 'ca.crt' ].each do |file| + it { should contain_file("/etc/openvpn/test_server/download-configs/test_client/keys/#{file}").with( + 'ensure' => 'link', + 'target' => "/etc/openvpn/test_server/easy-rsa/keys/#{file}" + )} + end + + it { should contain_exec('tar the thing test_server with test_client').with( + 'cwd' => '/etc/openvpn/test_server/download-configs/', + 'command' => '/bin/rm test_client.tar.gz; tar --exclude=\*.conf.d -chzvf test_client.tar.gz test_client' + ) } + + it { should contain_openvpn__option('ca test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'ca', + 'value' => 'keys/ca.crt' + )} + it { should contain_openvpn__option('cert test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'cert', + 'value' => 'keys/test_client.crt' + )} + it { should contain_openvpn__option('key test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'key', + 'value' => 'keys/test_client.key' + )} + it { should contain_openvpn__option('client test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'client' + )} + it { should contain_openvpn__option('dev test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'dev', + 'value' => 'tun' + )} + it { should contain_openvpn__option('proto test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'proto', + 'value' => 'tcp' + )} + it { should contain_openvpn__option('remote test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'remote', + 'value' => 'somehost 1194' + )} + it { should contain_openvpn__option('resolv-retry test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'resolv-retry', + 'value' => 'infinite' + )} + it { should contain_openvpn__option('nobind test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'nobind' + )} + it { should contain_openvpn__option('persist-key test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'persist-key' + )} + it { should contain_openvpn__option('persist-tun test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'persist-tun' + )} + it { should contain_openvpn__option('mute-replay-warnings test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'mute-replay-warnings' + )} + it { should contain_openvpn__option('ns-cert-type test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'ns-cert-type', + 'value' => 'server' + )} + it { should contain_openvpn__option('comp-lzo test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'comp-lzo' + )} + it { should contain_openvpn__option('verb test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'verb', + 'value' => '3' + )} + it { should contain_openvpn__option('mute test_server with test_client').with( + 'server' => 'test_server', + 'client' => 'test_client', + 'key' => 'mute', + 'value' => '20' + )} +end diff --git a/puppet/modules/openvpn/spec/defines/openvpn_option_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_option_spec.rb new file mode 100644 index 00000000..a2d1661d --- /dev/null +++ b/puppet/modules/openvpn/spec/defines/openvpn_option_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe 'openvpn::option', :type => :define do + + let(:title) { 'test_param' } + + context "when key => 'test_key', server => 'test_server'" do + let(:params) { { 'key' => 'test_key', 'server' => 'test_server' } } + + it { should contain_concat__fragment('openvpn.test_server..test_param').with( + 'target' => '/etc/openvpn/test_server.conf', + 'content' => "test_key\n" + ) } + end + + context "when key => 'test_key', value => 'test_value', server => 'test_server'" do + let(:params) { { 'key' => 'test_key', 'value' => 'test_value', 'server' => 'test_server' } } + + it { should contain_concat__fragment('openvpn.test_server..test_param').with( + 'target' => '/etc/openvpn/test_server.conf', + 'content' => "test_key test_value\n" + ) } + end + + context "when key => 'test_key', server => 'test_server', client => 'test_client'" do + let(:params) { { 'key' => 'test_key', 'server' => 'test_server', 'client' => 'test_client' } } + + it { should contain_concat__fragment('openvpn.test_server.test_client.test_param').with( + 'target' => '/etc/openvpn/test_server/download-configs/test_client/test_client.conf', + 'content' => "test_key\n" + ) } + end + + context "when key => 'test_key', server => 'test_server', client => 'test_client', csc => true" do + let(:params) { { 'key' => 'test_key', 'server' => 'test_server', 'client' => 'test_client', 'csc' => 'true' } } + + it { should contain_concat__fragment('openvpn.test_server.test_client.test_param').with( + 'target' => '/etc/openvpn/test_server/client-configs/test_client', + 'content' => "test_key\n" + ) } + end +end diff --git a/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb new file mode 100644 index 00000000..1032302e --- /dev/null +++ b/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb @@ -0,0 +1,109 @@ +require 'spec_helper' + +describe 'openvpn::server', :type => :define do + + let(:title) { 'test_server' } + let(:params) { { + 'country' => 'CO', + 'province' => 'ST', + 'city' => 'Some City', + 'organization' => 'example.org', + 'email' => 'testemail@example.org' + } } + + let (:facts) { { :concat_basedir => '/var/lib/puppet/concat' } } + + # Files associated with a server config + it { should contain_file('/etc/openvpn/test_server').with('ensure' => 'directory')} + it { should contain_file('/etc/openvpn/test_server/client-configs').with('ensure' => 'directory')} + it { should contain_file('/etc/openvpn/test_server/download-configs').with('ensure' => 'directory')} + it { should contain_file('/etc/openvpn/test_server/easy-rsa/vars')} + it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf')} + it { should contain_file('/etc/openvpn/test_server/keys').with( + 'ensure' => 'link', + 'target' => '/etc/openvpn/test_server/easy-rsa/keys' + )} + + it { should contain_concat__fragment('openvpn.default.autostart.test_server').with( + 'content' => "AUTOSTART=\"$AUTOSTART test_server\"\n", + 'target' => '/etc/default/openvpn' + )} + + # Execs to working with certificates + it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with( + 'command' => '/bin/cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa' + )} + it { should contain_exec('generate dh param test_server') } + it { should contain_exec('initca test_server') } + it { should contain_exec('generate server cert test_server') } + + # Options that should be set + it { should contain_openvpn__option('client-config-dir test_server').with( + 'server' => 'test_server', + 'key' => 'client-config-dir', + 'value' => '/etc/openvpn/test_server/client-configs' + )} + it { should contain_openvpn__option('mode test_server').with( + 'server' => 'test_server', + 'key' => 'mode', + 'value' => 'server' + )} + it { should contain_openvpn__option('ca test_server').with( + 'server' => 'test_server', + 'key' => 'ca', + 'value' => '/etc/openvpn/test_server/keys/ca.crt' + )} + it { should contain_openvpn__option('cert test_server').with( + 'server' => 'test_server', + 'key' => 'cert', + 'value' => '/etc/openvpn/test_server/keys/server.crt' + )} + it { should contain_openvpn__option('key test_server').with( + 'server' => 'test_server', + 'key' => 'key', + 'value' => '/etc/openvpn/test_server/keys/server.key' + )} + it { should contain_openvpn__option('dh test_server').with( + 'server' => 'test_server', + 'key' => 'dh', + 'value' => '/etc/openvpn/test_server/keys/dh1024.pem' + )} + it { should contain_openvpn__option('proto test_server').with( + 'server' => 'test_server', + 'key' => 'proto', + 'value' => 'tcp' + )} + it { should contain_openvpn__option('comp-lzo test_server').with( + 'server' => 'test_server', + 'key' => 'comp-lzo' + )} + + context "when RedHat based machine" do + let(:facts) { { :osfamily => 'RedHat', :concat_basedir => '/var/lib/puppet/concat' } } + + it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf').with( + 'ensure' => 'link', + 'target' => '/etc/openvpn/test_server/easy-rsa/openssl-1.0.0.cnf' + )} + + it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with( + 'command' => '/bin/cp -r /usr/share/doc/openvpn-2.2.2/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa' + )} + + end + + context "when Debian based machine" do + let(:facts) { { :osfamily => 'Debian', :concat_basedir => '/var/lib/puppet/concat' } } + + it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf').with( + 'ensure' => 'link', + 'target' => '/etc/openvpn/test_server/easy-rsa/openssl-1.0.0.cnf' + )} + + it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with( + 'command' => '/bin/cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa' + )} + + end + +end diff --git a/puppet/modules/openvpn/spec/spec_helper.rb b/puppet/modules/openvpn/spec/spec_helper.rb new file mode 100644 index 00000000..dc7e9f4a --- /dev/null +++ b/puppet/modules/openvpn/spec/spec_helper.rb @@ -0,0 +1,2 @@ +require 'rubygems' +require 'puppetlabs_spec_helper/module_spec_helper' diff --git a/puppet/modules/openvpn/templates/etc-default-openvpn.erb b/puppet/modules/openvpn/templates/etc-default-openvpn.erb new file mode 100644 index 00000000..310e462e --- /dev/null +++ b/puppet/modules/openvpn/templates/etc-default-openvpn.erb @@ -0,0 +1,20 @@ +# This is the configuration file for /etc/init.d/openvpn + +# +# Start only these VPNs automatically via init script. +# Allowed values are "all", "none" or space separated list of +# names of the VPNs. If empty, "all" is assumed. +# +#AUTOSTART="all" +#AUTOSTART="none" +#AUTOSTART="home office" +# +# Refresh interval (in seconds) of default status files +# located in /var/run/openvpn.$NAME.status +# Defaults to 10, 0 disables status file generation +# +#STATUSREFRESH=10 +#STATUSREFRESH=0 +# Optional arguments to openvpn's command line +OPTARGS="" +AUTOSTART="" diff --git a/puppet/modules/openvpn/templates/vars.erb b/puppet/modules/openvpn/templates/vars.erb new file mode 100644 index 00000000..de988f45 --- /dev/null +++ b/puppet/modules/openvpn/templates/vars.erb @@ -0,0 +1,69 @@ +# easy-rsa parameter settings + +# NOTE: If you installed from an RPM, +# don't edit this file in place in +# /usr/share/openvpn/easy-rsa -- +# instead, you should copy the whole +# easy-rsa directory to another location +# (such as /etc/openvpn) so that your +# edits will not be wiped out by a future +# OpenVPN package upgrade. + +# This variable should point to +# the top level of the easy-rsa +# tree. +export EASY_RSA="/etc/openvpn/<%= name %>/easy-rsa" + +# +# This variable should point to +# the requested executables +# +export OPENSSL="openssl" +export PKCS11TOOL="pkcs11-tool" +export GREP="grep" + + +# This variable should point to +# the openssl.cnf file included +# with easy-rsa. +export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA` + +# Edit this variable to point to +# your soon-to-be-created key +# directory. +# +# WARNING: clean-all will do +# a rm -rf on this directory +# so make sure you define +# it correctly! +export KEY_DIR="$EASY_RSA/keys" + +# Issue rm -rf warning +echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR + +# PKCS11 fixes +export PKCS11_MODULE_PATH="dummy" +export PKCS11_PIN="dummy" + +# Increase this to 2048 if you +# are paranoid. This will slow +# down TLS negotiation performance +# as well as the one-time DH parms +# generation process. +export KEY_SIZE=1024 + +# In how many days should the root CA key expire? +export CA_EXPIRE=3650 + +# In how many days should certificates expire? +export KEY_EXPIRE=3650 + +# These are the default values for fields +# which will be placed in the certificate. +# Don't leave any of these fields blank. +export KEY_COUNTRY="<%= country %>" +export KEY_PROVINCE="<%= province %>" +export KEY_CITY="<%= city %>" +export KEY_ORG="<%= organization %>" +export KEY_EMAIL="<%= email %>" + -- cgit v1.2.3 From 26537fa81d6f97c6643fa41e5bfc5b8d0151049e Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 21 Jul 2016 21:10:54 -0700 Subject: fix couchdb's backupninja --- puppet/modules/site_couchdb/manifests/backup.pp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_couchdb/manifests/backup.pp b/puppet/modules/site_couchdb/manifests/backup.pp index 8b5aa6ea..a9771776 100644 --- a/puppet/modules/site_couchdb/manifests/backup.pp +++ b/puppet/modules/site_couchdb/manifests/backup.pp @@ -1,8 +1,8 @@ class site_couchdb::backup { # general backupninja config - backupninja::config { 'backupninja_config': - usecolors => false, + class { 'backupninja': + usecolors => false } # dump all DBs locally to /var/backups/couchdb once a day -- cgit v1.2.3 From 2aa19e3197e592ecabfa8d8b8ec29735b951ed08 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 21 Jul 2016 21:11:31 -0700 Subject: fix site_static's call to passenger --- puppet/modules/site_static/manifests/init.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_static/manifests/init.pp b/puppet/modules/site_static/manifests/init.pp index 0acfc223..462e6e05 100644 --- a/puppet/modules/site_static/manifests/init.pp +++ b/puppet/modules/site_static/manifests/init.pp @@ -56,7 +56,7 @@ class site_static { if (member($formats, 'rack')) { include site_apt::preferences::passenger class { 'passenger': - use_munin => false, + manage_munin => false, require => Class['site_apt::preferences::passenger'] } } -- cgit v1.2.3 From 5dfa7c46d09beaa15efec7248719833e9b6a9e20 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 2 Aug 2016 14:50:18 -0400 Subject: Set TCP_NODELAY option for couchdb (#8264) Mochiweb in couchdb by default sets the TCP socket option SO_NODELAY to false. This means that small data sent to the TCP socket, like the reply to a document write request (or reading a very small document), will not be sent immediately to the network - TCP will buffer it for a while hoping that it will be asked to send more data through the same socket and then send all the data at once for increased performance. Setting this increases the couchdb speed significantly. Change-Id: Ib493ef061ff62c9bdee501e44ce2b55990fe14b7 --- puppet/modules/site_couchdb/files/local.ini | 3 +++ 1 file changed, 3 insertions(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_couchdb/files/local.ini b/puppet/modules/site_couchdb/files/local.ini index b921a927..a6f4d981 100644 --- a/puppet/modules/site_couchdb/files/local.ini +++ b/puppet/modules/site_couchdb/files/local.ini @@ -6,3 +6,6 @@ [compactions] _default = [{db_fragmentation, "70%"}, {view_fragmentation, "60%"}, {from, "03:00"}, {to, "05:00"}] + +[httpd] +socket_options = [{nodelay, true}] -- cgit v1.2.3 From 8af8d4ec1ba1448fa65792903d04adb80ce0bf9c Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 4 Aug 2016 10:15:44 -0400 Subject: Remove site-apache symlink. There is no need to keep this symlink around any longer, it was there for older puppet. Change-Id: Ie7a380821d478e5ad69df39f03009d773afb73f3 --- puppet/modules/site-apache | 1 - 1 file changed, 1 deletion(-) delete mode 120000 puppet/modules/site-apache (limited to 'puppet/modules') diff --git a/puppet/modules/site-apache b/puppet/modules/site-apache deleted file mode 120000 index f0517fa5..00000000 --- a/puppet/modules/site-apache +++ /dev/null @@ -1 +0,0 @@ -site_apache \ No newline at end of file -- cgit v1.2.3 From 5d6a4c389b93486ab1aa0012284b5bdcfbbc8a20 Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 4 Aug 2016 14:57:03 -0400 Subject: Disallow intra-client connectivity (#8272). If you connect to the VPN with a client, you can make direct network connections to the other connected clients. This allows communication to the eip gateways, but disallows any other connections. Change-Id: I73e5bb5715e4d91256cbf95eda8c0ec70aa75f93 --- puppet/modules/site_shorewall/manifests/eip.pp | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_shorewall/manifests/eip.pp b/puppet/modules/site_shorewall/manifests/eip.pp index 21934761..b31f5c6f 100644 --- a/puppet/modules/site_shorewall/manifests/eip.pp +++ b/puppet/modules/site_shorewall/manifests/eip.pp @@ -85,6 +85,40 @@ class site_shorewall::eip { proto => 'tcp', destinationport => 'domain', order => 301; + + 'accept_all_eip_to_eip_gateway_udp_unlimited': + action => 'ACCEPT', + source => 'eip', + destination => 'eip:10.41.0.1', + proto => 'all', + order => 302; + + 'accept_all_eip_to_eip_gateway_tcp_unlimited': + action => 'ACCEPT', + source => 'eip', + destination => 'eip:10.42.0.1', + proto => 'all', + order => 303; + + 'accept_all_eip_to_eip_gateway_udp_limited': + action => 'ACCEPT', + source => 'eip', + destination => 'eip:10.43.0.1', + proto => 'all', + order => 302; + + 'accept_all_eip_to_eip_gateway_tcp_limited': + action => 'ACCEPT', + source => 'eip', + destination => 'eip:10.44.0.1', + proto => 'all', + order => 303; + + 'reject_all_other_eip_to_eip': + action => 'REJECT', + source => 'eip', + destination => 'eip', + order => 304; } # create dnat rule for each port -- cgit v1.2.3 From 9c2025cd0dbd8b8e19a838c3be2669a288f8a6b9 Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 4 Aug 2016 14:57:03 -0400 Subject: Disallow intra-client connectivity (#8272). If you connect to the VPN with a client, you can make direct network connections to the other connected clients. This allows communication to the eip gateways, but disallows any other connections. Change-Id: I73e5bb5715e4d91256cbf95eda8c0ec70aa75f93 --- puppet/modules/site_shorewall/manifests/eip.pp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_shorewall/manifests/eip.pp b/puppet/modules/site_shorewall/manifests/eip.pp index b31f5c6f..9da0ae3a 100644 --- a/puppet/modules/site_shorewall/manifests/eip.pp +++ b/puppet/modules/site_shorewall/manifests/eip.pp @@ -105,20 +105,19 @@ class site_shorewall::eip { source => 'eip', destination => 'eip:10.43.0.1', proto => 'all', - order => 302; + order => 304; 'accept_all_eip_to_eip_gateway_tcp_limited': action => 'ACCEPT', source => 'eip', destination => 'eip:10.44.0.1', - proto => 'all', - order => 303; + order => 305; 'reject_all_other_eip_to_eip': action => 'REJECT', source => 'eip', destination => 'eip', - order => 304; + order => 306; } # create dnat rule for each port -- cgit v1.2.3 From 7a3c80abc416bd022bf9d53d8641fc383c51b23d Mon Sep 17 00:00:00 2001 From: Micah Date: Thu, 4 Aug 2016 15:34:14 -0400 Subject: Stricter VPN egress firewall (#8289) Change-Id: Ie09a6a34dfa8fe3d72568d2de0b208e7d947412f --- puppet/modules/site_shorewall/manifests/eip.pp | 115 +++++++++++++++++++++++++ 1 file changed, 115 insertions(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_shorewall/manifests/eip.pp b/puppet/modules/site_shorewall/manifests/eip.pp index 9da0ae3a..5aac4fdd 100644 --- a/puppet/modules/site_shorewall/manifests/eip.pp +++ b/puppet/modules/site_shorewall/manifests/eip.pp @@ -118,6 +118,121 @@ class site_shorewall::eip { source => 'eip', destination => 'eip', order => 306; + # Strict egress filtering: + # SMTP (TCP 25) + # Trivial File Transfer Protocol - TFTP (UDP 69) + # MS RPC (TCP & UDP 135) + # NetBIOS/IP (TCP/UDP 139 & UDP 137, UDP 138) + # Simple Network Management Protocol – SNMP (UDP/TCP 161-162) + # SMB/IP (TCP/UDP 445) + # Syslog (UDP 514) + # Gamqowi trojan: TCP 4661 + # Mneah trojan: TCP 4666 + 'reject_outgoing_smtp': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'tcp', + destinationport => 'smtp', + order => 401; + 'reject_outgoing_tftp': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'udp', + destinationport => 'tftp', + order => 402; + 'reject_outgoing_ms_rpc_tcp': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'tcp', + destinationport => '135', + order => 403; + 'reject_outgoing_ms_rpc_udp': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'udp', + destinationport => '135', + order => 404; + 'reject_outgoing_netbios_tcp': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'tcp', + destinationport => '139', + order => 405; + 'reject_outgoing_netbios_udp': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'tcp', + destinationport => '139', + order => 406; + 'reject_outgoing_netbios_2': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'udp', + destinationport => '137', + order => 407; + 'reject_outgoing_netbios_3': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'udp', + destinationport => '138', + order => 408; + 'reject_outgoing_snmp_udp': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'udp', + destinationport => 'snmp', + order => 409; + 'reject_outgoing_snmp_tcp': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'tcp', + destinationport => 'snmp', + order => 410; + 'reject_outgoing_smb_udp': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'udp', + destinationport => '445', + order => 411; + 'reject_outgoing_smb_tcp': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'tcp', + destinationport => '445', + order => 412; + 'reject_outgoing_syslog': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'udp', + destinationport => 'syslog', + order => 413; + 'reject_outgoing_gamqowi': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'tcp', + destinationport => '4661', + order => 414; + 'reject_outgoing_mneah': + action => 'REJECT', + source => 'eip', + destination => 'net', + proto => 'tcp', + destinationport => '4666', + order => 415; } # create dnat rule for each port -- cgit v1.2.3 From 31dfdfc32439980e92e6472a8392850e2c9b6bd0 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 16 Aug 2016 14:23:16 -0400 Subject: ignore noisy 401 errors from soledad log. Change-Id: Ia1764cb28e263353856523c11f351a39774bf3b4 --- puppet/modules/site_check_mk/files/agent/logwatch/soledad.cfg | 3 +++ 1 file changed, 3 insertions(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/soledad.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/soledad.cfg index 3af5045b..11ad3a54 100644 --- a/puppet/modules/site_check_mk/files/agent/logwatch/soledad.cfg +++ b/puppet/modules/site_check_mk/files/agent/logwatch/soledad.cfg @@ -1,4 +1,7 @@ /var/log/soledad.log +# Ignore 401 errors because they are quite noisy due to scanners giving us many false +# positives, and we do not need to see those + I \".*401 [0-9]+ C WSGI application error C Error C error -- cgit v1.2.3 From c6aea725ed673a50ad0c9291c2f90ade44f20d8c Mon Sep 17 00:00:00 2001 From: Micah Date: Fri, 19 Aug 2016 08:21:06 -0400 Subject: Fix rsyslog auth.log entries (#8381). The auth.log rsyslog entry was accidentally removed in #7863. Change-Id: I4ebffeafedbca5df902041ddd2bcb80d3f68b230 --- puppet/modules/site_rsyslog/templates/client.conf.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_rsyslog/templates/client.conf.erb b/puppet/modules/site_rsyslog/templates/client.conf.erb index 553b8373..12d6ea9b 100644 --- a/puppet/modules/site_rsyslog/templates/client.conf.erb +++ b/puppet/modules/site_rsyslog/templates/client.conf.erb @@ -83,7 +83,7 @@ $ActionSendStreamDriverAuthMode anon <% if scope.lookupvar('rsyslog::log_style') == 'debian' -%> # Log auth messages locally -.*;auth,authpriv.none;mail.none -/var/log/syslog +auth,authpriv.* /var/log/auth.log <% elsif scope.lookupvar('rsyslog::log_style') == 'redhat' -%> # Log auth messages locally auth,authpriv.* /var/log/secure @@ -93,6 +93,7 @@ auth,authpriv.* /var/log/secure <% if scope.lookupvar('rsyslog::log_style') == 'debian' -%> # First some standard log files. Log by facility. # +*.*;auth,authpriv.none;mail.none -/var/log/syslog cron.* /var/log/cron.log daemon.* -/var/log/daemon.log kern.* -/var/log/kern.log -- cgit v1.2.3 From d0532dbe3463a2103ae4a0757c5168478a1ffb99 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 23 Aug 2016 09:08:27 -0400 Subject: syslog: remove duplicate messages (#8405). Change-Id: I90f8d160d2293288066847bcc199f480d06d877d --- puppet/modules/site_rsyslog/templates/client.conf.erb | 4 ---- 1 file changed, 4 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_rsyslog/templates/client.conf.erb b/puppet/modules/site_rsyslog/templates/client.conf.erb index 12d6ea9b..1a1e4b6d 100644 --- a/puppet/modules/site_rsyslog/templates/client.conf.erb +++ b/puppet/modules/site_rsyslog/templates/client.conf.erb @@ -106,10 +106,6 @@ user.* -/var/log/user.log *.=debug;\ auth,authpriv.none;\ news.none;mail.none -/var/log/debug -*.=info;*.=notice;*.=warn;\ - auth,authpriv.none;\ - cron,daemon.none;\ - mail,news.none -/var/log/messages # Log anything (except mail) of level info or higher. # Don't log private authentication messages! -- cgit v1.2.3 From dadac49e55f19e7ac814ae798dcfb87fddbef0ba Mon Sep 17 00:00:00 2001 From: varac Date: Mon, 29 Aug 2016 18:31:42 +0200 Subject: [feat] Use twisted 16.2 from jessie-backports New soledad packages now depend on Twisted 16.2.0 (see https://leap.se/code/issues/8412), so we need to pin twisted to get installed from jessie-backports. - Resolves: #8418 --- .../site_apt/manifests/preferences/twisted.pp | 11 +++++++ puppet/modules/site_webapp/manifests/init.pp | 35 +++++++++++----------- 2 files changed, 29 insertions(+), 17 deletions(-) create mode 100644 puppet/modules/site_apt/manifests/preferences/twisted.pp (limited to 'puppet/modules') diff --git a/puppet/modules/site_apt/manifests/preferences/twisted.pp b/puppet/modules/site_apt/manifests/preferences/twisted.pp new file mode 100644 index 00000000..a3fa0950 --- /dev/null +++ b/puppet/modules/site_apt/manifests/preferences/twisted.pp @@ -0,0 +1,11 @@ +# Pin twisted to jessie-backports in order to +# use 16.2.0 for i.e. soledad +class site_apt::preferences::twisted { + + apt::preferences_snippet { 'twisted': + package => 'python-twisted*', + release => "${::lsbdistcodename}-backports", + priority => 999; + } + +} diff --git a/puppet/modules/site_webapp/manifests/init.pp b/puppet/modules/site_webapp/manifests/init.pp index 15925aba..cdad206a 100644 --- a/puppet/modules/site_webapp/manifests/init.pp +++ b/puppet/modules/site_webapp/manifests/init.pp @@ -16,21 +16,22 @@ class site_webapp { Class['site_config::default'] -> Class['site_webapp'] - include site_config::ruby::dev - include site_webapp::apache - include site_webapp::couchdb - include site_haproxy - include site_webapp::cron - include site_config::default - include site_config::x509::cert - include site_config::x509::key - include site_config::x509::ca - include site_config::x509::client_ca::ca - include site_config::x509::client_ca::key - include site_nickserver + include ::site_config::ruby::dev + include ::site_webapp::apache + include ::site_webapp::couchdb + include ::site_haproxy + include ::site_webapp::cron + include ::site_config::default + include ::site_config::x509::cert + include ::site_config::x509::key + include ::site_config::x509::ca + include ::site_config::x509::client_ca::ca + include ::site_config::x509::client_ca::key + include ::site_nickserver + include ::site_apt::preferences::twisted # remove leftovers from previous installations on webapp nodes - include site_config::remove::webapp + include ::site_config::remove::webapp group { 'leap-webapp': ensure => present, @@ -163,17 +164,17 @@ class site_webapp { if $tor { $hidden_service = $tor['hidden_service'] if $hidden_service['active'] { - include site_webapp::hidden_service + include ::site_webapp::hidden_service } } # needed for the soledad-sync check which is run on the # webapp node - include soledad::client + include ::soledad::client leap::logfile { 'webapp': } - include site_shorewall::webapp - include site_check_mk::agent::webapp + include ::site_shorewall::webapp + include ::site_check_mk::agent::webapp } -- cgit v1.2.3 From d3bde1463bd31121a0015a93ad29f4db69fd77c7 Mon Sep 17 00:00:00 2001 From: varac Date: Mon, 29 Aug 2016 18:35:31 +0200 Subject: lint site_webapp/manifests/init.pp --- puppet/modules/site_webapp/manifests/init.pp | 36 +++++++++++++++++++--------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_webapp/manifests/init.pp b/puppet/modules/site_webapp/manifests/init.pp index cdad206a..83cf99a9 100644 --- a/puppet/modules/site_webapp/manifests/init.pp +++ b/puppet/modules/site_webapp/manifests/init.pp @@ -92,12 +92,16 @@ class site_webapp { '/srv/leap/webapp/config/provider': ensure => directory, require => Vcsrepo['/srv/leap/webapp'], - owner => leap-webapp, group => leap-webapp, mode => '0755'; + owner => 'leap-webapp', + group => 'leap-webapp', + mode => '0755'; '/srv/leap/webapp/config/provider/provider.json': content => $provider, require => Vcsrepo['/srv/leap/webapp'], - owner => leap-webapp, group => leap-webapp, mode => '0644'; + owner => 'leap-webapp', + group => 'leap-webapp', + mode => '0644'; '/srv/leap/webapp/public/ca.crt': ensure => link, @@ -107,27 +111,37 @@ class site_webapp { "/srv/leap/webapp/public/${api_version}": ensure => directory, require => Vcsrepo['/srv/leap/webapp'], - owner => leap-webapp, group => leap-webapp, mode => '0755'; + owner => 'leap-webapp', + group => 'leap-webapp', + mode => '0755'; "/srv/leap/webapp/public/${api_version}/config/": ensure => directory, require => Vcsrepo['/srv/leap/webapp'], - owner => leap-webapp, group => leap-webapp, mode => '0755'; + owner => 'leap-webapp', + group => 'leap-webapp', + mode => '0755'; "/srv/leap/webapp/public/${api_version}/config/eip-service.json": content => $eip_service, require => Vcsrepo['/srv/leap/webapp'], - owner => leap-webapp, group => leap-webapp, mode => '0644'; + owner => 'leap-webapp', + group => 'leap-webapp', + mode => '0644'; "/srv/leap/webapp/public/${api_version}/config/soledad-service.json": content => $soledad_service, require => Vcsrepo['/srv/leap/webapp'], - owner => leap-webapp, group => leap-webapp, mode => '0644'; + owner => 'leap-webapp', + group => 'leap-webapp', + mode => '0644'; "/srv/leap/webapp/public/${api_version}/config/smtp-service.json": content => $smtp_service, require => Vcsrepo['/srv/leap/webapp'], - owner => leap-webapp, group => leap-webapp, mode => '0644'; + owner => 'leap-webapp', + group => 'leap-webapp', + mode => '0644'; } try::file { @@ -136,8 +150,8 @@ class site_webapp { recurse => true, purge => true, force => true, - owner => leap-webapp, - group => leap-webapp, + owner => 'leap-webapp', + group => 'leap-webapp', mode => 'u=rwX,go=rX', require => Vcsrepo['/srv/leap/webapp'], notify => Exec['compile_assets'], @@ -154,8 +168,8 @@ class site_webapp { file { '/srv/leap/webapp/config/config.yml': content => template('site_webapp/config.yml.erb'), - owner => leap-webapp, - group => leap-webapp, + owner => 'leap-webapp', + group => 'leap-webapp', mode => '0600', require => Vcsrepo['/srv/leap/webapp'], notify => Service['apache']; -- cgit v1.2.3 From 1b4a1aaa6097e0fda72a7829ea3eb029a9e16c93 Mon Sep 17 00:00:00 2001 From: varac Date: Wed, 31 Aug 2016 09:47:08 +0200 Subject: Document site_check_mk::agent::soledad --- puppet/modules/site_check_mk/manifests/agent/soledad.pp | 1 + 1 file changed, 1 insertion(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_check_mk/manifests/agent/soledad.pp b/puppet/modules/site_check_mk/manifests/agent/soledad.pp index f4a3f3a6..d6aa810a 100644 --- a/puppet/modules/site_check_mk/manifests/agent/soledad.pp +++ b/puppet/modules/site_check_mk/manifests/agent/soledad.pp @@ -1,3 +1,4 @@ +# Configure soledad check_mk checks class site_check_mk::agent::soledad { file { '/etc/check_mk/logwatch.d/soledad.cfg': -- cgit v1.2.3 From b0c33b9c66116eb49f583a05d7baaaab7b6e7a15 Mon Sep 17 00:00:00 2001 From: varac Date: Wed, 31 Aug 2016 21:36:44 +0200 Subject: [style] lint soledad::server --- puppet/modules/soledad/manifests/server.pp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/soledad/manifests/server.pp b/puppet/modules/soledad/manifests/server.pp index 6cf806d0..c5e2455d 100644 --- a/puppet/modules/soledad/manifests/server.pp +++ b/puppet/modules/soledad/manifests/server.pp @@ -2,8 +2,8 @@ class soledad::server { tag 'leap_service' - include site_config::default - include soledad::common + include ::site_config::default + include ::soledad::common $soledad = hiera('soledad') $couchdb_user = $soledad['couchdb_soledad_user']['username'] @@ -90,11 +90,11 @@ class soledad::server { } user { 'soledad': - ensure => present, - system => true, - gid => 'soledad', - home => '/srv/leap/soledad', - require => Group['soledad']; + ensure => present, + system => true, + gid => 'soledad', + home => '/srv/leap/soledad', + require => Group['soledad']; 'soledad-admin': ensure => present, system => true, -- cgit v1.2.3 From 9ef0d00b4302b7ddfc9d5620eeb4fad90d3a15aa Mon Sep 17 00:00:00 2001 From: varac Date: Wed, 31 Aug 2016 22:11:49 +0200 Subject: [bug] Remove Nagios soledad procs check leap_cli already checks for running procs - Resolves: #8380 --- puppet/modules/site_check_mk/manifests/agent/soledad.pp | 10 ---------- puppet/modules/site_config/manifests/remove/soledad.pp | 12 ++++++++++++ puppet/modules/soledad/manifests/server.pp | 1 + 3 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 puppet/modules/site_config/manifests/remove/soledad.pp (limited to 'puppet/modules') diff --git a/puppet/modules/site_check_mk/manifests/agent/soledad.pp b/puppet/modules/site_check_mk/manifests/agent/soledad.pp index d6aa810a..a8febaae 100644 --- a/puppet/modules/site_check_mk/manifests/agent/soledad.pp +++ b/puppet/modules/site_check_mk/manifests/agent/soledad.pp @@ -5,14 +5,4 @@ class site_check_mk::agent::soledad { source => 'puppet:///modules/site_check_mk/agent/logwatch/soledad.cfg', } - # local nagios plugin checks via mrpe - - augeas { 'Soledad_Procs': - incl => '/etc/check_mk/mrpe.cfg', - lens => 'Spacevars.lns', - changes => [ - 'rm /files/etc/check_mk/mrpe.cfg/Soledad_Procs', - 'set Soledad_Procs \'/usr/lib/nagios/plugins/check_procs -w 1:1 -c 1:1 -a "/usr/bin/python /usr/bin/twistd --uid=soledad --gid=soledad --pidfile=/var/run/soledad.pid --logfile=/var/log/soledad.log web --wsgi=leap.soledad.server.application --port=ssl:2323:privateKey=/etc/x509/keys/leap.key:certKey=/etc/x509/certs/leap.crt:sslmethod=SSLv23_METHOD"\'' ], - require => File['/etc/check_mk/mrpe.cfg']; - } } diff --git a/puppet/modules/site_config/manifests/remove/soledad.pp b/puppet/modules/site_config/manifests/remove/soledad.pp new file mode 100644 index 00000000..46c23f26 --- /dev/null +++ b/puppet/modules/site_config/manifests/remove/soledad.pp @@ -0,0 +1,12 @@ +# remove possible leftovers on soledad nodes +class site_config::remove::soledad { + + # remove soledad procs check because leap_cli already checks for them + augeas { 'Soledad_Procs': + incl => '/etc/check_mk/mrpe.cfg', + lens => 'Spacevars.lns', + changes => [ 'rm /files/etc/check_mk/mrpe.cfg/Soledad_Procs' ], + require => File['/etc/check_mk/mrpe.cfg']; + } + +} diff --git a/puppet/modules/soledad/manifests/server.pp b/puppet/modules/soledad/manifests/server.pp index c5e2455d..81f51188 100644 --- a/puppet/modules/soledad/manifests/server.pp +++ b/puppet/modules/soledad/manifests/server.pp @@ -4,6 +4,7 @@ class soledad::server { include ::site_config::default include ::soledad::common + include ::site_config::remove::soledad $soledad = hiera('soledad') $couchdb_user = $soledad['couchdb_soledad_user']['username'] -- cgit v1.2.3 From 07c0e60e6bdc5b8bfe1f42f76dae9f0a79e7abb0 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 29 Aug 2016 16:35:14 -0700 Subject: moved infrastructure tests run by `leap run` to tests/server-tests --- puppet/modules/site_config/manifests/remove/files.pp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_config/manifests/remove/files.pp b/puppet/modules/site_config/manifests/remove/files.pp index 3de8d695..ac2350a0 100644 --- a/puppet/modules/site_config/manifests/remove/files.pp +++ b/puppet/modules/site_config/manifests/remove/files.pp @@ -12,11 +12,28 @@ class site_config::remove::files { # - # Platform X removals + # Platform 0.9 removals # tidy { + # moved to /srv/static/public/provider.json + # for permissions reasons. '/srv/leap/provider.json':; + + # tests are moved to /srv/leap/tests/server-tests + # by rsync is not able to clean up the old location, + # so, we do it here: + '/srv/leap/tests/order.rb':; + '/srv/leap/tests/README.md':; + '/srv/leap/tests/helpers': + recurse => true, + rmdirs => true; + '/srv/leap/tests/puppet': + recurse => true, + rmdirs => true; + '/srv/leap/tests/white-box': + recurse => true, + rmdirs => true; } # -- cgit v1.2.3 From 8116e007cfd4dbee8282247348cf45473dcde45e Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 31 Aug 2016 14:54:46 -0700 Subject: added support for Let's Encrypt --- puppet/modules/site_apache/files/conf.d/acme.conf | 10 ++++++ puppet/modules/site_apache/manifests/common.pp | 2 ++ .../modules/site_apache/manifests/common/acme.pp | 38 ++++++++++++++++++++++ .../site_config/manifests/x509/commercial/ca.pp | 10 ++++-- 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 puppet/modules/site_apache/files/conf.d/acme.conf create mode 100644 puppet/modules/site_apache/manifests/common/acme.pp (limited to 'puppet/modules') diff --git a/puppet/modules/site_apache/files/conf.d/acme.conf b/puppet/modules/site_apache/files/conf.d/acme.conf new file mode 100644 index 00000000..cdddf53e --- /dev/null +++ b/puppet/modules/site_apache/files/conf.d/acme.conf @@ -0,0 +1,10 @@ +# +# Allow ACME certificate verification if /srv/acme exists. +# + + Alias "/.well-known/acme-challenge/" "/srv/acme/" + + Require all granted + Header set Content-Type "application/jose+json" + + diff --git a/puppet/modules/site_apache/manifests/common.pp b/puppet/modules/site_apache/manifests/common.pp index 8a11759a..208c15d5 100644 --- a/puppet/modules/site_apache/manifests/common.pp +++ b/puppet/modules/site_apache/manifests/common.pp @@ -27,4 +27,6 @@ class site_apache::common { } include site_apache::common::tls + include site_apache::common::acme + } diff --git a/puppet/modules/site_apache/manifests/common/acme.pp b/puppet/modules/site_apache/manifests/common/acme.pp new file mode 100644 index 00000000..eda4148b --- /dev/null +++ b/puppet/modules/site_apache/manifests/common/acme.pp @@ -0,0 +1,38 @@ +# +# Allows for potential ACME validations (aka Let's Encrypt) +# +class site_apache::common::acme { + # + # well, this doesn't work: + # + # apache::config::global {'acme.conf':} + # + # since /etc/apache2/conf.d is NEVER LOADED BY APACHE + # https://gitlab.com/shared-puppet-modules-group/apache/issues/11 + # + + file { + '/etc/apache2/conf-available/acme.conf': + ensure => present, + source => 'puppet:///modules/site_apache/conf.d/acme.conf', + require => Package[apache], + notify => Service[apache]; + '/etc/apache2/conf-enabled/acme.conf': + ensure => link, + target => '/etc/apache2/conf-available/acme.conf', + require => Package[apache], + notify => Service[apache]; + } + + file { + '/srv/acme': + ensure => 'directory', + owner => 'www-data', + group => 'www-data', + mode => '0755'; + '/srv/acme/ok': + owner => 'www-data', + group => 'www-data', + content => 'ok'; + } +} diff --git a/puppet/modules/site_config/manifests/x509/commercial/ca.pp b/puppet/modules/site_config/manifests/x509/commercial/ca.pp index c76a9dbb..21d57445 100644 --- a/puppet/modules/site_config/manifests/x509/commercial/ca.pp +++ b/puppet/modules/site_config/manifests/x509/commercial/ca.pp @@ -5,7 +5,13 @@ class site_config::x509::commercial::ca { $x509 = hiera('x509') $ca = $x509['commercial_ca_cert'] - x509::ca { $site_config::params::commercial_ca_name: - content => $ca + # + # CA cert might be empty, if it was bundled with 'commercial_cert' + # instead of specified separately. + # + if ($ca) { + x509::ca { $site_config::params::commercial_ca_name: + content => $ca + } } } -- cgit v1.2.3 From 90e4bca777f6edfbde29b590313cf938f75c53a7 Mon Sep 17 00:00:00 2001 From: varac Date: Mon, 5 Sep 2016 14:18:55 +0200 Subject: [style] lint ::site_static class --- puppet/modules/site_static/manifests/init.pp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_static/manifests/init.pp b/puppet/modules/site_static/manifests/init.pp index 462e6e05..824619b4 100644 --- a/puppet/modules/site_static/manifests/init.pp +++ b/puppet/modules/site_static/manifests/init.pp @@ -16,14 +16,14 @@ class site_static { file { '/srv/static/': ensure => 'directory', - owner => 'root', - group => 'root', - mode => '0744'; + owner => 'root', + group => 'root', + mode => '0744'; '/srv/static/public': ensure => 'directory', - owner => 'root', - group => 'root', - mode => '0744'; + owner => 'root', + group => 'root', + mode => '0744'; } if $bootstrap['enabled'] { @@ -57,7 +57,7 @@ class site_static { include site_apt::preferences::passenger class { 'passenger': manage_munin => false, - require => Class['site_apt::preferences::passenger'] + require => Class['site_apt::preferences::passenger'] } } -- cgit v1.2.3 From 67591d5f91b33bd8196137c14ea6ae4a01321aea Mon Sep 17 00:00:00 2001 From: varac Date: Tue, 6 Sep 2016 11:45:58 +0200 Subject: [feat] Add check_mk config values, dont set them When setting values like ignored_services = [...] this will override other `ignored_services` that might get parsed before. Instead, we use `+=` so multiple files can add sth to this config value. --- puppet/modules/site_check_mk/files/ignored_services.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_check_mk/files/ignored_services.mk b/puppet/modules/site_check_mk/files/ignored_services.mk index 35dc4433..8a6705ac 100644 --- a/puppet/modules/site_check_mk/files/ignored_services.mk +++ b/puppet/modules/site_check_mk/files/ignored_services.mk @@ -1,3 +1,5 @@ -ignored_services = [ +# ignore NTP Time because this check was +# very flaky in the past (see https://leap.se/code/issues/6407) +ignored_services += [ ( ALL_HOSTS, [ "NTP Time" ] ) ] -- cgit v1.2.3 From d6e6b05c093bf6e3c2abc5dc40cda466760b5f32 Mon Sep 17 00:00:00 2001 From: varac Date: Wed, 7 Sep 2016 10:44:57 +0200 Subject: Fix dependencies for clamd service Sometimes, after a deploy from scratch `leap test` fails because clamd could not get started (even when the deploy log says so). This fixes the dependencies of all resources needed in order to let clamd start reliable. Resolves: #8431 --- puppet/modules/clamav/manifests/daemon.pp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/clamav/manifests/daemon.pp b/puppet/modules/clamav/manifests/daemon.pp index 2e13a8fb..c0a4a450 100644 --- a/puppet/modules/clamav/manifests/daemon.pp +++ b/puppet/modules/clamav/manifests/daemon.pp @@ -15,7 +15,6 @@ class clamav::daemon { pattern => '/usr/sbin/clamd', enable => true, hasrestart => true, - subscribe => File['/etc/default/clamav-daemon'], require => Package['clamav-daemon']; } @@ -25,19 +24,23 @@ class clamav::daemon { mode => '0750', owner => clamav, group => postfix, - require => [Package['postfix'], Package['clamav-daemon']]; + require => [Package['postfix'], Package['clamav-daemon']], + notify => Service['clamav-daemon']; '/var/lib/clamav': mode => '0755', owner => clamav, group => clamav, - require => Package['clamav-daemon']; + require => Package['clamav-daemon'], + notify => Service['clamav-daemon']; '/etc/default/clamav-daemon': - source => 'puppet:///modules/clamav/clamav-daemon_default', - mode => '0644', - owner => root, - group => root; + source => 'puppet:///modules/clamav/clamav-daemon_default', + mode => '0644', + owner => root, + group => root, + require => Package['clamav-daemon'], + notify => Service['clamav-daemon']; # this file contains additional domains that we want the clamav # phishing process to look for (our domain) @@ -46,7 +49,8 @@ class clamav::daemon { mode => '0644', owner => clamav, group => clamav, - require => Package['clamav-daemon']; + require => Package['clamav-daemon'], + notify => Service['clamav-daemon']; } file_line { -- cgit v1.2.3 From f5db49cf6b3ca0a5830b849c0aac074e371b95d9 Mon Sep 17 00:00:00 2001 From: varac Date: Thu, 8 Sep 2016 14:27:39 +0200 Subject: Add systemd::enable define --- puppet/modules/systemd/manifests/enable.pp | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 puppet/modules/systemd/manifests/enable.pp (limited to 'puppet/modules') diff --git a/puppet/modules/systemd/manifests/enable.pp b/puppet/modules/systemd/manifests/enable.pp new file mode 100644 index 00000000..e1bee18a --- /dev/null +++ b/puppet/modules/systemd/manifests/enable.pp @@ -0,0 +1,8 @@ +# enables a systemd resource +define systemd::enable () { + + exec { "enable_systemd_${name}": + refreshonly => true, + command => "/bin/systemctl enable ${name}" + } +} -- cgit v1.2.3 From a3af8acba8cd479f47d76784082d95100c0833ef Mon Sep 17 00:00:00 2001 From: Christoph Kluenter Date: Wed, 7 Sep 2016 15:36:54 +0200 Subject: start clamav after definitions are downloaded freshclam might not be able to start clamav via the socket because the socket might not be there. This systemd unit watches for the definitions and then starts clamav. Resolves: #8431 --- puppet/modules/clamav/files/clamav-daemon.path | 12 +++++++++++ puppet/modules/clamav/manifests/daemon.pp | 1 + .../modules/clamav/manifests/daemon/activation.pp | 24 ++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 puppet/modules/clamav/files/clamav-daemon.path create mode 100644 puppet/modules/clamav/manifests/daemon/activation.pp (limited to 'puppet/modules') diff --git a/puppet/modules/clamav/files/clamav-daemon.path b/puppet/modules/clamav/files/clamav-daemon.path new file mode 100644 index 00000000..6e57d187 --- /dev/null +++ b/puppet/modules/clamav/files/clamav-daemon.path @@ -0,0 +1,12 @@ +[Unit] +Description=Path Activation for Clam AntiVirus userspace daemon +Documentation=man:clamd(8) man:clamd.conf(5) http://www.clamav.net/lang/en/doc/ + +[Path] +# Check and wait for database existence before starting up +PathExistsGlob=/var/lib/clamav/main.{c[vl]d,inc} +PathExistsGlob=/var/lib/clamav/daily.{c[vl]d,inc} + +[Install] +WantedBy=sockets.target + diff --git a/puppet/modules/clamav/manifests/daemon.pp b/puppet/modules/clamav/manifests/daemon.pp index 2e13a8fb..b51a07e9 100644 --- a/puppet/modules/clamav/manifests/daemon.pp +++ b/puppet/modules/clamav/manifests/daemon.pp @@ -1,5 +1,6 @@ # deploy clamav daemon class clamav::daemon { + include clamav::daemon::activation $domain_hash = hiera('domain') $domain = $domain_hash['full_suffix'] diff --git a/puppet/modules/clamav/manifests/daemon/activation.pp b/puppet/modules/clamav/manifests/daemon/activation.pp new file mode 100644 index 00000000..09c1e55e --- /dev/null +++ b/puppet/modules/clamav/manifests/daemon/activation.pp @@ -0,0 +1,24 @@ +# ensure clamav starts after the definitions are downloaded +# needed because sometimes clamd cannot get started by freshclam, +# see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=827909 +class clamav::daemon::activation { + + file { '/etc/systemd/system/clamav-daemon.path': + source => 'puppet:///modules/clamav/clamav-daemon.path', + mode => '0644', + owner => root, + group => root, + notify => [ Exec['systemctl-daemon-reload'], Systemd::Enable['clamav-daemon.path'] ] + } + + systemd::enable { 'clamav-daemon.path': + require => Exec['systemctl-daemon-reload'], + notify => Exec['start_clamd_path_monitor'] + } + + exec { 'start_clamd_path_monitor': + command => '/bin/systemctl start clamav-daemon.path', + refreshonly => true, + before => Service['freshclam'] + } +} -- cgit v1.2.3 From a063280eab5e8749c74381aabbe641c30887e9f6 Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 2 Sep 2016 12:35:09 -0700 Subject: [bugfix] static sites: only enable hidden service by default if one domain is configured The problem is that we have a single onion address per server, so if more than one domain is configured we need to make sure they don't both try to use the same onion address. --- puppet/modules/site_static/manifests/domain.pp | 1 + puppet/modules/site_static/manifests/init.pp | 8 ++++++++ puppet/modules/site_static/templates/apache.conf.erb | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_static/manifests/domain.pp b/puppet/modules/site_static/manifests/domain.pp index b26cc9e3..6cf2c653 100644 --- a/puppet/modules/site_static/manifests/domain.pp +++ b/puppet/modules/site_static/manifests/domain.pp @@ -4,6 +4,7 @@ define site_static::domain ( $key, $cert, $tls_only=true, + $use_hidden_service=false, $locations=undef, $aliases=undef, $apache_config=undef) { diff --git a/puppet/modules/site_static/manifests/init.pp b/puppet/modules/site_static/manifests/init.pp index 824619b4..dd3f912d 100644 --- a/puppet/modules/site_static/manifests/init.pp +++ b/puppet/modules/site_static/manifests/init.pp @@ -77,6 +77,14 @@ class site_static { if $hidden_service['active'] { include site_static::hidden_service } + # Currently, we only support a single hidden service address per server. + # So if there is more than one domain configured, then we need to make sure + # we don't enable the hidden service for every domain. + if size(keys($domains)) == 1 { + $always_use_hidden_service = true + } else { + $always_use_hidden_service = false + } } create_resources(site_static::domain, $domains) diff --git a/puppet/modules/site_static/templates/apache.conf.erb b/puppet/modules/site_static/templates/apache.conf.erb index af9a520d..dd04ca43 100644 --- a/puppet/modules/site_static/templates/apache.conf.erb +++ b/puppet/modules/site_static/templates/apache.conf.erb @@ -74,7 +74,7 @@ Require all granted -<%- if @tor -%> +<%- if @tor && (@always_use_hidden_service || @use_hidden_service) -%> ## ## Tor ## -- cgit v1.2.3 From 291d5718607a2df22ca58a0c110bee75452a085c Mon Sep 17 00:00:00 2001 From: varac Date: Wed, 28 Sep 2016 11:01:19 +0200 Subject: lint site_mx class --- puppet/modules/site_mx/manifests/init.pp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_mx/manifests/init.pp b/puppet/modules/site_mx/manifests/init.pp index a9b0198b..d18f4287 100644 --- a/puppet/modules/site_mx/manifests/init.pp +++ b/puppet/modules/site_mx/manifests/init.pp @@ -1,20 +1,21 @@ +# Configure leap_mx on mx server class site_mx { tag 'leap_service' - Class['site_config::default'] -> Class['site_mx'] + Class['::site_config::default'] -> Class['::site_mx'] - include site_config::default - include site_config::x509::cert - include site_config::x509::key - include site_config::x509::ca - include site_config::x509::client_ca::ca - include site_config::x509::client_ca::key + include ::site_config::default + include ::site_config::x509::cert + include ::site_config::x509::key + include ::site_config::x509::ca + include ::site_config::x509::client_ca::ca + include ::site_config::x509::client_ca::key - include site_stunnel + include ::site_stunnel - include site_postfix::mx - include site_haproxy - include site_shorewall::mx - include site_shorewall::service::smtp - include leap_mx - include site_check_mk::agent::mx + include ::site_postfix::mx + include ::site_haproxy + include ::site_shorewall::mx + include ::site_shorewall::service::smtp + include ::leap_mx + include ::site_check_mk::agent::mx } -- cgit v1.2.3 From c752039fdf59e5c8a18c5dc7c611bd996e323eec Mon Sep 17 00:00:00 2001 From: varac Date: Wed, 28 Sep 2016 11:06:05 +0200 Subject: [feat] Use twisted 16.2 from jessie-backports New soledad packages now depend on Twisted 16.2.0 (see https://leap.se/code/issues/8412), so we need to pin twisted to get installed from jessie-backports. - Resolves: #8418 --- puppet/modules/site_mx/manifests/init.pp | 2 ++ puppet/modules/soledad/manifests/common.pp | 3 +++ 2 files changed, 5 insertions(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_mx/manifests/init.pp b/puppet/modules/site_mx/manifests/init.pp index d18f4287..c910a45a 100644 --- a/puppet/modules/site_mx/manifests/init.pp +++ b/puppet/modules/site_mx/manifests/init.pp @@ -18,4 +18,6 @@ class site_mx { include ::site_shorewall::service::smtp include ::leap_mx include ::site_check_mk::agent::mx + # install twisted from jessie backports + include ::site_apt::preferences::twisted } diff --git a/puppet/modules/soledad/manifests/common.pp b/puppet/modules/soledad/manifests/common.pp index 8d8339d4..35969362 100644 --- a/puppet/modules/soledad/manifests/common.pp +++ b/puppet/modules/soledad/manifests/common.pp @@ -1,6 +1,9 @@ # install soledad-common, both needed both soledad-client and soledad-server class soledad::common { + # install twisted from jessie backports + include ::site_apt::preferences::twisted + package { 'soledad-common': ensure => latest; } -- cgit v1.2.3 From 73ca4fe4b3bad52b1d4c6c950d06b16e2db014ae Mon Sep 17 00:00:00 2001 From: varac Date: Wed, 12 Oct 2016 16:10:30 +0200 Subject: Lint site_couchdb::setup --- puppet/modules/site_couchdb/manifests/setup.pp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_couchdb/manifests/setup.pp b/puppet/modules/site_couchdb/manifests/setup.pp index 7477d24c..84659745 100644 --- a/puppet/modules/site_couchdb/manifests/setup.pp +++ b/puppet/modules/site_couchdb/manifests/setup.pp @@ -17,11 +17,11 @@ class site_couchdb::setup { # (i.e. using curl/wget without passing credentials) file { '/etc/couchdb/couchdb.netrc': - ensure => link, - target => "/etc/couchdb/couchdb-${user}.netrc"; + ensure => link, + target => "/etc/couchdb/couchdb-${user}.netrc"; '/root/.netrc': - ensure => link, - target => '/etc/couchdb/couchdb.netrc'; + ensure => link, + target => '/etc/couchdb/couchdb.netrc'; } # setup /etc/couchdb/couchdb-soledad-admin.netrc file for couchdb admin -- cgit v1.2.3 From 0b279d8a66293bdf5fe20a77b557055a95a66a46 Mon Sep 17 00:00:00 2001 From: varac Date: Wed, 12 Oct 2016 18:41:35 +0200 Subject: Setup couch for soledad before starting soledad When the soledad couch user is not present, soledad-server refuses to start, so we need to ensure that couch is setup correctly before starting soledad-server. see https://leap.se/code/issues/8535 --- puppet/modules/site_couchdb/manifests/add_users.pp | 3 ++- puppet/modules/site_couchdb/manifests/create_dbs.pp | 3 ++- puppet/modules/site_couchdb/manifests/setup.pp | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'puppet/modules') diff --git a/puppet/modules/site_couchdb/manifests/add_users.pp b/puppet/modules/site_couchdb/manifests/add_users.pp index c905316b..f12c5a5e 100644 --- a/puppet/modules/site_couchdb/manifests/add_users.pp +++ b/puppet/modules/site_couchdb/manifests/add_users.pp @@ -33,7 +33,8 @@ class site_couchdb::add_users { roles => '["tokens"]', pw => $site_couchdb::couchdb_soledad_pw, salt => $site_couchdb::couchdb_soledad_salt, - require => Couchdb::Query::Setup['localhost'] + require => Couchdb::Query::Setup['localhost'], + notify => Service['soledad-server']; } ## webapp couchdb user diff --git a/puppet/modules/site_couchdb/manifests/create_dbs.pp b/puppet/modules/site_couchdb/manifests/create_dbs.pp index a2d1c655..ddfb7d65 100644 --- a/puppet/modules/site_couchdb/manifests/create_dbs.pp +++ b/puppet/modules/site_couchdb/manifests/create_dbs.pp @@ -44,7 +44,8 @@ class site_couchdb::create_dbs { ## r/w: soledad couchdb::create_db { 'shared': members => "{ \"names\": [\"${site_couchdb::couchdb_soledad_user}\"], \"roles\": [\"replication\"] }", - require => Couchdb::Query::Setup['localhost'] + require => Couchdb::Query::Setup['localhost'], + notify => Service['soledad-server']; } ## tickets database diff --git a/puppet/modules/site_couchdb/manifests/setup.pp b/puppet/modules/site_couchdb/manifests/setup.pp index 84659745..a749c628 100644 --- a/puppet/modules/site_couchdb/manifests/setup.pp +++ b/puppet/modules/site_couchdb/manifests/setup.pp @@ -33,7 +33,8 @@ class site_couchdb::setup { mode => '0400', owner => 'soledad-admin', group => 'root', - require => [ Package['couchdb'], User['soledad-admin'] ]; + require => [ Package['couchdb'], User['soledad-admin'] ], + notify => Service['soledad-server']; } } -- cgit v1.2.3 From 53ddc64b6aa98653b35b23c334df605ed26ea60b Mon Sep 17 00:00:00 2001 From: Micah Anderson Date: Mon, 24 Oct 2016 11:29:59 -0400 Subject: Set X-Content-Type-Options nosniff. Setting this header will prevent the browser from interpreting files as something else than declared by the content type in the HTTP headers. This will prevent the browser from MIME-sniffing a response away from the declared content-type. When this is not set, older versions of Internet Explorer and Chrome perform MIME-sniffing on the response body, potentially causing the response body to be interpreted and displayed as a content type other than the declared content type. --- puppet/modules/site_apache/templates/vhosts.d/api.conf.erb | 1 + 1 file changed, 1 insertion(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb b/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb index bfa5d04d..5e27a9e4 100644 --- a/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb +++ b/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb @@ -23,6 +23,7 @@ Listen 0.0.0.0:<%= @api_port %> <% end -%> Header always unset X-Powered-By Header always unset X-Runtime + Header always set X-Content-Type-Options: nosniff
DocumentRoot /srv/leap/webapp/public -- cgit v1.2.3 From 4db1e7c4454ea05c524be4cc385ede1bab2e1be4 Mon Sep 17 00:00:00 2001 From: Micah Anderson Date: Mon, 24 Oct 2016 11:31:41 -0400 Subject: Set X-XSS-Protection HTTP response header to '1'. This HTTP response header enables the Cross-site scripting (XSS) filter built into some modern web browsers. This header is usually enabled by default anyway, so the role of this header is to re-enable the filter if it was disabled maliciously, or by accident. --- puppet/modules/site_apache/templates/vhosts.d/api.conf.erb | 1 + 1 file changed, 1 insertion(+) (limited to 'puppet/modules') diff --git a/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb b/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb index 5e27a9e4..e68b9ebe 100644 --- a/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb +++ b/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb @@ -23,6 +23,7 @@ Listen 0.0.0.0:<%= @api_port %> <% end -%> Header always unset X-Powered-By Header always unset X-Runtime + Header always set X-XSS-Protection "1; mode=block" Header always set X-Content-Type-Options: nosniff -- cgit v1.2.3