summaryrefslogtreecommitdiff
path: root/puppet/modules
diff options
context:
space:
mode:
Diffstat (limited to 'puppet/modules')
m---------puppet/modules/apt0
m---------puppet/modules/backupninja0
m---------puppet/modules/check_mk0
m---------puppet/modules/couchdb0
m---------puppet/modules/git0
-rw-r--r--puppet/modules/leap_mx/manifests/init.pp62
-rw-r--r--puppet/modules/leap_mx/templates/mx.conf.erb15
m---------puppet/modules/postfix0
m---------puppet/modules/rsyslog0
m---------puppet/modules/rubygems0
-rw-r--r--puppet/modules/site_apache/files/conf.d/security55
-rw-r--r--puppet/modules/site_apache/manifests/common.pp26
-rw-r--r--puppet/modules/site_apache/manifests/module/alias.pp5
-rw-r--r--puppet/modules/site_apache/manifests/module/expires.pp4
-rw-r--r--puppet/modules/site_apache/manifests/module/headers.pp5
-rw-r--r--puppet/modules/site_apache/manifests/module/removeip.pp5
-rw-r--r--puppet/modules/site_apache/manifests/module/rewrite.pp5
-rw-r--r--puppet/modules/site_apache/templates/vhosts.d/api.conf.erb19
-rw-r--r--puppet/modules/site_apache/templates/vhosts.d/common.conf.erb73
-rw-r--r--puppet/modules/site_apache/templates/vhosts.d/leap_webapp.conf.erb46
-rw-r--r--puppet/modules/site_apt/files/keys/cloudant-key.asc52
-rw-r--r--puppet/modules/site_apt/files/keys/leap_key.asc18
-rw-r--r--puppet/modules/site_apt/manifests/init.pp13
-rw-r--r--puppet/modules/site_apt/manifests/preferences/check_mk.pp9
-rw-r--r--puppet/modules/site_apt/manifests/preferences/twisted.pp9
-rw-r--r--puppet/modules/site_apt/templates/wheezy/postfix.seeds1
-rw-r--r--puppet/modules/site_check_mk/files/agent/local_checks/all_hosts/run_node_tests.sh5
-rwxr-xr-xpuppet/modules/site_check_mk/files/agent/local_checks/mx/check_leap_mx.sh33
-rw-r--r--puppet/modules/site_check_mk/files/agent/logwatch/bigcouch.cfg20
-rw-r--r--puppet/modules/site_check_mk/files/agent/logwatch/leap_mx.cfg4
-rw-r--r--puppet/modules/site_check_mk/files/agent/logwatch/logwatch.cfg31
-rw-r--r--puppet/modules/site_check_mk/files/agent/logwatch/soledad.cfg5
-rw-r--r--puppet/modules/site_check_mk/files/agent/logwatch/syslog/couchdb.cfg7
-rw-r--r--puppet/modules/site_check_mk/files/agent/logwatch/syslog/openvpn.cfg7
-rw-r--r--puppet/modules/site_check_mk/files/agent/logwatch/syslog/stunnel.cfg9
-rw-r--r--puppet/modules/site_check_mk/files/agent/logwatch/syslog/tapicero.cfg8
-rw-r--r--puppet/modules/site_check_mk/files/agent/logwatch/syslog/webapp.cfg5
-rw-r--r--puppet/modules/site_check_mk/files/agent/logwatch/syslog_header.cfg1
-rw-r--r--puppet/modules/site_check_mk/files/agent/logwatch/syslog_tail.cfg11
-rwxr-xr-xpuppet/modules/site_check_mk/files/agent/nagios_plugins/check_unix_open_fds.pl322
-rwxr-xr-xpuppet/modules/site_check_mk/files/agent/plugins/mk_logwatch.1.2.4374
-rw-r--r--puppet/modules/site_check_mk/manifests/agent.pp28
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/couchdb.pp36
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/haproxy.pp12
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/logwatch.pp36
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/logwatch/syslog.pp18
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/mrpe.pp18
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/mx.pp23
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/openvpn.pp10
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/package/nagios_plugins_contrib.pp5
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/package/perl_plugin.pp5
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/soledad.pp14
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/stunnel.pp9
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/tapicero.pp16
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/webapp.pp26
-rw-r--r--puppet/modules/site_check_mk/manifests/server.pp64
-rw-r--r--puppet/modules/site_check_mk/templates/use_ssh.mk6
-rw-r--r--puppet/modules/site_config/manifests/caching_resolver.pp1
-rw-r--r--puppet/modules/site_config/manifests/default.pp37
-rw-r--r--puppet/modules/site_config/manifests/files.pp23
-rw-r--r--puppet/modules/site_config/manifests/hosts.pp3
-rw-r--r--puppet/modules/site_config/manifests/initial_firewall.pp62
-rw-r--r--puppet/modules/site_config/manifests/packages/base.pp (renamed from puppet/modules/site_config/manifests/base_packages.pp)18
-rw-r--r--puppet/modules/site_config/manifests/packages/build_essential.pp11
-rw-r--r--puppet/modules/site_config/manifests/packages/gnutls.pp5
-rw-r--r--puppet/modules/site_config/manifests/packages/uninstall.pp16
-rw-r--r--puppet/modules/site_config/manifests/params.pp16
-rw-r--r--puppet/modules/site_config/manifests/resolvconf.pp9
-rw-r--r--puppet/modules/site_config/manifests/ruby/dev.pp8
-rw-r--r--puppet/modules/site_config/manifests/setup.pp50
-rw-r--r--puppet/modules/site_config/manifests/sysctl.pp8
-rw-r--r--puppet/modules/site_config/manifests/syslog.pp28
-rw-r--r--puppet/modules/site_config/manifests/vagrant.pp11
-rw-r--r--puppet/modules/site_config/manifests/x509/ca.pp9
-rw-r--r--puppet/modules/site_config/manifests/x509/ca_bundle.pp16
-rw-r--r--puppet/modules/site_config/manifests/x509/cert.pp10
-rw-r--r--puppet/modules/site_config/manifests/x509/client_ca/ca.pp14
-rw-r--r--puppet/modules/site_config/manifests/x509/client_ca/key.pp14
-rw-r--r--puppet/modules/site_config/manifests/x509/commercial/ca.pp9
-rw-r--r--puppet/modules/site_config/manifests/x509/commercial/cert.pp10
-rw-r--r--puppet/modules/site_config/manifests/x509/commercial/key.pp9
-rw-r--r--puppet/modules/site_config/manifests/x509/key.pp9
-rw-r--r--puppet/modules/site_config/templates/hosts6
-rw-r--r--puppet/modules/site_config/templates/ipv4firewall_up.rules.erb22
-rw-r--r--puppet/modules/site_config/templates/ipv6firewall_up.rules.erb7
-rw-r--r--puppet/modules/site_couchdb/files/couchdb_scripts_defaults.conf4
-rw-r--r--puppet/modules/site_couchdb/files/designs/Readme.md14
-rw-r--r--puppet/modules/site_couchdb/files/designs/customers/Customer.json18
-rw-r--r--puppet/modules/site_couchdb/files/designs/identities/Identity.json28
-rw-r--r--puppet/modules/site_couchdb/files/designs/messages/Message.json18
-rw-r--r--puppet/modules/site_couchdb/files/designs/sessions/Session.json8
-rw-r--r--puppet/modules/site_couchdb/files/designs/shared/docs.json8
-rw-r--r--puppet/modules/site_couchdb/files/designs/shared/syncs.json11
-rw-r--r--puppet/modules/site_couchdb/files/designs/shared/transactions.json13
-rw-r--r--puppet/modules/site_couchdb/files/designs/tickets/Ticket.json50
-rw-r--r--puppet/modules/site_couchdb/files/designs/tokens/Token.json14
-rw-r--r--puppet/modules/site_couchdb/files/designs/users/User.json22
-rw-r--r--puppet/modules/site_couchdb/manifests/add_users.pp54
-rw-r--r--puppet/modules/site_couchdb/manifests/backup.pp23
-rw-r--r--puppet/modules/site_couchdb/manifests/bigcouch/add_nodes.pp5
-rw-r--r--puppet/modules/site_couchdb/manifests/bigcouch/compaction.pp8
-rw-r--r--puppet/modules/site_couchdb/manifests/bigcouch/settle_cluster.pp11
-rw-r--r--puppet/modules/site_couchdb/manifests/create_dbs.pp70
-rw-r--r--puppet/modules/site_couchdb/manifests/designs.pp20
-rw-r--r--puppet/modules/site_couchdb/manifests/init.pp155
-rw-r--r--puppet/modules/site_couchdb/manifests/logrotate.pp12
-rw-r--r--puppet/modules/site_couchdb/manifests/stunnel.pp46
-rw-r--r--puppet/modules/site_haproxy/files/haproxy-stats.cfg6
-rw-r--r--puppet/modules/site_haproxy/manifests/init.pp8
-rw-r--r--puppet/modules/site_mx/manifests/couchdb.pp23
-rw-r--r--puppet/modules/site_mx/manifests/haproxy.pp14
-rw-r--r--puppet/modules/site_mx/manifests/init.pp19
-rw-r--r--puppet/modules/site_nagios/files/configs/Debian/nagios.cfg91
-rw-r--r--puppet/modules/site_nagios/manifests/add_host.pp31
-rw-r--r--puppet/modules/site_nagios/manifests/add_host_services.pp28
-rw-r--r--puppet/modules/site_nagios/manifests/add_service.pp26
-rw-r--r--puppet/modules/site_nagios/manifests/init.pp2
-rw-r--r--puppet/modules/site_nagios/manifests/server.pp40
-rw-r--r--puppet/modules/site_nagios/manifests/server/apache.pp7
-rw-r--r--puppet/modules/site_nagios/manifests/server/purge.pp20
-rw-r--r--puppet/modules/site_nickserver/manifests/init.pp89
-rw-r--r--puppet/modules/site_nickserver/templates/nickserver-proxy.conf.erb6
-rw-r--r--puppet/modules/site_nickserver/templates/nickserver.yml.erb2
-rw-r--r--puppet/modules/site_openvpn/manifests/dh_key.pp10
-rw-r--r--puppet/modules/site_openvpn/manifests/init.pp78
-rw-r--r--puppet/modules/site_openvpn/manifests/keys.pp51
-rw-r--r--puppet/modules/site_openvpn/manifests/resolver.pp10
-rw-r--r--puppet/modules/site_openvpn/manifests/server_config.pp70
-rw-r--r--puppet/modules/site_openvpn/templates/add_gateway_ips.sh.erb8
-rw-r--r--puppet/modules/site_postfix/files/checks/received_anon2
-rw-r--r--puppet/modules/site_postfix/manifests/debug.pp9
-rw-r--r--puppet/modules/site_postfix/manifests/mx.pp74
-rw-r--r--puppet/modules/site_postfix/manifests/mx/checks.pp41
-rw-r--r--puppet/modules/site_postfix/manifests/mx/reserved_aliases.pp15
-rw-r--r--puppet/modules/site_postfix/manifests/mx/smtp_auth.pp6
-rw-r--r--puppet/modules/site_postfix/manifests/mx/smtp_tls.pp27
-rw-r--r--puppet/modules/site_postfix/manifests/mx/smtpd_checks.pp31
-rw-r--r--puppet/modules/site_postfix/manifests/mx/smtpd_tls.pp55
-rw-r--r--puppet/modules/site_postfix/manifests/satellite.pp47
-rw-r--r--puppet/modules/site_postfix/templates/checks/helo_access.erb21
-rw-r--r--puppet/modules/site_shorewall/manifests/defaults.pp34
-rw-r--r--puppet/modules/site_shorewall/manifests/mx.pp24
-rw-r--r--puppet/modules/site_shorewall/manifests/service/smtp.pp13
-rw-r--r--puppet/modules/site_shorewall/manifests/soledad.pp23
-rw-r--r--puppet/modules/site_shorewall/manifests/sshd.pp6
-rw-r--r--puppet/modules/site_squid_deb_proxy/manifests/client.pp5
-rw-r--r--puppet/modules/site_sshd/manifests/authorized_keys.pp3
-rw-r--r--puppet/modules/site_sshd/manifests/init.pp18
-rw-r--r--puppet/modules/site_sshd/templates/authorized_keys.erb4
-rw-r--r--puppet/modules/site_sshd/templates/ssh_config.erb23
-rw-r--r--puppet/modules/site_sshd/templates/ssh_known_hosts.erb7
-rw-r--r--puppet/modules/site_static/README3
-rw-r--r--puppet/modules/site_static/manifests/domain.pp28
-rw-r--r--puppet/modules/site_static/manifests/init.pp17
-rw-r--r--puppet/modules/site_static/manifests/location.pp25
-rw-r--r--puppet/modules/site_static/templates/apache.conf.erb77
-rw-r--r--puppet/modules/site_stunnel/manifests/clients.pp9
-rw-r--r--puppet/modules/site_stunnel/manifests/setup.pp24
-rw-r--r--puppet/modules/site_tor/manifests/init.pp20
-rw-r--r--puppet/modules/site_webapp/files/migrate_design_documents16
-rw-r--r--puppet/modules/site_webapp/manifests/apache.pp55
-rw-r--r--puppet/modules/site_webapp/manifests/client_ca.pp25
-rw-r--r--puppet/modules/site_webapp/manifests/couchdb.pp53
-rw-r--r--puppet/modules/site_webapp/manifests/cron.pp17
-rw-r--r--puppet/modules/site_webapp/manifests/haproxy.pp1
-rw-r--r--puppet/modules/site_webapp/manifests/init.pp99
-rw-r--r--puppet/modules/site_webapp/templates/config.yml.erb8
-rw-r--r--puppet/modules/site_webapp/templates/couchdb.yml.admin.erb9
-rw-r--r--puppet/modules/site_webapp/templates/haproxy_couchdb.cfg.erb25
-rw-r--r--puppet/modules/soledad/manifests/common.pp10
-rw-r--r--puppet/modules/soledad/manifests/init.pp29
-rw-r--r--puppet/modules/soledad/manifests/server.pp63
-rw-r--r--puppet/modules/soledad/templates/default-soledad.erb5
-rw-r--r--puppet/modules/soledad/templates/soledad-server.conf.erb3
m---------puppet/modules/squid_deb_proxy0
m---------puppet/modules/sshd0
m---------puppet/modules/stdlib0
m---------puppet/modules/stunnel0
m---------puppet/modules/sysctl0
-rwxr-xr-xpuppet/modules/tapicero/files/tapicero.init60
-rw-r--r--puppet/modules/tapicero/manifests/init.pp123
-rw-r--r--puppet/modules/tapicero/templates/tapicero.yaml.erb42
m---------puppet/modules/tor0
-rw-r--r--puppet/modules/try/manifests/file.pp108
m---------puppet/modules/vcsrepo0
185 files changed, 3972 insertions, 752 deletions
diff --git a/puppet/modules/apt b/puppet/modules/apt
-Subproject 1a72a99693c1d77bfe891546408f88264fca98e
+Subproject 64fb988c0e37d64fb3e241dc95f156072e43bf2
diff --git a/puppet/modules/backupninja b/puppet/modules/backupninja
new file mode 160000
+Subproject daeb1a1f112a4dbf6b39565f0dea461e46a6468
diff --git a/puppet/modules/check_mk b/puppet/modules/check_mk
new file mode 160000
+Subproject 5c11597a055858b5ddc1ce8f7f8db249f5f1b33
diff --git a/puppet/modules/couchdb b/puppet/modules/couchdb
-Subproject 20deb0652ccfe105eddec6ba2ad32b8d633705f
+Subproject c8f5443e0998d3d3d43505ff5a6fdf8c438d6c2
diff --git a/puppet/modules/git b/puppet/modules/git
-Subproject 497a1034489e0dc3cab5dab2fb0a85778576973
+Subproject ba5dd8d5c8e09d521ff49f1ebc753601e449f82
diff --git a/puppet/modules/leap_mx/manifests/init.pp b/puppet/modules/leap_mx/manifests/init.pp
new file mode 100644
index 00000000..b59eac01
--- /dev/null
+++ b/puppet/modules/leap_mx/manifests/init.pp
@@ -0,0 +1,62 @@
+class leap_mx {
+
+ $leap_mx = hiera('couchdb_leap_mx_user')
+ $couchdb_user = $leap_mx['username']
+ $couchdb_password = $leap_mx['password']
+
+ $couchdb_host = 'localhost'
+ $couchdb_port = '4096'
+
+ include soledad::common
+ include site_apt::preferences::twisted
+
+ #
+ # USER AND GROUP
+ #
+
+ group { 'leap-mx':
+ ensure => present,
+ allowdupe => false;
+ }
+
+ user { 'leap-mx':
+ ensure => present,
+ allowdupe => false,
+ gid => 'leap-mx',
+ home => '/etc/leap',
+ require => Group['leap-mx'];
+ }
+
+ #
+ # LEAP-MX CONFIG
+ #
+
+ file { '/etc/leap/mx.conf':
+ content => template('leap_mx/mx.conf.erb'),
+ owner => 'leap-mx',
+ group => 'leap-mx',
+ mode => '0600',
+ notify => Service['leap-mx'];
+ }
+
+ #
+ # LEAP-MX CODE
+ #
+
+ package { 'leap-mx':
+ ensure => installed,
+ require => Class['site_apt::preferences::twisted']
+ }
+
+ #
+ # LEAP-MX DAEMON
+ #
+
+ service { 'leap-mx':
+ ensure => running,
+ enable => true,
+ hasstatus => true,
+ hasrestart => true,
+ require => [ Package['leap-mx'] ];
+ }
+}
diff --git a/puppet/modules/leap_mx/templates/mx.conf.erb b/puppet/modules/leap_mx/templates/mx.conf.erb
new file mode 100644
index 00000000..e05bc150
--- /dev/null
+++ b/puppet/modules/leap_mx/templates/mx.conf.erb
@@ -0,0 +1,15 @@
+[mail1]
+path=/var/mail/vmail/Maildir
+recursive=True
+
+[couchdb]
+user=<%= @couchdb_user %>
+password=<%= @couchdb_password %>
+server=<%= @couchdb_host %>
+port=<%= @couchdb_port %>
+
+[alias map]
+port=4242
+
+[check recipient]
+port=2244
diff --git a/puppet/modules/postfix b/puppet/modules/postfix
new file mode 160000
+Subproject 1103a73ab4253712c6446bba7a443619fe51671
diff --git a/puppet/modules/rsyslog b/puppet/modules/rsyslog
new file mode 160000
+Subproject 20fbda6b91472e656331a9c64630fb207e9f578
diff --git a/puppet/modules/rubygems b/puppet/modules/rubygems
-Subproject 1e5ed3dbef9381bb9d5e2a7b4957bb3f5288d6a
+Subproject ef820cfec3321d17be99ef814318adb4e3cc1e9
diff --git a/puppet/modules/site_apache/files/conf.d/security b/puppet/modules/site_apache/files/conf.d/security
new file mode 100644
index 00000000..a5ae5bdc
--- /dev/null
+++ b/puppet/modules/site_apache/files/conf.d/security
@@ -0,0 +1,55 @@
+#
+# 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.
+#
+#<Directory />
+# AllowOverride None
+# Order Deny,Allow
+# Deny from all
+#</Directory>
+
+
+# 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 Prod
+
+#
+# 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 Off
+
+#
+# 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
+
+# Setting this header will prevent other sites from embedding pages from this
+# site as frames. This defends against clickjacking attacks.
+# Requires mod_headers to be enabled.
+#
+Header set X-Frame-Options: "DENY"
diff --git a/puppet/modules/site_apache/manifests/common.pp b/puppet/modules/site_apache/manifests/common.pp
new file mode 100644
index 00000000..72f24838
--- /dev/null
+++ b/puppet/modules/site_apache/manifests/common.pp
@@ -0,0 +1,26 @@
+class site_apache::common {
+ # installs x509 cert + key and common config
+ # that both nagios + leap webapp use
+
+ $web_domain = hiera('domain')
+ $domain_name = $web_domain['name']
+
+ include x509::variables
+ include site_config::x509::commercial::cert
+ include site_config::x509::commercial::key
+ include site_config::x509::commercial::ca
+
+ Class['Site_config::X509::Commercial::Key'] ~> Service[apache]
+ Class['Site_config::X509::Commercial::Cert'] ~> Service[apache]
+ Class['Site_config::X509::Commercial::Ca'] ~> Service[apache]
+
+ include site_apache::module::rewrite
+
+ class { '::apache': no_default_site => true, ssl => true }
+
+ apache::vhost::file {
+ 'common':
+ content => template('site_apache/vhosts.d/common.conf.erb')
+ }
+
+}
diff --git a/puppet/modules/site_apache/manifests/module/alias.pp b/puppet/modules/site_apache/manifests/module/alias.pp
new file mode 100644
index 00000000..c1f5e185
--- /dev/null
+++ b/puppet/modules/site_apache/manifests/module/alias.pp
@@ -0,0 +1,5 @@
+class site_apache::module::alias ( $ensure = present )
+{
+
+ apache::module { 'alias': ensure => $ensure }
+}
diff --git a/puppet/modules/site_apache/manifests/module/expires.pp b/puppet/modules/site_apache/manifests/module/expires.pp
new file mode 100644
index 00000000..f73a5607
--- /dev/null
+++ b/puppet/modules/site_apache/manifests/module/expires.pp
@@ -0,0 +1,4 @@
+class site_apache::module::expires ( $ensure = present )
+{
+ apache::module { 'expires': ensure => $ensure }
+}
diff --git a/puppet/modules/site_apache/manifests/module/headers.pp b/puppet/modules/site_apache/manifests/module/headers.pp
new file mode 100644
index 00000000..f7caa28c
--- /dev/null
+++ b/puppet/modules/site_apache/manifests/module/headers.pp
@@ -0,0 +1,5 @@
+class site_apache::module::headers ( $ensure = present )
+{
+
+ apache::module {'headers': ensure => $ensure }
+}
diff --git a/puppet/modules/site_apache/manifests/module/removeip.pp b/puppet/modules/site_apache/manifests/module/removeip.pp
new file mode 100644
index 00000000..f106167a
--- /dev/null
+++ b/puppet/modules/site_apache/manifests/module/removeip.pp
@@ -0,0 +1,5 @@
+class site_apache::module::removeip ( $ensure = present )
+{
+ package { 'libapache2-mod-removeip': ensure => $ensure }
+ apache::module { 'removeip': ensure => $ensure }
+}
diff --git a/puppet/modules/site_apache/manifests/module/rewrite.pp b/puppet/modules/site_apache/manifests/module/rewrite.pp
new file mode 100644
index 00000000..7ad00a0c
--- /dev/null
+++ b/puppet/modules/site_apache/manifests/module/rewrite.pp
@@ -0,0 +1,5 @@
+class site_apache::module::rewrite ( $ensure = present )
+{
+
+ apache::module { 'rewrite': ensure => $ensure }
+}
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 ae894cd4..3360ac59 100644
--- a/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb
+++ b/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb
@@ -10,17 +10,26 @@ Listen 0.0.0.0:<%= api_port %>
ServerName <%= api_domain %>
SSLEngine on
- SSLProtocol -all +SSLv3 +TLSv1
- SSLCipherSuite HIGH:MEDIUM:!aNULL:!SSLv2:!MD5:@STRENGTH
+ SSLProtocol all -SSLv2
SSLHonorCipherOrder on
+ SSLCompression off
+ SSLCipherSuite "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK"
SSLCACertificatePath /etc/ssl/certs
- SSLCertificateChainFile /etc/ssl/certs/leap_api.pem
- SSLCertificateKeyFile /etc/x509/keys/leap_api.key
- SSLCertificateFile /etc/x509/certs/leap_api.crt
+ SSLCertificateChainFile <%= scope.lookupvar('x509::variables::local_CAs') %>/<%= scope.lookupvar('site_config::params::ca_name') %>.crt
+ SSLCertificateKeyFile <%= scope.lookupvar('x509::variables::keys') %>/<%= scope.lookupvar('site_config::params::cert_name') %>.key
+ SSLCertificateFile <%= scope.lookupvar('x509::variables::certs') %>/<%= scope.lookupvar('site_config::params::cert_name') %>.crt
RequestHeader set X_FORWARDED_PROTO 'https'
+ <IfModule mod_headers.c>
+<% if @webapp['secure'] -%>
+ Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
+<% end -%>
+ Header always unset X-Powered-By
+ Header always unset X-Runtime
+ </IfModule>
+
DocumentRoot /srv/leap/webapp/public
# Check for maintenance file and redirect all requests
diff --git a/puppet/modules/site_apache/templates/vhosts.d/common.conf.erb b/puppet/modules/site_apache/templates/vhosts.d/common.conf.erb
new file mode 100644
index 00000000..ed430510
--- /dev/null
+++ b/puppet/modules/site_apache/templates/vhosts.d/common.conf.erb
@@ -0,0 +1,73 @@
+<VirtualHost *:80>
+ ServerName <%= domain %>
+ ServerAlias www.<%= domain %>
+ RewriteEngine On
+ RewriteRule ^.*$ https://<%= domain -%>%{REQUEST_URI} [R=permanent,L]
+</VirtualHost>
+
+<VirtualHost *:443>
+ ServerName <%= domain_name %>
+ ServerAlias <%= domain %>
+ ServerAlias www.<%= domain %>
+
+ SSLEngine on
+ SSLProtocol all -SSLv2
+ SSLHonorCipherOrder on
+ SSLCompression off
+ SSLCipherSuite "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK"
+
+ SSLCACertificatePath /etc/ssl/certs
+ SSLCertificateChainFile <%= scope.lookupvar('x509::variables::local_CAs') %>/<%= scope.lookupvar('site_config::params::commercial_ca_name') %>.crt
+ SSLCertificateKeyFile <%= scope.lookupvar('x509::variables::keys') %>/<%= scope.lookupvar('site_config::params::commercial_cert_name') %>.key
+ SSLCertificateFile <%= scope.lookupvar('x509::variables::certs') %>/<%= scope.lookupvar('site_config::params::commercial_cert_name') %>.crt
+
+ RequestHeader set X_FORWARDED_PROTO 'https'
+
+ <IfModule mod_headers.c>
+<% if (defined? @services) and (@services.include? 'webapp') and (@webapp['secure']) -%>
+ Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
+<% end -%>
+ Header always unset X-Powered-By
+ Header always unset X-Runtime
+ </IfModule>
+
+<% if (defined? @services) and (@services.include? 'webapp') -%>
+ DocumentRoot /srv/leap/webapp/public
+
+ RewriteEngine On
+ # Check for maintenance file and redirect all requests
+ RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
+ RewriteCond %{SCRIPT_FILENAME} !maintenance.html
+ RewriteCond %{REQUEST_URI} !/images/maintenance.jpg
+ RewriteRule ^.*$ %{DOCUMENT_ROOT}/system/maintenance.html [L]
+
+ # http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengerallowencodedslashes_lt_on_off_gt
+ AllowEncodedSlashes on
+ PassengerAllowEncodedSlashes on
+ PassengerFriendlyErrorPages off
+ SetEnv TMPDIR /var/tmp
+
+ # Allow rails assets to be cached for a very long time (since the URLs change whenever the content changes)
+ <Location /assets/>
+ Header unset ETag
+ FileETag None
+ ExpiresActive On
+ ExpiresDefault "access plus 1 year"
+ </Location>
+<% end -%>
+
+
+<% if (defined? @services) and (@services.include? 'monitor') -%>
+ <DirectoryMatch (/usr/share/nagios3/htdocs|/usr/lib/cgi-bin/nagios3|/etc/nagios3/stylesheets)>
+ <% if (defined? @services) and (@services.include? 'webapp') -%>
+ PassengerEnabled off
+ <% end -%>
+ AllowOverride all
+ # Nagios won't work with setting this option to "DENY",
+ # as set in conf.d/security (#4169). Therefor we allow
+ # it here, only for nagios.
+ Header set X-Frame-Options: "ALLOW"
+ </DirectoryMatch>
+<% end -%>
+</VirtualHost>
+
diff --git a/puppet/modules/site_apache/templates/vhosts.d/leap_webapp.conf.erb b/puppet/modules/site_apache/templates/vhosts.d/leap_webapp.conf.erb
deleted file mode 100644
index 4b051699..00000000
--- a/puppet/modules/site_apache/templates/vhosts.d/leap_webapp.conf.erb
+++ /dev/null
@@ -1,46 +0,0 @@
-<VirtualHost *:80>
- ServerName <%= domain %>
- ServerAlias www.<%= domain %>
- RewriteEngine On
- RewriteRule ^.*$ https://<%= domain -%>%{REQUEST_URI} [R=permanent,L]
-</VirtualHost>
-
-<VirtualHost *:443>
- ServerName <%= domain %>
- ServerAlias www.<%= domain %>
-
- SSLEngine on
- SSLProtocol -all +SSLv3 +TLSv1
- SSLCipherSuite HIGH:MEDIUM:!aNULL:!SSLv2:!MD5:@STRENGTH
- SSLHonorCipherOrder on
-
- SSLCACertificatePath /etc/ssl/certs
- SSLCertificateChainFile /etc/ssl/certs/leap_webapp.pem
- SSLCertificateKeyFile /etc/x509/keys/leap_webapp.key
- SSLCertificateFile /etc/x509/certs/leap_webapp.crt
-
- RequestHeader set X_FORWARDED_PROTO 'https'
-
- DocumentRoot /srv/leap/webapp/public
-
- RewriteEngine On
- # Check for maintenance file and redirect all requests
- RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
- RewriteCond %{SCRIPT_FILENAME} !maintenance.html
- RewriteCond %{REQUEST_URI} !/images/maintenance.jpg
- RewriteRule ^.*$ %{DOCUMENT_ROOT}/system/maintenance.html [L]
-
- # http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengerallowencodedslashes_lt_on_off_gt
- AllowEncodedSlashes on
- PassengerAllowEncodedSlashes on
- PassengerFriendlyErrorPages off
- SetEnv TMPDIR /var/tmp
-
- <% if (defined? @services) and (@services.include? 'monitor') -%>
- <DirectoryMatch (/usr/share/nagios3/htdocs|/usr/lib/cgi-bin/nagios3|/etc/nagios3/stylesheets)>
- PassengerEnabled off
- AllowOverride all
- </DirectoryMatch>
- <% end -%>
-</VirtualHost>
-
diff --git a/puppet/modules/site_apt/files/keys/cloudant-key.asc b/puppet/modules/site_apt/files/keys/cloudant-key.asc
deleted file mode 100644
index 99716a3c..00000000
--- a/puppet/modules/site_apt/files/keys/cloudant-key.asc
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.4.11 (GNU/Linux)
-
-mQINBFE7fhIBEACrDREcODnhdugNozMeBawOm2irpNCP54yMljST/DOXx1uo3gQw
-HnVcQ4lL7lXhbfL6Tp0WhrNYTWbbWHO0DaQbW0GQMHa2BGG0Xm0HPrjr3j55tAcM
-NPr0ArDuplq4Py2pwviZiEtQkkn+biH9oV+N3jNO+8+zVHLVU7pHaX6Yd7HAxFM8
-XX+7SeVtplZ7nvSxUREiMNxQb9o0kYNRPS+b0UjiIXHrFO9afl7lTdg/I8AhKWa0
-3jJoY/IRvVopJblISQNGFipR11Lpu5sOHghgz4V8mk/in7JLMmoqSl5DP5VhRII8
-OyADBjaUJD2mkv5cGaevqpB4AId78X9+Y62gFJrGkIHY9uBxIUkRe+leYI4Zz4Bm
-D9qBIbEY/kKkblTlC1G7u3qbGQcsbCRVIOnhruCih7vifcP40YwGUk5NmDA5AE78
-OovCGYGp4zMepDTSJxGT3sJOTEbzN09so6C7fQWBeQiiG5Uepp1q+VnaGpT1L4rc
-Y6yRbu9dOFj6WzY4W5HtnbalzTIEYy+SIGZqRkJt6jREYLiFfyrpSFIgGoJAs0yx
-9M0McXfeOod69TPufB1PeppnBwFcTmYNYxakusQxAebRDPEBZqoEgl0gMmxWbAdI
-nxGMWWnSsN/Dj0dXRf1MG/5akOhX2zQcUzBOE2m/Xr5kjDPYFtFxVJDGzQARAQAB
-tDNDbG91ZGFudCBQYWNrYWdlIFNpZ25pbmcgS2V5IDxzdXBwb3J0QGNsb3VkYW50
-LmNvbT6JAj4EEwECACgFAlE7fhICGwMFCQHhM4AGCwkIBwMCBhUIAgkKCwQWAgMB
-Ah4BAheAAAoJEFngH70Vvo4mciIP/AlqHA/LDtSYfrFwdXifY2ImCMyzYvH40Ko2
-DHCw2qDjvK5UXn1iWuzXidT7DrxOfYoZpzySRP7VGyHxa3VPhOtzLDZSvTpk9ELo
-2x2IczUwLC17M0Iis4CpqlxSFIBYGX78pMzvsEyC4TFqUDfXRlye3apjD0iwK0hE
-kdP1+TPdJjhWImJm+3TLu45zTw3Ph5dnf5pLQPNhKfBSdku+vRrd35N5hHso9S1y
-Z3NrxcQlWnXuqkLIA14gM7qbBFD+el9Y+tZ7ERGYg3s5uNDQRTb0QC8zg/um2+zW
-4hHmuRcWY3n8IgHcYUruC1VyrrsFIWWMyLv7SZkAAoSY+jKyESDfYpJQ8jtZ4EF9
-2/gYm4FgZR8j4gWkzHSLGVt/4EIykJZb0yIg/QEovmmHqpy8xYri3goMSl4h7tfF
-TOCZLTzTyQ7xONdyEsrvQPhmdtXEgvSo5S7ZU9kkx32OjCoshLLjhtqAipBgEXqb
-hElFo1oSyOVoGc7UNh7KNBjWfeP8dNdCbIbIYPMeM0/CVjD60kW5ZEVDuYglT+Rz
-enJJvS4Hs+fq8cFNxMB+l64qE7iS+I6RP2bPeQM2aBa2UZNWxUIbXF7bb3zLrCGn
-GT8GF1AFRoW3GiDzB7QnLVp8BhIaqFUzbDim+5mFFG8wguxHTiz4snDdQXq2Es6V
-UETFsNsluQINBFE7fhIBEADIyLHyBh8AKJKQHksFAPHOyA48ocxgQDpQnqYlQcAK
-D8eUbRXciIz4ePBmvjaQmz8wJgWULc04u4i9jK8Jd/Ks+VhEz3AjRBfjvkBaVMog
-FMPKaoDn9LVMBSZJ3fcC1DVck1oO8LnFIdktt0zhvzG+pV5b/UTRsVZmwNh1p2dM
-4cJswxlksJXYnI9tFA74qiomDCPYM0zpv7TEjX23PZTLqTSHP5aWctx+MIEtdoqp
-EsEDL6npvYBRz/tuL41cUWs7CItH131Hyuizo4vGrxgWPnoXIxLmLOOZCMk/kbx0
-XCSvengqYwNgAOlIjewtTw+WJm1gtNQQeKmaXBX7njf2Wz7LI/0KVxttEpKT5/5y
-embOGn7My9i7zOc1frMCDivIOTQDBZTzR9o7/6wUJ69DIoFLMlO8UcCK3R7o5VUI
-ezx+XYsOAD7D2vKoiD8Se65Vnax2rfFlLP7OQqdem5l2lkHpJzP3lA8qmA2MfJ7V
-jsk7eDSyJQjG5c6KBoaFlYGhp/E2kR82cAKVaFIbW3euMM4XK6Mgzy3+DVKfk8mu
-AEuHub7plfxM+65yjLNAK6l6IKtY1HfM7F4GFyNSd3mNNcWN7ceIHh8Ur4DeD2Tp
-7r3XcWd6/czLYNsw2BAHeVUxnMTCeGN99UZTtHgVq9IJMOCDOPwMSzHFfZ6sNaYL
-qQARAQABiQIlBBgBAgAPBQJRO34SAhsMBQkB4TOAAAoJEFngH70Vvo4mpokP/jJJ
-2mXdhMVqZCtZhwphJfdxg8nBERzrd6ebXxKbTq1MmSN/fDwLknPabFHUpzk1ADCf
-6mh2o0HB+67yMzo1UVtyfPOaHgCE/pWer5ultJM8gOdpBfSWL8jRwU8ZQ4fDu3z8
-AC6zTNq7znOVLEzZPy8U7q5Rt5/6QdQYoTLe6DwlLmkflzWP5VWi/mTGvtu/t5OV
-tGZkzBYQ5QAXRXXkKswqkJpQFuW6d1vlYm9+x/+Q1+2kGT+CKbRAkqkf77qVcyJR
-1M2JQSs4ko+rLMZzr01sYA+EBD17nxqV8vUdYebNc9Qnk8Aphid1zarUbySgAdnJ
-5SLAjLe/6N6IEE9F3uKsPEs87gJrnwrYHRrmu0wAPwA0cMmtgD4Bz7Iiz4CLYPFW
-rHpQCA313K+rS/LLfLBL66wIRKcPuYIFR9N03jX9eGR6qtk0b5Zb3YjWOo4V9Q1r
-o+g6IB0Us5vH6ISuokq7Bv+8cXhEMVoctL9A8xWN1KDkweZ+7dNWCGV8lUWKy3Hw
-ig6hENH6H7J57U8H2v2aZTeUo6e7VDP9gddNKPSEEeoBKfVnWYGoG8mVPQ2PzTgZ
-ZO2vwp4c3Ix/kIV3xe+/Opcq1lxYhD7HSre1MB7HOeFmis6tBBjMJPaatZVfzj1v
-6Uhz5oUCwcPol8rsp69DvGVUPSHfDwBxurDX71oG
-=lEm7
------END PGP PUBLIC KEY BLOCK-----
diff --git a/puppet/modules/site_apt/files/keys/leap_key.asc b/puppet/modules/site_apt/files/keys/leap_key.asc
index b69251f0..b6b5077b 100644
--- a/puppet/modules/site_apt/files/keys/leap_key.asc
+++ b/puppet/modules/site_apt/files/keys/leap_key.asc
@@ -1,5 +1,5 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.4.11 (GNU/Linux)
+Version: GnuPG v1.4.14 (GNU/Linux)
mQINBFESwt0BEAC2CR+XgW04DVwT427v2T4+qz+O/xGOwQcalVaSOUuguYgf29en
Apb6mUqROOTuJWN1nw1lvXiA6iFxg6DjDUhsp6j54X7GAAAjZ9QuavPgcsractsJ
@@ -36,7 +36,19 @@ y9k8peFB7wwf0sW3Eg78XFsfy4gyV619VnBR+PbfOpKqFFXAodF1mFiIrPeefaVp
F9fiQ5Owt0sJjDaJnYT83ksAO2Aj+VsY3UjnDrGFaiV8Neit9y/8W8DqmZ3EZEF/
M3iS0yDjqqt9ACFD+jkGlKYsyHv7gbpTq0yi6u/kRXHUTIvVwFL9M6Z6AUcG8gzo
qbKhXGfWKEq0lN5HAjJ//V9ro3DekFd0A+NQOlFV6XtspZwphVdtW1WS078HmVlw
-F5dbD8pcfT/RjbkCDQRREsLdARAA3Frw+j6H9McEIi/gjiGwvxnIdGc8McWchnFp
+F5dbD8pcfT/RjYkCPQQTAQoAJwIbAwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAUC
+UvT9ZgUJA8NuBQAKCRAeNKGCjiB5AXB+D/9k/BzZdAczQ3/v7hKrN9y3/D8kOEYK
+rF8HdcBOH522sN6mqvm7wGkf3RmNSi731m6vzlbBSonrAT5KDMpj+THOmUcY29V5
+a1YOgFCCkToOfl+LmlLiuqfrGCJyE28MKMrsi2zMBKhsSxhvcI0EhJkQpPBu8gUs
+XW1GSHuh5CYzwf/i8eNDpVrhHjRF0AVCOWIq52LTR62QchR+6ci/wVDHWd9Ase5X
+8rxNnt2/pCbgATklQbmRcQS6efTVk3oXk1DZ8M46vayJ1g2BFuIi7pohiekLAAAt
+MCwRKHTHvtPkGAUAEXExPGS78qHxLHIau2VCtSBxm+bQX+ZyCMANDpI+ZTFp1APJ
+9SpbtGozuQOpWFjWY1rERunrbyWHIb2DuVVNKGiHlkMJB76zzysvbIPYWx1RqD6s
+KFJBkjrM0xn8H+D6qzwzGfmX1Yaw12oYA6pcai4aK5sO7KHt+THAxYAcVF7qxGU7
+lnDifM56hrH/DbE5InlDC8OUqDysj0cHacRee+ZYtj7TiEykWfP5RrZCLQ7L6Jd/
+HtgQti/9TVUaFkIlQCfvF+l4BYZQYvnhx3MVK7ChKLmy6AVQLWnDrBrDvl07HLvW
+6pslRzVHfWyIYng0pZ0HvK+MpQztCoUcDK470mjlpAtjNHuyKh6r6TtaiVK8MgbR
+Sx/NMHb1/PXQJrkCDQRREsLdARAA3Frw+j6H9McEIi/gjiGwvxnIdGc8McWchnFp
OWvdhTW9056v+y22DoKbULjT8k+8GzuRQ0xp4VwCC1rX3UExwceczzGs+tSKuIGm
g1ELygsaOZHdQBNLGPvn+TZNGlaYXPlQo7m8YhXGHwgQrdKyjcFD5xnOHxe981LT
q+IQ6jVYhho7/Qik9rVE1XHxoOfYvnNZJD0cFdf9OcX47YoqmM4sZYPMoOmKoVQT
@@ -59,5 +71,5 @@ Dxix2FBXQU/4pVpGHjXTQP6RqeTrAedXvpgCHWP1UIlswIQecGmQcJ/hRZjd+0vl
cjfCYhZHr7N96Da6Cy8v2fZiZHaSAt7T2oIZ9X3gEh/kOlLDcuIdvMHUfojn0MrP
Ce1AqOHyQQqhkVylvZpS0PdE0VW3PmJ98uKfX2FVAOTUD4Rw3n9Ew7bfM249HuP4
JOXi/Skp4sBB/xgrtV1u+E+BW0SS/BOiwfrI4xUy+MrWuw==
-=4STg
+=Om8x
-----END PGP PUBLIC KEY BLOCK-----
diff --git a/puppet/modules/site_apt/manifests/init.pp b/puppet/modules/site_apt/manifests/init.pp
index 8821c110..9facf4cc 100644
--- a/puppet/modules/site_apt/manifests/init.pp
+++ b/puppet/modules/site_apt/manifests/init.pp
@@ -1,15 +1,6 @@
class site_apt {
- # on couchdb we need to include squeeze in apt preferences,
- # so the cloudant package can pull some packages from squeeze
- # template() must be unquoted !
- if 'couchdb' in $::services {
- $custom_preferences = template("site_apt/preferences.include_squeeze")
- } else {
- $custom_preferences = ''
- }
class { 'apt':
- custom_preferences => $custom_preferences,
custom_key_dir => 'puppet:///modules/site_apt/keys'
}
@@ -37,6 +28,6 @@ class site_apt {
# The creation of sources.list depends on the lsb package
File['/etc/apt/preferences'] ->
- Exec['refresh_apt']
- Package <| ( title != 'lsb' ) |>
+ Exec['refresh_apt'] ->
+ Package <| ( title != 'lsb' ) |>
}
diff --git a/puppet/modules/site_apt/manifests/preferences/check_mk.pp b/puppet/modules/site_apt/manifests/preferences/check_mk.pp
new file mode 100644
index 00000000..580e0d3f
--- /dev/null
+++ b/puppet/modules/site_apt/manifests/preferences/check_mk.pp
@@ -0,0 +1,9 @@
+class site_apt::preferences::check_mk {
+
+ apt::preferences_snippet { 'check-mk':
+ package => 'check-mk-*',
+ release => "${::lsbdistcodename}-backports",
+ priority => 999;
+ }
+
+}
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..abff6838
--- /dev/null
+++ b/puppet/modules/site_apt/manifests/preferences/twisted.pp
@@ -0,0 +1,9 @@
+class site_apt::preferences::twisted {
+
+ apt::preferences_snippet { 'python-twisted':
+ package => 'python-twisted*',
+ release => "${::lsbdistcodename}-backports",
+ priority => 999;
+ }
+
+}
diff --git a/puppet/modules/site_apt/templates/wheezy/postfix.seeds b/puppet/modules/site_apt/templates/wheezy/postfix.seeds
new file mode 100644
index 00000000..1a878ccc
--- /dev/null
+++ b/puppet/modules/site_apt/templates/wheezy/postfix.seeds
@@ -0,0 +1 @@
+postfix postfix/main_mailer_type select No configuration
diff --git a/puppet/modules/site_check_mk/files/agent/local_checks/all_hosts/run_node_tests.sh b/puppet/modules/site_check_mk/files/agent/local_checks/all_hosts/run_node_tests.sh
new file mode 100644
index 00000000..1dd0afc9
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/local_checks/all_hosts/run_node_tests.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+#
+# runs node tests
+
+/srv/leap/bin/run_tests --checkmk
diff --git a/puppet/modules/site_check_mk/files/agent/local_checks/mx/check_leap_mx.sh b/puppet/modules/site_check_mk/files/agent/local_checks/mx/check_leap_mx.sh
new file mode 100755
index 00000000..b8687c9a
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/local_checks/mx/check_leap_mx.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+
+WARN=1
+CRIT=5
+
+# in minutes
+MAXAGE=10
+
+STATUS[0]='OK'
+STATUS[1]='Warning'
+STATUS[2]='Critical'
+CHECKNAME='Leap_MX_Queue'
+
+WATCHDIR='/var/mail/vmail/Maildir/new/'
+
+
+total=`find $WATCHDIR -type f -mmin +$MAXAGE | wc -l`
+
+if [ $total -lt $WARN ]
+then
+ exitcode=0
+else
+ if [ $total -le $CRIT ]
+ then
+ exitcode=1
+ else
+ exitcode=2
+ fi
+fi
+
+echo "${exitcode} ${CHECKNAME} stale_files=${total} ${STATUS[exitcode]}: ${total} stale files (>=${MAXAGE} min) in ${WATCHDIR}."
+
diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/bigcouch.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/bigcouch.cfg
new file mode 100644
index 00000000..28f333b0
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/logwatch/bigcouch.cfg
@@ -0,0 +1,20 @@
+/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 "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,
+ 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/logwatch/leap_mx.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/leap_mx.cfg
new file mode 100644
index 00000000..c71c5392
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/logwatch/leap_mx.cfg
@@ -0,0 +1,4 @@
+/var/log/leap_mx.log
+ W Don't know how to deliver mail
+ W No public key, stopping the processing chain
+
diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/logwatch.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/logwatch.cfg
new file mode 100644
index 00000000..4f16d1bd
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/logwatch/logwatch.cfg
@@ -0,0 +1,31 @@
+# This file is managed by Puppet. DO NOT EDIT.
+
+# logwatch.cfg
+# This file configures mk_logwatch. Define your logfiles
+# and patterns to be looked for here.
+
+# Name one or more logfiles
+/var/log/messages
+# Patterns are indented with one space are prefixed with:
+# C: Critical messages
+# W: Warning messages
+# I: ignore these lines (OK)
+# The first match decided. Lines that do not match any pattern
+# are ignored
+ C Fail event detected on md device
+ I mdadm.*: Rebuild.*event detected
+ W mdadm\[
+ W ata.*hard resetting link
+ W ata.*soft reset failed (.*FIS failed)
+ W device-mapper: thin:.*reached low water mark
+ C device-mapper: thin:.*no free space
+
+/var/log/auth.log
+ W sshd.*Corrupted MAC on input
+
+/var/log/kern.log
+ C panic
+ C Oops
+ W generic protection rip
+ W .*Unrecovered read error - auto reallocate failed
+
diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/soledad.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/soledad.cfg
new file mode 100644
index 00000000..623d1e46
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/logwatch/soledad.cfg
@@ -0,0 +1,5 @@
+/var/log/soledad.log
+ C WSGI application error
+ C Error
+ C error
+ W Timing out client:
diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/syslog/couchdb.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/syslog/couchdb.cfg
new file mode 100644
index 00000000..f546135a
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/logwatch/syslog/couchdb.cfg
@@ -0,0 +1,7 @@
+ C /usr/local/bin/couch-doc-update.*failed
+ C /usr/local/bin/couch-doc-update.*ERROR
+# on one-node bigcouch setups, we'll get this msg
+# a lot, so we ignore it here until we fix
+# https://leap.se/code/issues/5244
+ I epmd: got partial packet only on file descriptor
+
diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/syslog/openvpn.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/syslog/openvpn.cfg
new file mode 100644
index 00000000..d58e876d
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/logwatch/syslog/openvpn.cfg
@@ -0,0 +1,7 @@
+# ignore openvpn TLS initialization errors when clients
+# suddenly hangup before properly establishing
+# a tls connection
+ I ovpn-.*TLS Error: Unroutable control packet received from
+ I ovpn-.*TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
+ I ovpn-.*TLS Error: TLS handshake failed
+
diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/syslog/stunnel.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/syslog/stunnel.cfg
new file mode 100644
index 00000000..eb3131f2
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/logwatch/syslog/stunnel.cfg
@@ -0,0 +1,9 @@
+# check for stunnel failures
+#
+# these are temporary failures and happen very often, so we
+# ignore them until we tuned stunnel timeouts/logging,
+# see https://leap.se/code/issues/5218
+ I stunnel:.*Connection reset by peer
+ I stunnel:.*Peer suddenly disconnected
+ I stunnel:.*Connection refused
+
diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/syslog/tapicero.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/syslog/tapicero.cfg
new file mode 100644
index 00000000..93ce0311
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/logwatch/syslog/tapicero.cfg
@@ -0,0 +1,8 @@
+ C tapicero.*RestClient::InternalServerError:
+# possible race condition between multiple tapicero
+# instances, so we ignore it
+# see https://leap.se/code/issues/5168
+ I tapicero.*RestClient::PreconditionFailed:
+ C tapicero.*Creating database.*failed due to:
+ C tapicero.*failed
+ W tapicero.*Couch stream ended unexpectedly.
diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/syslog/webapp.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/syslog/webapp.cfg
new file mode 100644
index 00000000..00f9c7fd
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/logwatch/syslog/webapp.cfg
@@ -0,0 +1,5 @@
+# check for webapp errors
+ C webapp.*Could not connect to couch database messages due to 401 Unauthorized: {"error":"unauthorized","reason":"You are not a server admin."}
+# ignore RoutingErrors that rails throw when it can't handle a url
+# see https://leap.se/code/issues/5173
+ I webapp.*ActionController::RoutingError
diff --git a/puppet/modules/site_check_mk/files/agent/logwatch/syslog_header.cfg b/puppet/modules/site_check_mk/files/agent/logwatch/syslog_header.cfg
new file mode 100644
index 00000000..f60d752b
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/logwatch/syslog_header.cfg
@@ -0,0 +1 @@
+/var/log/syslog
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
new file mode 100644
index 00000000..450b9e90
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/logwatch/syslog_tail.cfg
@@ -0,0 +1,11 @@
+# some general patterns
+ C panic
+ C Oops
+ I Error: Driver 'pcspkr' is already registered, aborting...
+ C Error
+ C error
+ W generic protection rip
+ W .*Unrecovered read error - auto reallocate failed
+# 401 Unauthorized error logged by webapp and possible other
+# applications
+ C Unauthorized
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
new file mode 100755
index 00000000..06163d49
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/nagios_plugins/check_unix_open_fds.pl
@@ -0,0 +1,322 @@
+#!/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 <process_threshold,application_threshold> -c <process_threshold,application_threshold>\n".
+ "\t\t[-V <version>]\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: <process_threshold,application_threshold>",
+ required => 1);
+ # Add argument critical
+ $Nagios->add_arg(spec => 'critical|c=s',
+ help => "Critical thresholds. Format: <process_threshold,application_threshold>",
+ 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/files/agent/plugins/mk_logwatch.1.2.4 b/puppet/modules/site_check_mk/files/agent/plugins/mk_logwatch.1.2.4
new file mode 100755
index 00000000..3dbca322
--- /dev/null
+++ b/puppet/modules/site_check_mk/files/agent/plugins/mk_logwatch.1.2.4
@@ -0,0 +1,374 @@
+#!/usr/bin/python
+# -*- encoding: utf-8; py-indent-offset: 4 -*-
+# +------------------------------------------------------------------+
+# | ____ _ _ __ __ _ __ |
+# | / ___| |__ ___ ___| | __ | \/ | |/ / |
+# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
+# | | |___| | | | __/ (__| < | | | | . \ |
+# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
+# | |
+# | Copyright Mathias Kettner 2010 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.
+
+# Call with -d for debug mode: colored output, no saving of status
+
+import sys, os, re, time
+import glob
+
+if '-d' in sys.argv[1:] or '--debug' in sys.argv[1:]:
+ tty_red = '\033[1;31m'
+ tty_green = '\033[1;32m'
+ tty_yellow = '\033[1;33m'
+ tty_blue = '\033[1;34m'
+ tty_normal = '\033[0m'
+ debug = True
+else:
+ tty_red = ''
+ tty_green = ''
+ tty_yellow = ''
+ tty_blue = ''
+ tty_normal = ''
+ debug = False
+
+# The configuration file and status file are searched
+# in the directory named by the environment variable
+# LOGWATCH_DIR. If that is not set, MK_CONFDIR is used.
+# If that is not set either, the current directory ist
+# used.
+logwatch_dir = os.getenv("LOGWATCH_DIR")
+if not logwatch_dir:
+ logwatch_dir = os.getenv("MK_CONFDIR")
+ if not logwatch_dir:
+ logwatch_dir = "."
+
+print "<<<logwatch>>>"
+
+config_filename = logwatch_dir + "/logwatch.cfg"
+status_filename = logwatch_dir + "/logwatch.state"
+config_dir = logwatch_dir + "/logwatch.d/*.cfg"
+
+def is_not_comment(line):
+ if line.lstrip().startswith('#') or \
+ line.strip() == '':
+ return False
+ return True
+
+def parse_filenames(line):
+ return line.split()
+
+def parse_pattern(level, pattern):
+ if level not in [ 'C', 'W', 'I', 'O' ]:
+ raise(Exception("Invalid pattern line '%s'" % line))
+ try:
+ compiled = re.compile(pattern)
+ except:
+ raise(Exception("Invalid regular expression in line '%s'" % line))
+ return (level, compiled)
+
+def read_config():
+ config_lines = [ line.rstrip() for line in filter(is_not_comment, file(config_filename).readlines()) ]
+ # Add config from a logwatch.d folder
+ for config_file in glob.glob(config_dir):
+ config_lines += [ line.rstrip() for line in filter(is_not_comment, file(config_file).readlines()) ]
+
+ have_filenames = False
+ config = []
+
+ for line in config_lines:
+ rewrite = False
+ if line[0].isspace(): # pattern line
+ if not have_filenames:
+ raise Exception("Missing logfile names")
+ level, pattern = line.split(None, 1)
+ if level == 'A':
+ cont_list.append(parse_cont_pattern(pattern))
+ elif level == 'R':
+ rewrite_list.append(pattern)
+ else:
+ level, compiled = parse_pattern(level, pattern)
+ cont_list = [] # List of continuation patterns
+ rewrite_list = [] # List of rewrite patterns
+ patterns.append((level, compiled, cont_list, rewrite_list))
+ else: # filename line
+ patterns = []
+ config.append((parse_filenames(line), patterns))
+ have_filenames = True
+ return config
+
+def parse_cont_pattern(pattern):
+ try:
+ return int(pattern)
+ except:
+ try:
+ return re.compile(pattern)
+ except:
+ if debug:
+ raise
+ raise Exception("Invalid regular expression in line '%s'" % pattern)
+
+# structure of statusfile
+# # LOGFILE OFFSET INODE
+# /var/log/messages|7767698|32455445
+# /var/test/x12134.log|12345|32444355
+def read_status():
+ if debug:
+ return {}
+
+ status = {}
+ for line in file(status_filename):
+ # TODO: Remove variants with spaces. rsplit is
+ # not portable. split fails if logfilename contains
+ # spaces
+ inode = -1
+ try:
+ parts = line.split('|')
+ filename = parts[0]
+ offset = parts[1]
+ if len(parts) >= 3:
+ inode = parts[2]
+
+ except:
+ try:
+ filename, offset = line.rsplit(None, 1)
+ except:
+ filename, offset = line.split(None, 1)
+ status[filename] = int(offset), int(inode)
+ return status
+
+def save_status(status):
+ f = file(status_filename, "w")
+ for filename, (offset, inode) in status.items():
+ f.write("%s|%d|%d\n" % (filename, offset, inode))
+
+pushed_back_line = None
+def next_line(f):
+ global pushed_back_line
+ if pushed_back_line != None:
+ line = pushed_back_line
+ pushed_back_line = None
+ return line
+ else:
+ try:
+ line = f.next()
+ return line
+ except:
+ return None
+
+
+def process_logfile(logfile, patterns):
+ global pushed_back_line
+
+ # Look at which file offset we have finished scanning
+ # the logfile last time. If we have never seen this file
+ # before, we set the offset to -1
+ offset, prev_inode = status.get(logfile, (-1, -1))
+ try:
+ fl = os.open(logfile, os.O_RDONLY)
+ inode = os.fstat(fl)[1] # 1 = st_ino
+ except:
+ if debug:
+ raise
+ print "[[[%s:cannotopen]]]" % logfile
+ return
+
+ print "[[[%s]]]" % logfile
+
+ # Seek to the current end in order to determine file size
+ current_end = os.lseek(fl, 0, 2) # os.SEEK_END not available in Python 2.4
+ status[logfile] = current_end, inode
+
+ # If we have never seen this file before, we just set the
+ # current pointer to the file end. We do not want to make
+ # a fuss about ancient log messages...
+ if offset == -1:
+ if not debug:
+ return
+ else:
+ offset = 0
+
+
+ # If the inode of the logfile has changed it has appearently
+ # been started from new (logfile rotation). At least we must
+ # assume that. In some rare cases (restore of a backup, etc)
+ # we are wrong and resend old log messages
+ if prev_inode >= 0 and inode != prev_inode:
+ offset = 0
+
+ # Our previously stored offset is the current end ->
+ # no new lines in this file
+ if offset == current_end:
+ return # nothing new
+
+ # If our offset is beyond the current end, the logfile has been
+ # truncated or wrapped while keeping the same inode. We assume
+ # that it contains all new data in that case and restart from
+ # offset 0.
+ if offset > current_end:
+ offset = 0
+
+ # now seek to offset where interesting data begins
+ os.lseek(fl, offset, 0) # os.SEEK_SET not available in Python 2.4
+ f = os.fdopen(fl)
+ worst = -1
+ outputtxt = ""
+ lines_parsed = 0
+ start_time = time.time()
+
+ while True:
+ line = next_line(f)
+ if line == None:
+ break # End of file
+
+ lines_parsed += 1
+ # Check if maximum number of new log messages is exceeded
+ if opt_maxlines != None and lines_parsed > opt_maxlines:
+ outputtxt += "%s Maximum number (%d) of new log messages exceeded.\n" % (
+ opt_overflow, opt_maxlines)
+ worst = max(worst, opt_overflow_level)
+ os.lseek(fl, 0, 2) # Seek to end of file, skip all other messages
+ break
+
+ # Check if maximum processing time (per file) is exceeded. Check only
+ # every 100'th line in order to save system calls
+ if opt_maxtime != None and lines_parsed % 100 == 10 \
+ and time.time() - start_time > opt_maxtime:
+ outputtxt += "%s Maximum parsing time (%.1f sec) of this log file exceeded.\n" % (
+ opt_overflow, opt_maxtime)
+ worst = max(worst, opt_overflow_level)
+ os.lseek(fl, 0, 2) # Seek to end of file, skip all other messages
+ break
+
+ level = "."
+ for lev, pattern, cont_patterns, replacements in patterns:
+ matches = pattern.search(line[:-1])
+ if matches:
+ level = lev
+ levelint = {'C': 2, 'W': 1, 'O': 0, 'I': -1, '.': -1}[lev]
+ worst = max(levelint, worst)
+
+ # Check for continuation lines
+ for cont_pattern in cont_patterns:
+ if type(cont_pattern) == int: # add that many lines
+ for x in range(cont_pattern):
+ cont_line = next_line(f)
+ if cont_line == None: # end of file
+ break
+ line = line[:-1] + "\1" + cont_line
+
+ else: # pattern is regex
+ while True:
+ cont_line = next_line(f)
+ if cont_line == None: # end of file
+ break
+ elif cont_pattern.search(cont_line[:-1]):
+ line = line[:-1] + "\1" + cont_line
+ else:
+ pushed_back_line = cont_line # sorry for stealing this line
+ break
+
+ # Replacement
+ for replace in replacements:
+ line = replace.replace('\\0', line) + "\n"
+ for nr, group in enumerate(matches.groups()):
+ line = line.replace('\\%d' % (nr+1), group)
+
+ break # matching rule found and executed
+
+ color = {'C': tty_red, 'W': tty_yellow, 'O': tty_green, 'I': tty_blue, '.': ''}[level]
+ if debug:
+ line = line.replace("\1", "\nCONT:")
+ if level == "I":
+ level = "."
+ if opt_nocontext and level == '.':
+ continue
+ outputtxt += "%s%s %s%s\n" % (color, level, line[:-1], tty_normal)
+
+ new_offset = os.lseek(fl, 0, 1) # os.SEEK_CUR not available in Python 2.4
+ status[logfile] = new_offset, inode
+
+ # output all lines if at least one warning, error or ok has been found
+ if worst > -1:
+ sys.stdout.write(outputtxt)
+ sys.stdout.flush()
+
+try:
+ config = read_config()
+except Exception, e:
+ if debug:
+ raise
+ print "CANNOT READ CONFIG FILE: %s" % e
+ sys.exit(1)
+
+# Simply ignore errors in the status file. In case of a corrupted status file we simply begin
+# with an empty status. That keeps the monitoring up and running - even if we might loose a
+# message in the extreme case of a corrupted status file.
+try:
+ status = read_status()
+except Exception, e:
+ status = {}
+
+
+# The filename line may contain options like 'maxlines=100' or 'maxtime=10'
+for filenames, patterns in config:
+ # Initialize options with default values
+ opt_maxlines = None
+ opt_maxtime = None
+ opt_regex = None
+ opt_overflow = 'C'
+ opt_overflow_level = 2
+ opt_nocontext = False
+ try:
+ options = [ o.split('=', 1) for o in filenames if '=' in o ]
+ for key, value in options:
+ if key == 'maxlines':
+ opt_maxlines = int(value)
+ elif key == 'maxtime':
+ opt_maxtime = float(value)
+ elif key == 'overflow':
+ if value not in [ 'C', 'I', 'W', 'O' ]:
+ raise Exception("Invalid value %s for overflow. Allowed are C, I, O and W" % value)
+ opt_overflow = value
+ opt_overflow_level = {'C':2, 'W':1, 'O':0, 'I':0}[value]
+ elif key == 'regex':
+ opt_regex = re.compile(value)
+ elif key == 'iregex':
+ opt_regex = re.compile(value, re.I)
+ elif key == 'nocontext':
+ opt_nocontext = True
+ else:
+ raise Exception("Invalid option %s" % key)
+ except Exception, e:
+ if debug:
+ raise
+ print "INVALID CONFIGURATION: %s" % e
+ sys.exit(1)
+
+
+ for glob in filenames:
+ if '=' in glob:
+ continue
+ logfiles = [ l.strip() for l in os.popen("ls %s 2>/dev/null" % glob).readlines() ]
+ if opt_regex:
+ logfiles = [ f for f in logfiles if opt_regex.search(f) ]
+ if len(logfiles) == 0:
+ print '[[[%s:missing]]]' % glob
+ else:
+ for logfile in logfiles:
+ process_logfile(logfile, patterns)
+
+if not debug:
+ save_status(status)
diff --git a/puppet/modules/site_check_mk/manifests/agent.pp b/puppet/modules/site_check_mk/manifests/agent.pp
new file mode 100644
index 00000000..589041eb
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent.pp
@@ -0,0 +1,28 @@
+class site_check_mk::agent {
+
+ $ssh_hash = hiera('ssh')
+ $pubkey = $ssh_hash['authorized_keys']['monitor']['key']
+ $type = $ssh_hash['authorized_keys']['monitor']['type']
+
+ class { 'site_apt::preferences::check_mk': } ->
+
+ class { 'check_mk::agent':
+ agent_package_name => 'check-mk-agent',
+ agent_logwatch_package_name => 'check-mk-agent-logwatch',
+ method => 'ssh',
+ homedir => '/etc/nagios/check_mk',
+ register_agent => false
+ } ->
+
+ class { 'site_check_mk::agent::mrpe': } ->
+ class { 'site_check_mk::agent::logwatch': } ->
+
+ file {
+ [ '/srv/leap/nagios', '/srv/leap/nagios/plugins' ]:
+ ensure => directory;
+ '/usr/lib/check_mk_agent/local/run_node_tests.sh':
+ source => 'puppet:///modules/site_check_mk/agent/local_checks/all_hosts/run_node_tests.sh',
+ mode => '0755';
+ }
+
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/couchdb.pp b/puppet/modules/site_check_mk/manifests/agent/couchdb.pp
new file mode 100644
index 00000000..01e2b886
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/couchdb.pp
@@ -0,0 +1,36 @@
+class site_check_mk::agent::couchdb {
+
+ # watch logs
+ file { '/etc/check_mk/logwatch.d/bigcouch.cfg':
+ source => 'puppet:///modules/site_check_mk/agent/logwatch/bigcouch.cfg',
+ }
+ concat::fragment { 'syslog_couchdb':
+ source => 'puppet:///modules/site_check_mk/agent/logwatch/syslog/couchdb.cfg',
+ target => '/etc/check_mk/logwatch.d/syslog.cfg',
+ order => '02';
+ }
+
+
+ # check bigcouch processes
+ file_line {
+ 'Bigcouch_epmd_procs':
+ line => 'Bigcouch_epmd_procs /usr/lib/nagios/plugins/check_procs -w 1:1 -c 1:1 -a /opt/bigcouch/erts-5.9.1/bin/epmd',
+ path => '/etc/check_mk/mrpe.cfg';
+ 'Bigcouch_beam_procs':
+ line => 'Bigcouch_beam_procs /usr/lib/nagios/plugins/check_procs -w 1:1 -c 1:1 -a /opt/bigcouch/erts-5.9.1/bin/beam',
+ path => '/etc/check_mk/mrpe.cfg';
+ }
+
+ # 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'
+ }
+ file_line {
+ 'Bigcouch_open_files':
+ line => 'Bigcouch_open_files /srv/leap/nagios/plugins/check_unix_open_fds.pl -a beam -w 750,750 -c 1000,1000',
+ path => '/etc/check_mk/mrpe.cfg';
+ }
+
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/haproxy.pp b/puppet/modules/site_check_mk/manifests/agent/haproxy.pp
new file mode 100644
index 00000000..e7986db1
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/haproxy.pp
@@ -0,0 +1,12 @@
+class site_check_mk::agent::haproxy {
+
+ include site_check_mk::agent::package::nagios_plugins_contrib
+
+ # local nagios plugin checks via mrpe
+ file_line {
+ 'haproxy':
+ line => 'Haproxy /usr/lib/nagios/plugins/check_haproxy -u "http://localhost:8000/haproxy;csv"',
+ path => '/etc/check_mk/mrpe.cfg';
+ }
+
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/logwatch.pp b/puppet/modules/site_check_mk/manifests/agent/logwatch.pp
new file mode 100644
index 00000000..423cace2
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/logwatch.pp
@@ -0,0 +1,36 @@
+class site_check_mk::agent::logwatch {
+ # Deploy mk_logwatch 1.2.4 so we can split the config
+ # into multiple config files in /etc/check_mk/logwatch.d
+ # see https://leap.se/code/issues/5135
+
+ file { '/usr/lib/check_mk_agent/plugins/mk_logwatch':
+ source => 'puppet:///modules/site_check_mk/agent/plugins/mk_logwatch.1.2.4',
+ mode => '0755',
+ require => Package['check-mk-agent-logwatch']
+ }
+
+ # only config files that watch a distinct logfile should go in logwatch.d/
+ file { '/etc/check_mk/logwatch.d':
+ ensure => directory,
+ recurse => true,
+ purge => true,
+ require => Package['check-mk-agent-logwatch']
+ }
+
+ # service that share a common logfile (i.e. /var/log/syslog) need to get
+ # concanated in one file, otherwise the last file sourced will override
+ # the config before
+ # see mk_logwatch: "logwatch.cfg overwrites config files in logwatch.d",
+ # https://leap.se/code/issues/5155
+
+ # first, we need to deploy a custom logwatch.cfg that doesn't include
+ # a section about /var/log/syslog
+
+ file { '/etc/check_mk/logwatch.cfg':
+ source => 'puppet:///modules/site_check_mk/agent/logwatch/logwatch.cfg',
+ require => Package['check_mk-agent-logwatch']
+ }
+
+ include concat::setup
+ include site_check_mk::agent::logwatch::syslog
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/logwatch/syslog.pp b/puppet/modules/site_check_mk/manifests/agent/logwatch/syslog.pp
new file mode 100644
index 00000000..c927780d
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/logwatch/syslog.pp
@@ -0,0 +1,18 @@
+class site_check_mk::agent::logwatch::syslog {
+
+ concat { '/etc/check_mk/logwatch.d/syslog.cfg':
+ warn => true
+ }
+
+ concat::fragment { 'syslog_header':
+ source => 'puppet:///modules/site_check_mk/agent/logwatch/syslog_header.cfg',
+ target => '/etc/check_mk/logwatch.d/syslog.cfg',
+ order => '01';
+ }
+ concat::fragment { 'syslog_tail':
+ source => 'puppet:///modules/site_check_mk/agent/logwatch/syslog_tail.cfg',
+ target => '/etc/check_mk/logwatch.d/syslog.cfg',
+ order => '99';
+ }
+
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/mrpe.pp b/puppet/modules/site_check_mk/manifests/agent/mrpe.pp
new file mode 100644
index 00000000..6921574f
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/mrpe.pp
@@ -0,0 +1,18 @@
+class site_check_mk::agent::mrpe {
+ # check_mk can use standard nagios plugins using
+ # a wrapper called mrpe
+ # see http://mathias-kettner.de/checkmk_mrpe.html
+
+ package { 'nagios-plugins-basic':
+ ensure => latest,
+ }
+
+ file { '/etc/check_mk/mrpe.cfg':
+ ensure => present,
+ require => Package['check-mk-agent']
+ } ->
+ file_line { 'Apt':
+ line => 'APT /usr/lib/nagios/plugins/check_apt',
+ path => '/etc/check_mk/mrpe.cfg',
+ }
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/mx.pp b/puppet/modules/site_check_mk/manifests/agent/mx.pp
new file mode 100644
index 00000000..35a4e9a5
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/mx.pp
@@ -0,0 +1,23 @@
+class site_check_mk::agent::mx {
+
+ # watch logs
+ file { '/etc/check_mk/logwatch.d/leap_mx.cfg':
+ source => 'puppet:///modules/site_check_mk/agent/logwatch/leap_mx.cfg',
+ }
+
+ # local nagios plugin checks via mrpe
+ file_line {
+ 'Leap_MX_Procs':
+ line => 'Leap_MX_Procs /usr/lib/nagios/plugins/check_procs -w 1:1 -c 1:1 -a leap_mx',
+ path => '/etc/check_mk/mrpe.cfg';
+ }
+
+
+ # check stale files in queue dir
+ file { '/usr/lib/check_mk_agent/local/check_leap_mx.sh':
+ source => 'puppet:///modules/site_check_mk/agent/local_checks/mx/check_leap_mx.sh',
+ mode => '0755',
+ require => Package['check_mk-agent']
+ }
+
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/openvpn.pp b/puppet/modules/site_check_mk/manifests/agent/openvpn.pp
new file mode 100644
index 00000000..919a408d
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/openvpn.pp
@@ -0,0 +1,10 @@
+class site_check_mk::agent::openvpn {
+
+ # check syslog
+ concat::fragment { 'syslog_openpvn':
+ source => 'puppet:///modules/site_check_mk/agent/logwatch/syslog/openvpn.cfg',
+ target => '/etc/check_mk/logwatch.d/syslog.cfg',
+ order => '02';
+ }
+
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/package/nagios_plugins_contrib.pp b/puppet/modules/site_check_mk/manifests/agent/package/nagios_plugins_contrib.pp
new file mode 100644
index 00000000..95a60d17
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/package/nagios_plugins_contrib.pp
@@ -0,0 +1,5 @@
+class site_check_mk::agent::package::nagios_plugins_contrib {
+ package { 'nagios-plugins-contrib':
+ ensure => installed,
+ }
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/package/perl_plugin.pp b/puppet/modules/site_check_mk/manifests/agent/package/perl_plugin.pp
new file mode 100644
index 00000000..4feda375
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/package/perl_plugin.pp
@@ -0,0 +1,5 @@
+class site_check_mk::agent::package::perl_plugin {
+ package { 'libnagios-plugin-perl':
+ ensure => installed,
+ }
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/soledad.pp b/puppet/modules/site_check_mk/manifests/agent/soledad.pp
new file mode 100644
index 00000000..cbae81fe
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/soledad.pp
@@ -0,0 +1,14 @@
+class site_check_mk::agent::soledad {
+
+ file { '/etc/check_mk/logwatch.d/soledad.cfg':
+ source => 'puppet:///modules/site_check_mk/agent/logwatch/soledad.cfg',
+ }
+
+ # local nagios plugin checks via mrpe
+ file_line {
+ 'Soledad_Procs':
+ line => 'Soledad_Procs /usr/lib/nagios/plugins/check_procs -w 1:1 -c 1:1 -a soledad',
+ path => '/etc/check_mk/mrpe.cfg';
+ }
+
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/stunnel.pp b/puppet/modules/site_check_mk/manifests/agent/stunnel.pp
new file mode 100644
index 00000000..64022824
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/stunnel.pp
@@ -0,0 +1,9 @@
+class site_check_mk::agent::stunnel {
+
+ concat::fragment { 'syslog_stunnel':
+ source => 'puppet:///modules/site_check_mk/agent/logwatch/syslog/stunnel.cfg',
+ target => '/etc/check_mk/logwatch.d/syslog.cfg',
+ order => '02';
+ }
+
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/tapicero.pp b/puppet/modules/site_check_mk/manifests/agent/tapicero.pp
new file mode 100644
index 00000000..369ed00b
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/tapicero.pp
@@ -0,0 +1,16 @@
+class site_check_mk::agent::tapicero {
+
+ concat::fragment { 'syslog_tapicero':
+ source => 'puppet:///modules/site_check_mk/agent/logwatch/syslog/tapicero.cfg',
+ target => '/etc/check_mk/logwatch.d/syslog.cfg',
+ order => '02';
+ }
+
+ # local nagios plugin checks via mrpe
+ file_line {
+ 'Tapicero_Procs':
+ line => 'Tapicero_Procs /usr/lib/nagios/plugins/check_procs -w 1:1 -c 1:1 -a tapicero',
+ path => '/etc/check_mk/mrpe.cfg';
+ }
+
+}
diff --git a/puppet/modules/site_check_mk/manifests/agent/webapp.pp b/puppet/modules/site_check_mk/manifests/agent/webapp.pp
new file mode 100644
index 00000000..64f5ea6d
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/agent/webapp.pp
@@ -0,0 +1,26 @@
+class site_check_mk::agent::webapp {
+
+ # check webapp login + soledad sync
+ package { [ 'python-srp', 'python-requests', 'python-yaml', 'python-u1db' ]:
+ ensure => installed
+ }
+ file { '/usr/lib/check_mk_agent/local/nagios-webapp_login.py':
+ ensure => link,
+ target => '/srv/leap/webapp/test/nagios/webapp_login.py',
+ require => Package['check_mk-agent']
+ }
+ file { '/usr/lib/check_mk_agent/local/soledad_sync.py':
+ ensure => link,
+ target => '/srv/leap/webapp/test/nagios/soledad_sync.py',
+ require => Package['check_mk-agent']
+ }
+
+
+ # check syslog
+ concat::fragment { 'syslog_webapp':
+ source => 'puppet:///modules/site_check_mk/agent/logwatch/syslog/webapp.cfg',
+ target => '/etc/check_mk/logwatch.d/syslog.cfg',
+ order => '02';
+ }
+
+}
diff --git a/puppet/modules/site_check_mk/manifests/server.pp b/puppet/modules/site_check_mk/manifests/server.pp
new file mode 100644
index 00000000..e544ef0d
--- /dev/null
+++ b/puppet/modules/site_check_mk/manifests/server.pp
@@ -0,0 +1,64 @@
+class site_check_mk::server {
+
+ $ssh_hash = hiera('ssh')
+ $pubkey = $ssh_hash['authorized_keys']['monitor']['key']
+ $type = $ssh_hash['authorized_keys']['monitor']['type']
+ $seckey = $ssh_hash['monitor']['private_key']
+
+ $nagios_hiera = hiera_hash('nagios')
+ $nagios_hosts = $nagios_hiera['hosts']
+
+ $hosts = hiera_hash('hosts')
+ $all_hosts = inline_template ('<% @hosts.keys.sort.each do |key| -%>"<%= @hosts[key]["domain_internal"] %>", <% end -%>')
+
+ package { 'check-mk-server':
+ ensure => installed,
+ }
+
+ # override paths to use the system check_mk rather than OMD
+ class { 'check_mk::config':
+ site => '',
+ etc_dir => '/etc',
+ nagios_subdir => 'nagios3',
+ bin_dir => '/usr/bin',
+ host_groups => undef,
+ use_storedconfigs => false,
+ require => Package['check-mk-server']
+ }
+
+ Exec['check_mk-reload'] ->
+ Exec['check_mk-refresh-inventory-daily'] ->
+ Service['nagios']
+
+ file {
+ '/etc/check_mk/conf.d/use_ssh.mk':
+ content => template('site_check_mk/use_ssh.mk'),
+ notify => Exec['check_mk-refresh'],
+ require => Package['check-mk-server'];
+ '/etc/check_mk/all_hosts_static':
+ content => $all_hosts,
+ notify => Exec['check_mk-refresh'],
+ require => Package['check-mk-server'];
+ '/etc/check_mk/.ssh':
+ ensure => directory,
+ require => Package['check-mk-server'];
+ '/etc/check_mk/.ssh/id_rsa':
+ content => $seckey,
+ owner => 'nagios',
+ mode => '0600',
+ require => Package['check-mk-server'];
+ '/etc/check_mk/.ssh/id_rsa.pub':
+ content => "${type} ${pubkey} monitor",
+ owner => 'nagios',
+ mode => '0644',
+ require => Package['check-mk-server'];
+ # check_icmp must be suid root or called by sudo
+ # see https://leap.se/code/issues/5171
+ '/usr/lib/nagios/plugins/check_icmp':
+ mode => '4755',
+ require => Package['nagios-plugins-basic'];
+ }
+
+
+ include check_mk::agent::local_checks
+}
diff --git a/puppet/modules/site_check_mk/templates/use_ssh.mk b/puppet/modules/site_check_mk/templates/use_ssh.mk
new file mode 100644
index 00000000..0bebebcf
--- /dev/null
+++ b/puppet/modules/site_check_mk/templates/use_ssh.mk
@@ -0,0 +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 -%>
+
+]
diff --git a/puppet/modules/site_config/manifests/caching_resolver.pp b/puppet/modules/site_config/manifests/caching_resolver.pp
index 922c394f..3d7b9206 100644
--- a/puppet/modules/site_config/manifests/caching_resolver.pp
+++ b/puppet/modules/site_config/manifests/caching_resolver.pp
@@ -1,4 +1,5 @@
class site_config::caching_resolver {
+ tag 'leap_base'
# Setup a conf.d directory to place additional unbound configuration files.
# There must be at least one file in the directory, or unbound will not start,
diff --git a/puppet/modules/site_config/manifests/default.pp b/puppet/modules/site_config/manifests/default.pp
index 00eee9d0..7e421a21 100644
--- a/puppet/modules/site_config/manifests/default.pp
+++ b/puppet/modules/site_config/manifests/default.pp
@@ -2,19 +2,27 @@ class site_config::default {
tag 'leap_base'
$domain_hash = hiera('domain')
+ include site_config::params
- include concat::setup
+ # make sure apt is updated before any packages are installed
+ include apt::update
+ Package { require => Exec['apt_updated'] }
+
+ include site_config::slow
# default class, used by all hosts
include lsb, git
- # configure apt
- include site_apt
+ # configure sysctl parameters
+ include site_config::sysctl
# configure ssh and include ssh-keys
include site_config::sshd
+ # include classes for special environments
+ # i.e. openstack/aws nodes, vagrant nodes
+
# fix dhclient from changing resolver information
if $::ec2_instance_id {
include site_config::dhclient
@@ -26,13 +34,11 @@ class site_config::default {
# configure caching, local resolver
include site_config::caching_resolver
- # configure /etc/hosts
- class { 'site_config::hosts':
- stage => setup,
- }
+ # install/configure syslog
+ include site_config::syslog
# install/remove base packages
- include site_config::base_packages
+ include site_config::packages::base
# include basic shorewall config
include site_shorewall::defaults
@@ -41,4 +47,19 @@ class site_config::default {
# include basic shell config
include site_config::shell
+
+ # set up core leap files and directories
+ include site_config::files
+
+ if $::services !~ /\bmx\b/ {
+ include site_postfix::satellite
+ }
+
+ # if class site_custom exists, include it.
+ # possibility for users to define custom puppet recipes
+ if defined( '::site_custom') {
+ include ::site_custom
+ }
+
+ include site_check_mk::agent
}
diff --git a/puppet/modules/site_config/manifests/files.pp b/puppet/modules/site_config/manifests/files.pp
new file mode 100644
index 00000000..684d3ad0
--- /dev/null
+++ b/puppet/modules/site_config/manifests/files.pp
@@ -0,0 +1,23 @@
+class site_config::files {
+
+ file {
+ '/srv/leap':
+ ensure => directory,
+ owner => 'root',
+ group => 'root',
+ mode => '0711';
+
+ '/var/lib/leap':
+ ensure => directory,
+ owner => root,
+ group => 'root',
+ mode => '0755';
+
+ '/var/log/leap':
+ ensure => directory,
+ owner => root,
+ group => 'adm',
+ mode => '0750';
+ }
+
+}
diff --git a/puppet/modules/site_config/manifests/hosts.pp b/puppet/modules/site_config/manifests/hosts.pp
index ccedf036..e5d4dd70 100644
--- a/puppet/modules/site_config/manifests/hosts.pp
+++ b/puppet/modules/site_config/manifests/hosts.pp
@@ -1,8 +1,9 @@
class site_config::hosts() {
- $hosts = hiera('hosts','')
+ $hosts = hiera('hosts', false)
$hostname = hiera('name')
$domain_hash = hiera('domain')
$domain_public = $domain_hash['full_suffix']
+ $api = hiera('api', '')
file { '/etc/hostname':
ensure => present,
diff --git a/puppet/modules/site_config/manifests/initial_firewall.pp b/puppet/modules/site_config/manifests/initial_firewall.pp
new file mode 100644
index 00000000..51cceb31
--- /dev/null
+++ b/puppet/modules/site_config/manifests/initial_firewall.pp
@@ -0,0 +1,62 @@
+class site_config::initial_firewall {
+
+ # This class is intended to setup an initial firewall, before shorewall is
+ # configured. The purpose of this is for the rare case where shorewall fails
+ # to start, we should not expose services to the public.
+
+ $ssh_config = hiera('ssh')
+ $ssh_port = $ssh_config['port']
+
+ package { 'iptables':
+ ensure => present
+ }
+
+ file {
+ # This firewall enables ssh access, dns lookups and web lookups (for
+ # package installation) but otherwise restricts all outgoing and incoming
+ # ports
+ '/etc/network/ipv4firewall_up.rules':
+ content => template('site_config/ipv4firewall_up.rules.erb'),
+ owner => root,
+ group => 0,
+ mode => '0644';
+
+ # This firewall denys all ipv6 traffic - we will need to change this
+ # when we begin to support ipv6
+ '/etc/network/ipv6firewall_up.rules':
+ content => template('site_config/ipv6firewall_up.rules.erb'),
+ owner => root,
+ group => 0,
+ mode => '0644';
+
+ # Run the iptables-restore in if-pre-up so that the network is locked down
+ # until the correct interfaces and ips are connected
+ '/etc/network/if-pre-up.d/ipv4tables':
+ content => "#!/bin/sh\n/sbin/iptables-restore < /etc/network/ipv4firewall_up.rules\n",
+ owner => root,
+ group => 0,
+ mode => '0744';
+
+ # Same as above for IPv6
+ '/etc/network/if-pre-up.d/ipv6tables':
+ content => "#!/bin/sh\n/sbin/ip6tables-restore < /etc/network/ipv6firewall_up.rules\n",
+ owner => root,
+ group => 0,
+ mode => '0744';
+ }
+
+ # Immediately setup these firewall rules, but only if shorewall is not running
+ exec {
+ 'default_ipv4_firewall':
+ command => '/sbin/iptables-restore < /etc/network/ipv4firewall_up.rules',
+ logoutput => true,
+ unless => 'test -x /etc/init.d/shorewall && /etc/init.d/shorewall status',
+ require => File['/etc/network/ipv4firewall_up.rules'];
+
+ 'default_ipv6_firewall':
+ command => '/sbin/ip6tables-restore < /etc/network/ipv6firewall_up.rules',
+ logoutput => true,
+ unless => 'test -x /etc/init.d/shorewall && /etc/init.d/shorewall status',
+ require => File['/etc/network/ipv6firewall_up.rules'];
+ }
+}
diff --git a/puppet/modules/site_config/manifests/base_packages.pp b/puppet/modules/site_config/manifests/packages/base.pp
index 3d40f7a2..ae47963c 100644
--- a/puppet/modules/site_config/manifests/base_packages.pp
+++ b/puppet/modules/site_config/manifests/packages/base.pp
@@ -1,12 +1,13 @@
-class site_config::base_packages {
+class site_config::packages::base {
+
# base set of packages that we want to have installed everywhere
- package { [ 'etckeeper', 'screen', 'less' ]:
+ package { [ 'etckeeper', 'screen', 'less', 'ntp' ]:
ensure => installed,
}
# base set of packages that we want to remove everywhere
- package { [ 'acpi', 'acpid', 'acpi-support-base', 'eject', 'ftp',
+ package { [ 'acpi', 'acpid', 'acpi-support-base', 'eject', 'ftp', 'fontconfig-config',
'laptop-detect', 'lpr', 'nfs-common', 'nfs-kernel-server',
'portmap', 'pppconfig', 'pppoe', 'pump', 'qstat', 'rpcbind',
'samba-common', 'samba-common-bin', 'smbclient', 'tcl8.5',
@@ -14,15 +15,4 @@ class site_config::base_packages {
'x11-utils', 'xterm' ]:
ensure => absent;
}
-
- if $::virtual == 'virtualbox' {
- $virtualbox_ensure = present
- } else {
- $virtualbox_ensure = absent
- }
-
- package { [ 'build-essential', 'fontconfig-config', 'g++', 'g++-4.7', 'gcc',
- 'gcc-4.6', 'gcc-4.7', 'cpp', 'cpp-4.6', 'cpp-4.7', 'libc6-dev' ]:
- ensure => $virtualbox_ensure
- }
}
diff --git a/puppet/modules/site_config/manifests/packages/build_essential.pp b/puppet/modules/site_config/manifests/packages/build_essential.pp
new file mode 100644
index 00000000..7dfb8b03
--- /dev/null
+++ b/puppet/modules/site_config/manifests/packages/build_essential.pp
@@ -0,0 +1,11 @@
+#
+# include this whenever you want to ensure build-essential package and related compilers are installed.
+#
+class site_config::packages::build_essential {
+ if !defined(Package['build-essential']) {
+ package {
+ ['build-essential', 'g++', 'g++-4.7', 'gcc', 'gcc-4.6', 'gcc-4.7', 'cpp', 'cpp-4.6', 'cpp-4.7', 'libc6-dev']:
+ ensure => present
+ }
+ }
+} \ No newline at end of file
diff --git a/puppet/modules/site_config/manifests/packages/gnutls.pp b/puppet/modules/site_config/manifests/packages/gnutls.pp
new file mode 100644
index 00000000..b1f17480
--- /dev/null
+++ b/puppet/modules/site_config/manifests/packages/gnutls.pp
@@ -0,0 +1,5 @@
+class site_config::packages::gnutls {
+
+ package { 'gnutls-bin': ensure => installed }
+
+}
diff --git a/puppet/modules/site_config/manifests/packages/uninstall.pp b/puppet/modules/site_config/manifests/packages/uninstall.pp
new file mode 100644
index 00000000..12f527d9
--- /dev/null
+++ b/puppet/modules/site_config/manifests/packages/uninstall.pp
@@ -0,0 +1,16 @@
+#
+# Uninstall build-essential and compilers, unless they have been explicitly installed elsewhere.
+#
+class site_config::packages::uninstall {
+ tag 'leap_base'
+
+ # generally, dev packages are needed for installing ruby gems with native extensions.
+ # (nickserver, webapp, etc)
+
+ if !defined(Package['build-essential']) {
+ package {
+ ['build-essential', 'g++', 'g++-4.7', 'gcc', 'gcc-4.6', 'gcc-4.7', 'cpp', 'cpp-4.6', 'cpp-4.7', 'libc6-dev']:
+ ensure => purged
+ }
+ }
+} \ No newline at end of file
diff --git a/puppet/modules/site_config/manifests/params.pp b/puppet/modules/site_config/manifests/params.pp
index 237ee454..012b3ce0 100644
--- a/puppet/modules/site_config/manifests/params.pp
+++ b/puppet/modules/site_config/manifests/params.pp
@@ -3,9 +3,12 @@ class site_config::params {
$ip_address = hiera('ip_address')
$ip_address_interface = getvar("interface_${ip_address}")
$ec2_local_ipv4_interface = getvar("interface_${::ec2_local_ipv4}")
+ $environment = hiera('environment', undef)
- if $::virtual == 'virtualbox' {
- $interface = [ 'eth0', 'eth1' ]
+
+ if $environment == 'local' {
+ $interface = 'eth1'
+ include site_config::packages::build_essential
}
elsif hiera('interface','') != '' {
$interface = hiera('interface')
@@ -17,9 +20,16 @@ class site_config::params {
$interface = $ec2_local_ipv4_interface
}
elsif $::interfaces =~ /eth0/ {
- $interface = eth0
+ $interface = 'eth0'
}
else {
fail("unable to determine a valid interface, please set a valid interface for this node in nodes/${::hostname}.json")
}
+
+ $ca_name = 'leap_ca'
+ $client_ca_name = 'leap_client_ca'
+ $ca_bundle_name = 'leap_ca_bundle'
+ $cert_name = 'leap'
+ $commercial_ca_name = 'leap_commercial_ca'
+ $commercial_cert_name = 'leap_commercial'
}
diff --git a/puppet/modules/site_config/manifests/resolvconf.pp b/puppet/modules/site_config/manifests/resolvconf.pp
index 271c5043..05990c67 100644
--- a/puppet/modules/site_config/manifests/resolvconf.pp
+++ b/puppet/modules/site_config/manifests/resolvconf.pp
@@ -2,12 +2,13 @@ class site_config::resolvconf {
$domain_public = $site_config::default::domain_hash['full_suffix']
- # 127.0.0.1: caching-only local bind
- # 87.118.100.175: http://server.privacyfoundation.de
- # 62.141.58.13: http://www.privacyfoundation.ch/de/service/server.html
class { '::resolvconf':
domain => $domain_public,
search => $domain_public,
- nameservers => [ '127.0.0.1', '87.118.100.175', '62.141.58.13' ]
+ nameservers => [
+ '127.0.0.1 # local caching-only, unbound',
+ '85.214.20.141 # Digitalcourage, a german privacy organisation: (https://en.wikipedia.org/wiki/Digitalcourage)',
+ '77.109.138.45 # Swiss privacy Foundation (http://www.privacyfoundation.ch/de/service/server.html)'
+ ]
}
}
diff --git a/puppet/modules/site_config/manifests/ruby/dev.pp b/puppet/modules/site_config/manifests/ruby/dev.pp
new file mode 100644
index 00000000..3ea6ca96
--- /dev/null
+++ b/puppet/modules/site_config/manifests/ruby/dev.pp
@@ -0,0 +1,8 @@
+class site_config::ruby::dev inherits site_config::ruby {
+ Class['::ruby'] {
+ ruby_version => '1.9.3',
+ install_dev => true
+ }
+ # building gems locally probably requires build-essential and gcc:
+ include site_config::packages::build_essential
+}
diff --git a/puppet/modules/site_config/manifests/setup.pp b/puppet/modules/site_config/manifests/setup.pp
new file mode 100644
index 00000000..6d89be86
--- /dev/null
+++ b/puppet/modules/site_config/manifests/setup.pp
@@ -0,0 +1,50 @@
+class site_config::setup {
+ tag 'leap_base'
+
+ #
+ # this is applied before each run of site.pp
+ #
+ #$services = ''
+
+ Exec { path => '/usr/bin:/usr/sbin/:/bin:/sbin:/usr/local/bin:/usr/local/sbin' }
+
+ include site_config::params
+
+ include concat::setup
+ include stdlib
+
+ # configure /etc/hosts
+ class { 'site_config::hosts':
+ stage => setup,
+ }
+
+ include site_config::initial_firewall
+
+ include site_apt
+
+ package { 'facter':
+ ensure => latest,
+ require => Exec['refresh_apt']
+ }
+
+ # if squid_deb_proxy_client is set to true, install and configure
+ # squid_deb_proxy_client for apt caching
+ if hiera('squid_deb_proxy_client', false) {
+ include site_squid_deb_proxy::client
+ }
+
+ # shorewall is installed/half-configured during setup.pp (Bug #3871)
+ # we need to include shorewall::interface{eth0} in setup.pp so
+ # packages can be installed during main puppetrun, even before shorewall
+ # is configured completly
+ if ( $::site_config::params::environment == 'local' ) {
+ include site_config::vagrant
+ }
+
+ # if class site_custom::setup exists, include it.
+ # possibility for users to define custom puppet recipes
+ if defined( '::site_custom::setup') {
+ include ::site_custom::setup
+ }
+
+}
diff --git a/puppet/modules/site_config/manifests/sysctl.pp b/puppet/modules/site_config/manifests/sysctl.pp
new file mode 100644
index 00000000..99f75123
--- /dev/null
+++ b/puppet/modules/site_config/manifests/sysctl.pp
@@ -0,0 +1,8 @@
+class site_config::sysctl {
+
+ sysctl::config {
+ 'net.ipv4.ip_nonlocal_bind':
+ value => 1,
+ comment => 'Allow applications to bind to an address when link is down (see https://leap.se/code/issues/4506)'
+ }
+}
diff --git a/puppet/modules/site_config/manifests/syslog.pp b/puppet/modules/site_config/manifests/syslog.pp
new file mode 100644
index 00000000..d3abeca1
--- /dev/null
+++ b/puppet/modules/site_config/manifests/syslog.pp
@@ -0,0 +1,28 @@
+class site_config::syslog {
+
+ # we need to pull in rsyslog from the leap repository until it is availbale in
+ # wheezy-backports
+ apt::preferences_snippet { 'fixed_rsyslog_anon_package':
+ package => 'rsyslog*',
+ priority => '999',
+ pin => 'release o=leap.se',
+ before => Class['rsyslog::install']
+ }
+
+ apt::preferences_snippet { 'rsyslog_anon_depends':
+ package => 'libestr0 librelp0',
+ priority => '999',
+ pin => 'release a=wheezy-backports',
+ before => Class['rsyslog::install']
+ }
+
+ class { 'rsyslog::client':
+ log_remote => false,
+ log_local => true
+ }
+
+ rsyslog::snippet { '00-anonymize_logs':
+ content => '$ModLoad mmanon
+action(type="mmanon" ipv4.bits="32" mode="rewrite")'
+ }
+}
diff --git a/puppet/modules/site_config/manifests/vagrant.pp b/puppet/modules/site_config/manifests/vagrant.pp
new file mode 100644
index 00000000..8f50b305
--- /dev/null
+++ b/puppet/modules/site_config/manifests/vagrant.pp
@@ -0,0 +1,11 @@
+class site_config::vagrant {
+ # class for vagrant nodes
+
+ include site_shorewall::defaults
+ # eth0 on vagrant nodes is the uplink if
+ shorewall::interface { 'eth0':
+ zone => 'net',
+ options => 'tcpflags,blacklist,nosmurfs';
+ }
+
+}
diff --git a/puppet/modules/site_config/manifests/x509/ca.pp b/puppet/modules/site_config/manifests/x509/ca.pp
new file mode 100644
index 00000000..b16d0eeb
--- /dev/null
+++ b/puppet/modules/site_config/manifests/x509/ca.pp
@@ -0,0 +1,9 @@
+class site_config::x509::ca {
+
+ $x509 = hiera('x509')
+ $ca = $x509['ca_cert']
+
+ x509::ca { $site_config::params::ca_name:
+ content => $ca
+ }
+}
diff --git a/puppet/modules/site_config/manifests/x509/ca_bundle.pp b/puppet/modules/site_config/manifests/x509/ca_bundle.pp
new file mode 100644
index 00000000..4cbe574a
--- /dev/null
+++ b/puppet/modules/site_config/manifests/x509/ca_bundle.pp
@@ -0,0 +1,16 @@
+class site_config::x509::ca_bundle {
+
+ # CA bundle -- we want to have the possibility of allowing multiple CAs.
+ # For now, the reason is to transition to using client CA. In the future,
+ # we will want to be able to smoothly phase out one CA and phase in another.
+ # I tried "--capath" for this, but it did not work.
+
+
+ $x509 = hiera('x509')
+ $ca = $x509['ca_cert']
+ $client_ca = $x509['client_ca_cert']
+
+ x509::ca { $site_config::params::ca_bundle_name:
+ content => "${ca}${client_ca}"
+ }
+}
diff --git a/puppet/modules/site_config/manifests/x509/cert.pp b/puppet/modules/site_config/manifests/x509/cert.pp
new file mode 100644
index 00000000..7ed42959
--- /dev/null
+++ b/puppet/modules/site_config/manifests/x509/cert.pp
@@ -0,0 +1,10 @@
+class site_config::x509::cert {
+
+ $x509 = hiera('x509')
+ $cert = $x509['cert']
+
+ x509::cert { $site_config::params::cert_name:
+ content => $cert
+ }
+
+}
diff --git a/puppet/modules/site_config/manifests/x509/client_ca/ca.pp b/puppet/modules/site_config/manifests/x509/client_ca/ca.pp
new file mode 100644
index 00000000..0f313898
--- /dev/null
+++ b/puppet/modules/site_config/manifests/x509/client_ca/ca.pp
@@ -0,0 +1,14 @@
+class site_config::x509::client_ca::ca {
+
+ ##
+ ## This is for the special CA that is used exclusively for generating
+ ## client certificates by the webapp.
+ ##
+
+ $x509 = hiera('x509')
+ $cert = $x509['client_ca_cert']
+
+ x509::ca { $site_config::params::client_ca_name:
+ content => $cert
+ }
+}
diff --git a/puppet/modules/site_config/manifests/x509/client_ca/key.pp b/puppet/modules/site_config/manifests/x509/client_ca/key.pp
new file mode 100644
index 00000000..f9ef3f52
--- /dev/null
+++ b/puppet/modules/site_config/manifests/x509/client_ca/key.pp
@@ -0,0 +1,14 @@
+class site_config::x509::client_ca::key {
+
+ ##
+ ## This is for the special CA that is used exclusively for generating
+ ## client certificates by the webapp.
+ ##
+
+ $x509 = hiera('x509')
+ $key = $x509['client_ca_key']
+
+ x509::key { $site_config::params::client_ca_name:
+ content => $key
+ }
+}
diff --git a/puppet/modules/site_config/manifests/x509/commercial/ca.pp b/puppet/modules/site_config/manifests/x509/commercial/ca.pp
new file mode 100644
index 00000000..8f35759f
--- /dev/null
+++ b/puppet/modules/site_config/manifests/x509/commercial/ca.pp
@@ -0,0 +1,9 @@
+class site_config::x509::commercial::ca {
+
+ $x509 = hiera('x509')
+ $ca = $x509['commercial_ca_cert']
+
+ x509::ca { $site_config::params::commercial_ca_name:
+ content => $ca
+ }
+}
diff --git a/puppet/modules/site_config/manifests/x509/commercial/cert.pp b/puppet/modules/site_config/manifests/x509/commercial/cert.pp
new file mode 100644
index 00000000..0c71a705
--- /dev/null
+++ b/puppet/modules/site_config/manifests/x509/commercial/cert.pp
@@ -0,0 +1,10 @@
+class site_config::x509::commercial::cert {
+
+ $x509 = hiera('x509')
+ $cert = $x509['commercial_cert']
+
+ x509::cert { $site_config::params::commercial_cert_name:
+ content => $cert
+ }
+
+}
diff --git a/puppet/modules/site_config/manifests/x509/commercial/key.pp b/puppet/modules/site_config/manifests/x509/commercial/key.pp
new file mode 100644
index 00000000..d32e85ef
--- /dev/null
+++ b/puppet/modules/site_config/manifests/x509/commercial/key.pp
@@ -0,0 +1,9 @@
+class site_config::x509::commercial::key {
+
+ $x509 = hiera('x509')
+ $key = $x509['commercial_key']
+
+ x509::key { $site_config::params::commercial_cert_name:
+ content => $key
+ }
+}
diff --git a/puppet/modules/site_config/manifests/x509/key.pp b/puppet/modules/site_config/manifests/x509/key.pp
new file mode 100644
index 00000000..32b59726
--- /dev/null
+++ b/puppet/modules/site_config/manifests/x509/key.pp
@@ -0,0 +1,9 @@
+class site_config::x509::key {
+
+ $x509 = hiera('x509')
+ $key = $x509['key']
+
+ x509::key { $site_config::params::cert_name:
+ content => $key
+ }
+}
diff --git a/puppet/modules/site_config/templates/hosts b/puppet/modules/site_config/templates/hosts
index 2c784b05..bfcabaa5 100644
--- a/puppet/modules/site_config/templates/hosts
+++ b/puppet/modules/site_config/templates/hosts
@@ -1,10 +1,12 @@
# This file is managed by puppet, any changes will be overwritten!
127.0.0.1 localhost
-127.0.1.1 <%= @hostname %>.<%= @domain_public %> <%= @hostname %>
+127.0.1.1 <%= @hostname %>.<%= @domain_public %> <%= @hostname %> <% if (defined? @services) and (@services.include? 'webapp') -%><%= @domain_public %> <%= @api['domain'] %><% end -%>
+
<%- if @hosts then -%>
-<% @hosts.each do |name, props| -%>
+<% @hosts.keys.sort.each do |name| -%>
+<%- props = @hosts[name] -%>
<%= props["ip_address"] %> <%= props["domain_full"] %> <%= props["domain_internal"] %> <%= name %>
<% end -%>
<% end -%>
diff --git a/puppet/modules/site_config/templates/ipv4firewall_up.rules.erb b/puppet/modules/site_config/templates/ipv4firewall_up.rules.erb
new file mode 100644
index 00000000..524ae308
--- /dev/null
+++ b/puppet/modules/site_config/templates/ipv4firewall_up.rules.erb
@@ -0,0 +1,22 @@
+# Generated by iptables-save v1.4.14 on Tue Aug 20 14:40:40 2013
+*filter
+:INPUT DROP [0:0]
+:FORWARD DROP [0:0]
+:OUTPUT DROP [0:0]
+-A INPUT -i lo -j ACCEPT
+-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A INPUT -p tcp -m state --state NEW,ESTABLISHED --dport <%= @ssh_port %> -j ACCEPT
+-A INPUT -p udp -m udp --sport 53 -j ACCEPT
+-A INPUT -p icmp -m icmp --icmp-type 8 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
+-A INPUT -p icmp -m icmp --icmp-type 0 -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
+-A OUTPUT -o lo -j ACCEPT
+-A OUTPUT -p icmp -m icmp --icmp-type 0 -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A OUTPUT -p icmp -m icmp --icmp-type 8 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
+-A OUTPUT -p tcp -m state --state NEW,ESTABLISHED --sport <%= @ssh_port %> -j ACCEPT
+-A OUTPUT -p tcp -m state --state NEW,ESTABLISHED --dport 80 -j ACCEPT
+-A OUTPUT -p tcp -m state --state NEW,ESTABLISHED --dport 443 -j ACCEPT
+-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
+-A OUTPUT -p udp -m udp --dport 123 -j ACCEPT
+-A OUTPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
+COMMIT
diff --git a/puppet/modules/site_config/templates/ipv6firewall_up.rules.erb b/puppet/modules/site_config/templates/ipv6firewall_up.rules.erb
new file mode 100644
index 00000000..e7fae52e
--- /dev/null
+++ b/puppet/modules/site_config/templates/ipv6firewall_up.rules.erb
@@ -0,0 +1,7 @@
+# Generated by ip6tables-save v1.4.20 on Tue Aug 20 12:19:43 2013
+*filter
+:INPUT DROP [24:1980]
+:FORWARD DROP [0:0]
+:OUTPUT DROP [14:8030]
+COMMIT
+# Completed on Tue Aug 20 12:19:43 2013
diff --git a/puppet/modules/site_couchdb/files/couchdb_scripts_defaults.conf b/puppet/modules/site_couchdb/files/couchdb_scripts_defaults.conf
new file mode 100644
index 00000000..1565e1a1
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/couchdb_scripts_defaults.conf
@@ -0,0 +1,4 @@
+# space separated list of excluded DBs for dumping
+# sourced by couchdb_dumpall.sh
+EXCLUDE_DBS='sessions tokens'
+
diff --git a/puppet/modules/site_couchdb/files/designs/Readme.md b/puppet/modules/site_couchdb/files/designs/Readme.md
new file mode 100644
index 00000000..983f629f
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/designs/Readme.md
@@ -0,0 +1,14 @@
+This directory contains design documents for the leap platform.
+
+They need to be uploaded to the couch database in order to query the
+database in certain ways.
+
+Each subdirectory corresponds to a couch database and contains the design
+documents that need to be added to that particular database.
+
+Here's an example of how to upload the users design document:
+```bash
+HOST="http://localhost:5984"
+curl -X PUT $HOST/users/_design/User --data @users/User.json
+
+```
diff --git a/puppet/modules/site_couchdb/files/designs/customers/Customer.json b/puppet/modules/site_couchdb/files/designs/customers/Customer.json
new file mode 100644
index 00000000..1b4bbddd
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/designs/customers/Customer.json
@@ -0,0 +1,18 @@
+{
+ "_id": "_design/Customer",
+ "language": "javascript",
+ "views": {
+ "by_user_id": {
+ "map": " function(doc) {\n if ((doc['type'] == 'Customer') && (doc['user_id'] != null)) {\n emit(doc['user_id'], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "by_braintree_customer_id": {
+ "map": " function(doc) {\n if ((doc['type'] == 'Customer') && (doc['braintree_customer_id'] != null)) {\n emit(doc['braintree_customer_id'], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "all": {
+ "map": " function(doc) {\n if (doc['type'] == 'Customer') {\n emit(doc._id, null);\n }\n }\n"
+ }
+ },
+ "couchrest-hash": "688c401ec0230b75625c176a88fc4a02"
+} \ No newline at end of file
diff --git a/puppet/modules/site_couchdb/files/designs/identities/Identity.json b/puppet/modules/site_couchdb/files/designs/identities/Identity.json
new file mode 100644
index 00000000..2ac092ab
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/designs/identities/Identity.json
@@ -0,0 +1,28 @@
+{
+ "_id": "_design/Identity",
+ "language": "javascript",
+ "views": {
+ "by_user_id": {
+ "map": " function(doc) {\n if ((doc['type'] == 'Identity') && (doc['user_id'] != null)) {\n emit(doc['user_id'], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "by_address_and_destination": {
+ "map": " function(doc) {\n if ((doc['type'] == 'Identity') && (doc['address'] != null) && (doc['destination'] != null)) {\n emit([doc['address'], doc['destination']], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "by_address": {
+ "map": " function(doc) {\n if ((doc['type'] == 'Identity') && (doc['address'] != null)) {\n emit(doc['address'], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "pgp_key_by_email": {
+ "map": " function(doc) {\n if (doc.type != 'Identity') {\n return;\n }\n if (typeof doc.keys === \"object\") {\n emit(doc.address, doc.keys[\"pgp\"]);\n }\n }\n"
+ },
+ "disabled": {
+ "map": " function(doc) {\n if (doc.type != 'Identity') {\n return;\n }\n if (typeof doc.user_id === \"undefined\") {\n emit(doc._id, 1);\n }\n }\n"
+ },
+ "all": {
+ "map": " function(doc) {\n if (doc['type'] == 'Identity') {\n emit(doc._id, null);\n }\n }\n"
+ }
+ },
+ "couchrest-hash": "e9004d70e26770c621a9667536429a68"
+} \ No newline at end of file
diff --git a/puppet/modules/site_couchdb/files/designs/messages/Message.json b/puppet/modules/site_couchdb/files/designs/messages/Message.json
new file mode 100644
index 00000000..7bcd74c7
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/designs/messages/Message.json
@@ -0,0 +1,18 @@
+{
+ "_id": "_design/Message",
+ "language": "javascript",
+ "views": {
+ "by_user_ids_to_show_and_created_at": {
+ "map": "// not using at moment\n// call with something like Message.by_user_ids_to_show_and_created_at.startkey([user_id, start_date]).endkey([user_id,end_date])\nfunction (doc) {\n if (doc.type === 'Message' && doc.user_ids_to_show && Array.isArray(doc.user_ids_to_show)) {\n doc.user_ids_to_show.forEach(function (userId) {\n emit([userId, doc.created_at], 1);\n });\n }\n}\n",
+ "reduce": "function(key, values, rereduce) { return sum(values); }"
+ },
+ "by_user_ids_to_show": {
+ "map": "function (doc) {\n if (doc.type === 'Message' && doc.user_ids_to_show && Array.isArray(doc.user_ids_to_show)) {\n doc.user_ids_to_show.forEach(function (userId) {\n emit(userId, 1);\n });\n }\n}\n",
+ "reduce": "function(key, values, rereduce) { return sum(values); }"
+ },
+ "all": {
+ "map": " function(doc) {\n if (doc['type'] == 'Message') {\n emit(doc._id, null);\n }\n }\n"
+ }
+ },
+ "couchrest-hash": "0967e7cc5bb1e61edc1c085f6f0cecbf"
+} \ No newline at end of file
diff --git a/puppet/modules/site_couchdb/files/designs/sessions/Session.json b/puppet/modules/site_couchdb/files/designs/sessions/Session.json
new file mode 100644
index 00000000..70202780
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/designs/sessions/Session.json
@@ -0,0 +1,8 @@
+{
+ "views": {
+ "by_expires": {
+ "reduce": "_sum",
+ "map": "function(doc) {\n if(typeof doc.expires !== \"undefined\") {\n emit(doc.expires, 1);\n }\n}\n"
+ }
+ }
+}
diff --git a/puppet/modules/site_couchdb/files/designs/shared/docs.json b/puppet/modules/site_couchdb/files/designs/shared/docs.json
new file mode 100644
index 00000000..004180cd
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/designs/shared/docs.json
@@ -0,0 +1,8 @@
+{
+ "_id": "_design/docs",
+ "views": {
+ "get": {
+ "map": "function(doc) {\n if (doc.u1db_rev) {\n var is_tombstone = true;\n var has_conflicts = false;\n if (doc._attachments) {\n if (doc._attachments.u1db_content)\n is_tombstone = false;\n if (doc._attachments.u1db_conflicts)\n has_conflicts = true;\n }\n emit(doc._id,\n {\n \"couch_rev\": doc._rev,\n \"u1db_rev\": doc.u1db_rev,\n \"is_tombstone\": is_tombstone,\n \"has_conflicts\": has_conflicts,\n }\n );\n }\n}\n"
+ }
+ }
+} \ No newline at end of file
diff --git a/puppet/modules/site_couchdb/files/designs/shared/syncs.json b/puppet/modules/site_couchdb/files/designs/shared/syncs.json
new file mode 100644
index 00000000..bab5622f
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/designs/shared/syncs.json
@@ -0,0 +1,11 @@
+{
+ "_id": "_design/syncs",
+ "updates": {
+ "put": "function(doc, req){\n if (!doc) {\n doc = {}\n doc['_id'] = 'u1db_sync_log';\n doc['syncs'] = [];\n }\n body = JSON.parse(req.body);\n // remove outdated info\n doc['syncs'] = doc['syncs'].filter(\n function (entry) {\n return entry[0] != body['other_replica_uid'];\n }\n );\n // store u1db rev\n doc['syncs'].push([\n body['other_replica_uid'],\n body['other_generation'],\n body['other_transaction_id']\n ]);\n return [doc, 'ok'];\n}\n\n"
+ },
+ "views": {
+ "log": {
+ "map": "function(doc) {\n if (doc._id == 'u1db_sync_log') {\n if (doc.syncs)\n doc.syncs.forEach(function (entry) {\n emit(entry[0],\n {\n 'known_generation': entry[1],\n 'known_transaction_id': entry[2]\n });\n });\n }\n}\n"
+ }
+ }
+} \ No newline at end of file
diff --git a/puppet/modules/site_couchdb/files/designs/shared/transactions.json b/puppet/modules/site_couchdb/files/designs/shared/transactions.json
new file mode 100644
index 00000000..106ad46c
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/designs/shared/transactions.json
@@ -0,0 +1,13 @@
+{
+ "_id": "_design/transactions",
+ "lists": {
+ "generation": "function(head, req) {\n var row;\n var rows=[];\n // fetch all rows\n while(row = getRow()) {\n rows.push(row);\n }\n if (rows.length > 0)\n send(JSON.stringify({\n \"generation\": rows.length,\n \"doc_id\": rows[rows.length-1]['id'],\n \"transaction_id\": rows[rows.length-1]['value']\n }));\n else\n send(JSON.stringify({\n \"generation\": 0,\n \"doc_id\": \"\",\n \"transaction_id\": \"\",\n }));\n}\n",
+ "trans_id_for_gen": "function(head, req) {\n var row;\n var rows=[];\n var i = 1;\n var gen = 1;\n if (req.query.gen)\n gen = parseInt(req.query['gen']);\n // fetch all rows\n while(row = getRow())\n rows.push(row);\n if (gen <= rows.length)\n send(JSON.stringify({\n \"generation\": gen,\n \"doc_id\": rows[gen-1]['id'],\n \"transaction_id\": rows[gen-1]['value'],\n }));\n else\n send('{}');\n}\n",
+ "whats_changed": "function(head, req) {\n var row;\n var gen = 1;\n var old_gen = 0;\n if (req.query.old_gen)\n old_gen = parseInt(req.query['old_gen']);\n send('{\"transactions\":[\\n');\n // fetch all rows\n while(row = getRow()) {\n if (gen > old_gen) {\n if (gen > old_gen+1)\n send(',\\n');\n send(JSON.stringify({\n \"generation\": gen,\n \"doc_id\": row[\"id\"],\n \"transaction_id\": row[\"value\"]\n }));\n }\n gen++;\n }\n send('\\n]}');\n}\n"
+ },
+ "views": {
+ "log": {
+ "map": "function(doc) {\n if (doc.u1db_transactions)\n doc.u1db_transactions.forEach(function(t) {\n emit(t[0], // use timestamp as key so the results are ordered\n t[1]); // value is the transaction_id\n });\n}\n"
+ }
+ }
+} \ No newline at end of file
diff --git a/puppet/modules/site_couchdb/files/designs/tickets/Ticket.json b/puppet/modules/site_couchdb/files/designs/tickets/Ticket.json
new file mode 100644
index 00000000..2c9408b8
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/designs/tickets/Ticket.json
@@ -0,0 +1,50 @@
+{
+ "_id": "_design/Ticket",
+ "language": "javascript",
+ "views": {
+ "by_updated_at": {
+ "map": " function(doc) {\n if ((doc['type'] == 'Ticket') && (doc['updated_at'] != null)) {\n emit(doc['updated_at'], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "by_created_at": {
+ "map": " function(doc) {\n if ((doc['type'] == 'Ticket') && (doc['created_at'] != null)) {\n emit(doc['created_at'], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "by_created_by": {
+ "map": " function(doc) {\n if ((doc['type'] == 'Ticket') && (doc['created_by'] != null)) {\n emit(doc['created_by'], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "by_is_open_and_created_at": {
+ "map": " function(doc) {\n if ((doc['type'] == 'Ticket') && (doc['is_open'] != null) && (doc['created_at'] != null)) {\n emit([doc['is_open'], doc['created_at']], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "by_is_open_and_updated_at": {
+ "map": " function(doc) {\n if ((doc['type'] == 'Ticket') && (doc['is_open'] != null) && (doc['updated_at'] != null)) {\n emit([doc['is_open'], doc['updated_at']], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "by_includes_post_by_and_is_open_and_created_at": {
+ "map": "function(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit([comment.posted_by, doc.is_open, doc.created_at], 1);\n }\n });\n }\n}\n",
+ "reduce": "function(key, values, rereduce) { return sum(values); }"
+ },
+ "by_includes_post_by_and_is_open_and_updated_at": {
+ "map": "function(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit([comment.posted_by, doc.is_open, doc.updated_at], 1);\n }\n });\n }\n}\n",
+ "reduce": "function(key, values, rereduce) { return sum(values); }"
+ },
+ "by_includes_post_by_and_updated_at": {
+ "map": "function(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit([comment.posted_by, doc.updated_at], 1);\n }\n });\n }\n}\n",
+ "reduce": "function(key, values, rereduce) { return sum(values); }"
+ },
+ "by_includes_post_by": {
+ "map": "// TODO: This view is only used in tests--should we keep it?\nfunction(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit(comment.posted_by, 1);\n }\n });\n }\n}\n",
+ "reduce": "function(key, values, rereduce) { return sum(values); }"
+ },
+ "by_includes_post_by_and_created_at": {
+ "map": "function(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit([comment.posted_by, doc.created_at], 1);\n }\n });\n }\n}\n",
+ "reduce": "function(key, values, rereduce) { return sum(values); }"
+ },
+ "all": {
+ "map": " function(doc) {\n if (doc['type'] == 'Ticket') {\n emit(doc._id, null);\n }\n }\n"
+ }
+ },
+ "couchrest-hash": "9978e2cbeacbe8622c2a7f103bf8130f"
+} \ No newline at end of file
diff --git a/puppet/modules/site_couchdb/files/designs/tokens/Token.json b/puppet/modules/site_couchdb/files/designs/tokens/Token.json
new file mode 100644
index 00000000..b9025f15
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/designs/tokens/Token.json
@@ -0,0 +1,14 @@
+{
+ "_id": "_design/Token",
+ "language": "javascript",
+ "views": {
+ "by_last_seen_at": {
+ "map": " function(doc) {\n if ((doc['type'] == 'Token') && (doc['last_seen_at'] != null)) {\n emit(doc['last_seen_at'], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "all": {
+ "map": " function(doc) {\n if (doc['type'] == 'Token') {\n emit(doc._id, null);\n }\n }\n"
+ }
+ },
+ "couchrest-hash": "541dd924551c42a2317b345effbe65cc"
+} \ No newline at end of file
diff --git a/puppet/modules/site_couchdb/files/designs/users/User.json b/puppet/modules/site_couchdb/files/designs/users/User.json
new file mode 100644
index 00000000..4089ad97
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/designs/users/User.json
@@ -0,0 +1,22 @@
+{
+ "_id": "_design/User",
+ "language": "javascript",
+ "views": {
+ "by_login": {
+ "map": " function(doc) {\n if ((doc['type'] == 'User') && (doc['login'] != null)) {\n emit(doc['login'], 1);\n }\n }\n",
+ "reduce": "_sum"
+ },
+ "all": {
+ "map": " function(doc) {\n if (doc['type'] == 'User') {\n emit(doc._id, null);\n }\n }\n"
+ },
+ "by_created_at_and_one_month_warning_not_sent": {
+ "map": "function (doc) {\n if ((doc['type'] == 'User') && (doc['created_at'] != null) && (doc['one_month_warning_sent'] == null)) {\n emit(doc['created_at'], 1);\n } \n}\n",
+ "reduce": "function(key, values, rereduce) { return sum(values); }"
+ },
+ "by_created_at": {
+ "map": " function(doc) {\n if ((doc['type'] == 'User') && (doc['created_at'] != null)) {\n emit(doc['created_at'], 1);\n }\n }\n",
+ "reduce": "_sum"
+ }
+ },
+ "couchrest-hash": "61840ab3ec0f94ef8bbd6dd208db3b70"
+} \ No newline at end of file
diff --git a/puppet/modules/site_couchdb/manifests/add_users.pp b/puppet/modules/site_couchdb/manifests/add_users.pp
new file mode 100644
index 00000000..f9ea7349
--- /dev/null
+++ b/puppet/modules/site_couchdb/manifests/add_users.pp
@@ -0,0 +1,54 @@
+class site_couchdb::add_users {
+
+ # Couchdb users
+
+ ## leap_mx couchdb user
+ ## read: identities
+ ## write access to user-<uuid>
+ couchdb::add_user { $site_couchdb::couchdb_leap_mx_user:
+ roles => '["identities"]',
+ pw => $site_couchdb::couchdb_leap_mx_pw,
+ salt => $site_couchdb::couchdb_leap_mx_salt,
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ## nickserver couchdb user
+ ## r: identities
+ ## r/w: keycache
+ couchdb::add_user { $site_couchdb::couchdb_nickserver_user:
+ roles => '["identities","keycache"]',
+ pw => $site_couchdb::couchdb_nickserver_pw,
+ salt => $site_couchdb::couchdb_nickserver_salt,
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ## soledad couchdb user
+ ## r/w: user-<uuid>, shared
+ ## read: tokens
+ couchdb::add_user { $site_couchdb::couchdb_soledad_user:
+ roles => '["tokens"]',
+ pw => $site_couchdb::couchdb_soledad_pw,
+ salt => $site_couchdb::couchdb_soledad_salt,
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ### tapicero couchdb user
+ ### admin: needs to be able to create user-<uuid> databases
+ ### read: users
+ couchdb::add_user { $site_couchdb::couchdb_tapicero_user:
+ roles => '["users"]',
+ pw => $site_couchdb::couchdb_tapicero_pw,
+ salt => $site_couchdb::couchdb_tapicero_salt,
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ## webapp couchdb user
+ ## read/write: users, tokens, sessions, tickets, identities, customer
+ couchdb::add_user { $site_couchdb::couchdb_webapp_user:
+ roles => '["tokens","identities","users"]',
+ pw => $site_couchdb::couchdb_webapp_pw,
+ salt => $site_couchdb::couchdb_webapp_salt,
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+}
diff --git a/puppet/modules/site_couchdb/manifests/backup.pp b/puppet/modules/site_couchdb/manifests/backup.pp
new file mode 100644
index 00000000..8b5aa6ea
--- /dev/null
+++ b/puppet/modules/site_couchdb/manifests/backup.pp
@@ -0,0 +1,23 @@
+class site_couchdb::backup {
+
+ # general backupninja config
+ backupninja::config { 'backupninja_config':
+ usecolors => false,
+ }
+
+ # dump all DBs locally to /var/backups/couchdb once a day
+ backupninja::sh { 'couchdb_backup':
+ command_string => "cd /srv/leap/couchdb/scripts \n./couchdb_dumpall.sh"
+ }
+
+ # Deploy /etc/leap/couchdb_scripts_defaults.conf so we can exclude
+ # some databases
+
+ file { '/etc/leap/couchdb_scripts_defaults.conf':
+ source => 'puppet:///modules/site_couchdb/couchdb_scripts_defaults.conf',
+ mode => '0644',
+ owner => 'root',
+ group => 'root',
+ }
+
+}
diff --git a/puppet/modules/site_couchdb/manifests/bigcouch/add_nodes.pp b/puppet/modules/site_couchdb/manifests/bigcouch/add_nodes.pp
index 241a4914..97e85785 100644
--- a/puppet/modules/site_couchdb/manifests/bigcouch/add_nodes.pp
+++ b/puppet/modules/site_couchdb/manifests/bigcouch/add_nodes.pp
@@ -1,5 +1,8 @@
class site_couchdb::bigcouch::add_nodes {
# loop through neighbors array and add nodes
$nodes = $::site_couchdb::bigcouch_config['neighbors']
- couchdb::bigcouch::add_node { $nodes: }
+
+ 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
new file mode 100644
index 00000000..84aab4ef
--- /dev/null
+++ b/puppet/modules/site_couchdb/manifests/bigcouch/compaction.pp
@@ -0,0 +1,8 @@
+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
new file mode 100644
index 00000000..aa843e2e
--- /dev/null
+++ b/puppet/modules/site_couchdb/manifests/bigcouch/settle_cluster.pp
@@ -0,0 +1,11 @@
+class site_couchdb::bigcouch::settle_cluster {
+
+ exec { 'wait_for_couch_nodes':
+ command => '/srv/leap/bin/run_tests --test CouchDB/Are_configured_nodes_online? --retry 6 --wait 10'
+ }
+
+ exec { 'settle_cluster_membership':
+ command => '/srv/leap/bin/run_tests --test CouchDB/Is_cluster_membership_ok? --retry 6 --wait 10',
+ require => Exec['wait_for_couch_nodes']
+ }
+}
diff --git a/puppet/modules/site_couchdb/manifests/create_dbs.pp b/puppet/modules/site_couchdb/manifests/create_dbs.pp
new file mode 100644
index 00000000..41500d3a
--- /dev/null
+++ b/puppet/modules/site_couchdb/manifests/create_dbs.pp
@@ -0,0 +1,70 @@
+class site_couchdb::create_dbs {
+
+ # Couchdb databases
+
+ ### customer database
+ ### r/w: webapp,
+ couchdb::create_db { 'customers':
+ members => "{ \"names\": [\"$site_couchdb::couchdb_webapp_user\"], \"roles\": [] }",
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ## identities database
+ ## r: nickserver, leap_mx - needs to be restrict with design document
+ ## r/w: webapp
+ couchdb::create_db { 'identities':
+ members => "{ \"names\": [], \"roles\": [\"identities\"] }",
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ## keycache database
+ ## r/w: nickserver
+ couchdb::create_db { 'keycache':
+ members => "{ \"names\": [], \"roles\": [\"keycache\"] }",
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ## sessions database
+ ## r/w: webapp
+ couchdb::create_db { 'sessions':
+ members => "{ \"names\": [\"$site_couchdb::couchdb_webapp_user\"], \"roles\": [] }",
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ## shared database
+ ## r/w: soledad
+ couchdb::create_db { 'shared':
+ members => "{ \"names\": [\"$site_couchdb::couchdb_soledad_user\"], \"roles\": [] }",
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ## tickets database
+ ## r/w: webapp
+ couchdb::create_db { 'tickets':
+ members => "{ \"names\": [\"$site_couchdb::couchdb_webapp_user\"], \"roles\": [] }",
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ## tokens database
+ ## r: soledad - needs to be restricted with a design document
+ ## r/w: webapp
+ couchdb::create_db { 'tokens':
+ members => "{ \"names\": [], \"roles\": [\"tokens\"] }",
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ## users database
+ ## r/w: webapp
+ couchdb::create_db { 'users':
+ members => "{ \"names\": [], \"roles\": [\"users\"] }",
+ require => Couchdb::Query::Setup['localhost']
+ }
+
+ ## messages db
+ ## store messages to the clients such as payment reminders
+ ## r/w: webapp
+ couchdb::create_db { 'messages':
+ members => "{ \"names\": [\"$site_couchdb::couchdb_webapp_user\"], \"roles\": [] }",
+ require => Couchdb::Query::Setup['localhost']
+ }
+}
diff --git a/puppet/modules/site_couchdb/manifests/designs.pp b/puppet/modules/site_couchdb/manifests/designs.pp
new file mode 100644
index 00000000..9e88de64
--- /dev/null
+++ b/puppet/modules/site_couchdb/manifests/designs.pp
@@ -0,0 +1,20 @@
+class site_couchdb::designs {
+
+ Class['site_couchdb::create_dbs']
+ -> Class['site_couchdb::designs']
+
+ file { '/srv/leap/couchdb/designs':
+ ensure => directory,
+ source => 'puppet:///modules/site_couchdb/designs',
+ recurse => true,
+ purge => true,
+ mode => '0755'
+ }
+
+ exec { '/srv/leap/couchdb/scripts/load_design_documents.sh':
+ require => Vcsrepo['/srv/leap/couchdb/scripts'],
+ refreshonly => false
+ }
+
+}
+
diff --git a/puppet/modules/site_couchdb/manifests/init.pp b/puppet/modules/site_couchdb/manifests/init.pp
index 802f3224..3614661d 100644
--- a/puppet/modules/site_couchdb/manifests/init.pp
+++ b/puppet/modules/site_couchdb/manifests/init.pp
@@ -1,83 +1,118 @@
class site_couchdb {
tag 'leap_service'
- $x509 = hiera('x509')
- $key = $x509['key']
- $cert = $x509['cert']
- $ca = $x509['ca_cert']
-
- $couchdb_config = hiera('couch')
- $couchdb_users = $couchdb_config['users']
- $couchdb_admin = $couchdb_users['admin']
- $couchdb_admin_user = $couchdb_admin['username']
- $couchdb_admin_pw = $couchdb_admin['password']
- $couchdb_admin_salt = $couchdb_admin['salt']
- $couchdb_webapp = $couchdb_users['webapp']
- $couchdb_webapp_user = $couchdb_webapp['username']
- $couchdb_webapp_pw = $couchdb_webapp['password']
- $couchdb_webapp_salt = $couchdb_webapp['salt']
- $couchdb_soledad = $couchdb_users['soledad']
- $couchdb_soledad_user = $couchdb_soledad['username']
- $couchdb_soledad_pw = $couchdb_soledad['password']
- $couchdb_soledad_salt = $couchdb_soledad['salt']
-
- $bigcouch_config = $couchdb_config['bigcouch']
- $bigcouch_cookie = $bigcouch_config['cookie']
-
- $ednp_port = $bigcouch_config['ednp_port']
+ $couchdb_config = hiera('couch')
+ $couchdb_users = $couchdb_config['users']
+
+ $couchdb_admin = $couchdb_users['admin']
+ $couchdb_admin_user = $couchdb_admin['username']
+ $couchdb_admin_pw = $couchdb_admin['password']
+ $couchdb_admin_salt = $couchdb_admin['salt']
+
+ $couchdb_leap_mx = $couchdb_users['leap_mx']
+ $couchdb_leap_mx_user = $couchdb_leap_mx['username']
+ $couchdb_leap_mx_pw = $couchdb_leap_mx['password']
+ $couchdb_leap_mx_salt = $couchdb_leap_mx['salt']
+
+ $couchdb_nickserver = $couchdb_users['nickserver']
+ $couchdb_nickserver_user = $couchdb_nickserver['username']
+ $couchdb_nickserver_pw = $couchdb_nickserver['password']
+ $couchdb_nickserver_salt = $couchdb_nickserver['salt']
+
+ $couchdb_soledad = $couchdb_users['soledad']
+ $couchdb_soledad_user = $couchdb_soledad['username']
+ $couchdb_soledad_pw = $couchdb_soledad['password']
+ $couchdb_soledad_salt = $couchdb_soledad['salt']
+
+ $couchdb_tapicero = $couchdb_users['tapicero']
+ $couchdb_tapicero_user = $couchdb_tapicero['username']
+ $couchdb_tapicero_pw = $couchdb_tapicero['password']
+ $couchdb_tapicero_salt = $couchdb_tapicero['salt']
+
+ $couchdb_webapp = $couchdb_users['webapp']
+ $couchdb_webapp_user = $couchdb_webapp['username']
+ $couchdb_webapp_pw = $couchdb_webapp['password']
+ $couchdb_webapp_salt = $couchdb_webapp['salt']
+
+ $couchdb_backup = $couchdb_config['backup']
+
+ $bigcouch_config = $couchdb_config['bigcouch']
+ $bigcouch_cookie = $bigcouch_config['cookie']
+
+ $ednp_port = $bigcouch_config['ednp_port']
class { 'couchdb':
- bigcouch => true,
- admin_pw => $couchdb_admin_pw,
- admin_salt => $couchdb_admin_salt,
- bigcouch_cookie => $bigcouch_cookie,
- ednp_port => $ednp_port
+ bigcouch => true,
+ admin_pw => $couchdb_admin_pw,
+ admin_salt => $couchdb_admin_salt,
+ bigcouch_cookie => $bigcouch_cookie,
+ ednp_port => $ednp_port,
+ chttpd_bind_address => '127.0.0.1'
+ }
+
+ # 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
}
- class { 'couchdb::bigcouch::package::cloudant': }
+ Class['site_config::default']
+ -> Class['couchdb::bigcouch::package::cloudant']
+ -> Service['shorewall']
+ -> Class['site_couchdb::stunnel']
+ -> Service['couchdb']
+ -> File['/root/.netrc']
+ -> Class['site_couchdb::bigcouch::add_nodes']
+ -> Class['site_couchdb::bigcouch::settle_cluster']
+ -> Class['site_couchdb::create_dbs']
+ -> Class['site_couchdb::add_users']
- Class ['couchdb::bigcouch::package::cloudant']
- -> Service ['couchdb']
- -> Class ['site_couchdb::bigcouch::add_nodes']
- -> Couchdb::Create_db['users']
- -> Couchdb::Create_db['tokens']
- -> Couchdb::Add_user[$couchdb_webapp_user]
- -> Couchdb::Add_user[$couchdb_soledad_user]
+ # /etc/couchdb/couchdb.netrc is deployed by couchdb::query::setup
+ # we symlink this to /root/.netrc for couchdb_scripts (eg. backup)
+ # and makes life easier for the admin (i.e. using curl/wget without
+ # passing credentials)
+ file {
+ '/root/.netrc':
+ ensure => link,
+ target => '/etc/couchdb/couchdb.netrc';
- class { 'site_couchdb::stunnel':
- key => $key,
- cert => $cert,
- ca => $ca
+ '/srv/leap/couchdb':
+ ensure => directory
}
- class { 'site_couchdb::bigcouch::add_nodes': }
-
couchdb::query::setup { 'localhost':
user => $couchdb_admin_user,
pw => $couchdb_admin_pw,
}
- # Populate couchdb
- couchdb::add_user { $couchdb_webapp_user:
- roles => '["auth"]',
- pw => $couchdb_webapp_pw,
- salt => $couchdb_webapp_salt
+ vcsrepo { '/srv/leap/couchdb/scripts':
+ ensure => present,
+ provider => git,
+ source => 'https://leap.se/git/couchdb_scripts',
+ revision => 'origin/master',
+ require => File['/srv/leap/couchdb']
}
- couchdb::add_user { $couchdb_soledad_user:
- roles => '["auth"]',
- pw => $couchdb_soledad_pw,
- salt => $couchdb_soledad_salt
- }
-
- couchdb::create_db { 'users':
- readers => "{ \"names\": [\"$couchdb_webapp_user\"], \"roles\": [] }"
- }
+ include site_couchdb::stunnel
+ include site_couchdb::bigcouch::add_nodes
+ include site_couchdb::bigcouch::settle_cluster
+ include site_couchdb::create_dbs
+ include site_couchdb::add_users
+ include site_couchdb::designs
+ include site_couchdb::logrotate
+ include site_couchdb::bigcouch::compaction
- couchdb::create_db { 'tokens':
- readers => "{ \"names\": [], \"roles\": [\"auth\"] }"
- }
+ if $couchdb_backup { include site_couchdb::backup }
include site_shorewall::couchdb
include site_shorewall::couchdb::bigcouch
+
+ include site_check_mk::agent::couchdb
+ include site_check_mk::agent::tapicero
+
+ file { '/var/log/bigcouch':
+ ensure => directory
+ }
+
}
diff --git a/puppet/modules/site_couchdb/manifests/logrotate.pp b/puppet/modules/site_couchdb/manifests/logrotate.pp
new file mode 100644
index 00000000..e1039d49
--- /dev/null
+++ b/puppet/modules/site_couchdb/manifests/logrotate.pp
@@ -0,0 +1,12 @@
+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/stunnel.pp b/puppet/modules/site_couchdb/manifests/stunnel.pp
index d982013e..91f1e3aa 100644
--- a/puppet/modules/site_couchdb/manifests/stunnel.pp
+++ b/puppet/modules/site_couchdb/manifests/stunnel.pp
@@ -1,4 +1,4 @@
-class site_couchdb::stunnel ($key, $cert, $ca) {
+class site_couchdb::stunnel {
$stunnel = hiera('stunnel')
@@ -18,22 +18,16 @@ class site_couchdb::stunnel ($key, $cert, $ca) {
$ednp_server_connect = $ednp_server['connect']
$ednp_clients = $stunnel['ednp_clients']
+
+
+ include site_config::x509::cert
+ include site_config::x509::key
+ include site_config::x509::ca
+
include x509::variables
- $cert_name = 'leap_couchdb'
- $ca_name = 'leap_ca'
- $ca_path = "${x509::variables::local_CAs}/${ca_name}.crt"
- $cert_path = "${x509::variables::certs}/${cert_name}.crt"
- $key_path = "${x509::variables::keys}/${cert_name}.key"
-
- # basic setup: ensure cert, key, ca files are in place, and some generic
- # stunnel things are done
- class { 'site_stunnel::setup':
- cert_name => $cert_name,
- key => $key,
- cert => $cert,
- ca_name => $ca_name,
- ca => $ca
- }
+ $ca_path = "${x509::variables::local_CAs}/${site_config::params::ca_name}.crt"
+ $cert_path = "${x509::variables::certs}/${site_config::params::cert_name}.crt"
+ $key_path = "${x509::variables::keys}/${site_config::params::cert_name}.key"
# setup a stunnel server for the webapp to connect to couchdb
stunnel::service { 'couch_server':
@@ -46,7 +40,11 @@ class site_couchdb::stunnel ($key, $cert, $ca) {
verify => '2',
pid => '/var/run/stunnel4/couchserver.pid',
rndfile => '/var/lib/stunnel4/.rnd',
- debuglevel => '4'
+ debuglevel => '4',
+ require => [
+ Class['Site_config::X509::Key'],
+ Class['Site_config::X509::Cert'],
+ Class['Site_config::X509::Ca'] ];
}
@@ -62,7 +60,11 @@ class site_couchdb::stunnel ($key, $cert, $ca) {
verify => '2',
pid => '/var/run/stunnel4/epmd_server.pid',
rndfile => '/var/lib/stunnel4/.rnd',
- debuglevel => '4'
+ debuglevel => '4',
+ require => [
+ Class['Site_config::X509::Key'],
+ Class['Site_config::X509::Cert'],
+ Class['Site_config::X509::Ca'] ];
}
# setup stunnel clients for Erlang Port Mapper Daemon (epmd) to connect
@@ -88,7 +90,11 @@ class site_couchdb::stunnel ($key, $cert, $ca) {
verify => '2',
pid => '/var/run/stunnel4/ednp_server.pid',
rndfile => '/var/lib/stunnel4/.rnd',
- debuglevel => '4'
+ debuglevel => '4',
+ require => [
+ Class['Site_config::X509::Key'],
+ Class['Site_config::X509::Cert'],
+ Class['Site_config::X509::Ca'] ];
}
# setup stunnel clients for Erlang Distributed Node Protocol (ednp) to connect
@@ -101,4 +107,6 @@ class site_couchdb::stunnel ($key, $cert, $ca) {
}
create_resources(site_stunnel::clients, $ednp_clients, $ednp_client_defaults)
+
+ include site_check_mk::agent::stunnel
}
diff --git a/puppet/modules/site_haproxy/files/haproxy-stats.cfg b/puppet/modules/site_haproxy/files/haproxy-stats.cfg
new file mode 100644
index 00000000..e6335ba2
--- /dev/null
+++ b/puppet/modules/site_haproxy/files/haproxy-stats.cfg
@@ -0,0 +1,6 @@
+# provide access to stats for the nagios plugin
+listen stats 127.0.0.1:8000
+ mode http
+ stats enable
+ stats uri /haproxy
+
diff --git a/puppet/modules/site_haproxy/manifests/init.pp b/puppet/modules/site_haproxy/manifests/init.pp
index ace88a7b..1a681373 100644
--- a/puppet/modules/site_haproxy/manifests/init.pp
+++ b/puppet/modules/site_haproxy/manifests/init.pp
@@ -2,7 +2,6 @@ class site_haproxy {
class { 'haproxy':
enable => true,
- version => '1.4.23-0.1~leap60+1',
manage_service => true,
global_options => {
'log' => '127.0.0.1 local0',
@@ -23,4 +22,11 @@ class site_haproxy {
}
}
+ # monitor haproxy
+ concat::fragment { 'stats':
+ target => '/etc/haproxy/haproxy.cfg',
+ order => '90',
+ source => 'puppet:///modules/site_haproxy/haproxy-stats.cfg';
+ }
+ include site_check_mk::agent::haproxy
}
diff --git a/puppet/modules/site_mx/manifests/couchdb.pp b/puppet/modules/site_mx/manifests/couchdb.pp
new file mode 100644
index 00000000..b1f3bd02
--- /dev/null
+++ b/puppet/modules/site_mx/manifests/couchdb.pp
@@ -0,0 +1,23 @@
+class site_mx::couchdb {
+
+ $stunnel = hiera('stunnel')
+ $couch_client = $stunnel['couch_client']
+ $couch_client_connect = $couch_client['connect']
+
+ include x509::variables
+ $ca_path = "${x509::variables::local_CAs}/${site_config::params::ca_name}.crt"
+ $cert_path = "${x509::variables::certs}/${site_config::params::cert_name}.crt"
+ $key_path = "${x509::variables::keys}/${site_config::params::cert_name}.key"
+
+ include site_stunnel
+
+ $couchdb_stunnel_client_defaults = {
+ 'connect_port' => $couch_client_connect,
+ 'client' => true,
+ 'cafile' => $ca_path,
+ 'key' => $key_path,
+ 'cert' => $cert_path,
+ }
+
+ create_resources(site_stunnel::clients, $couch_client, $couchdb_stunnel_client_defaults)
+}
diff --git a/puppet/modules/site_mx/manifests/haproxy.pp b/puppet/modules/site_mx/manifests/haproxy.pp
new file mode 100644
index 00000000..988eeaf3
--- /dev/null
+++ b/puppet/modules/site_mx/manifests/haproxy.pp
@@ -0,0 +1,14 @@
+class site_mx::haproxy {
+
+ include site_haproxy
+
+ $haproxy = hiera('haproxy')
+ $local_ports = $haproxy['local_ports']
+
+ # Template uses $global_options, $defaults_options
+ concat::fragment { 'leap_haproxy_webapp_couchdb':
+ target => '/etc/haproxy/haproxy.cfg',
+ order => '20',
+ content => template('site_webapp/haproxy_couchdb.cfg.erb'),
+ }
+}
diff --git a/puppet/modules/site_mx/manifests/init.pp b/puppet/modules/site_mx/manifests/init.pp
new file mode 100644
index 00000000..3949c787
--- /dev/null
+++ b/puppet/modules/site_mx/manifests/init.pp
@@ -0,0 +1,19 @@
+class site_mx {
+ tag 'leap_service'
+ Class['site_config::default'] -> Class['site_mx']
+
+ 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_postfix::mx
+ include site_mx::haproxy
+ include site_shorewall::mx
+ include site_shorewall::service::smtp
+ include site_mx::couchdb
+ include leap_mx
+ include site_check_mk::agent::mx
+}
diff --git a/puppet/modules/site_nagios/files/configs/Debian/nagios.cfg b/puppet/modules/site_nagios/files/configs/Debian/nagios.cfg
index 753d1610..e46ebf62 100644
--- a/puppet/modules/site_nagios/files/configs/Debian/nagios.cfg
+++ b/puppet/modules/site_nagios/files/configs/Debian/nagios.cfg
@@ -1,6 +1,6 @@
##############################################################################
#
-# NAGIOS.CFG - Sample Main Config File for Nagios
+# NAGIOS.CFG - Sample Main Config File for Nagios
#
#
##############################################################################
@@ -8,7 +8,7 @@
# LOG FILE
# This is the main log file where service and host events are logged
-# for historical purposes. This should be the first option specified
+# for historical purposes. This should be the first option specified
# in the config file!!!
log_file=/var/log/nagios3/nagios.log
@@ -25,6 +25,9 @@ log_file=/var/log/nagios3/nagios.log
# Puppet-managed configuration files
cfg_dir=/etc/nagios3/conf.d
+# check-mk managed configuration files
+cfg_dir=/etc/nagios3/local
+
# Debian also defaults to using the check commands defined by the debian
# nagios-plugins package
cfg_dir=/etc/nagios-plugins/config
@@ -33,7 +36,7 @@ cfg_dir=/etc/nagios-plugins/config
# OBJECT CACHE FILE
# This option determines where object definitions are cached when
-# Nagios starts/restarts. The CGIs read object definitions from
+# Nagios starts/restarts. The CGIs read object definitions from
# this cache file (rather than looking at the object config files
# directly) in order to prevent inconsistencies that can occur
# when the config files are modified after Nagios starts.
@@ -49,7 +52,7 @@ object_cache_file=/var/cache/nagios3/objects.cache
# file. You can then start Nagios with the -u option to have it read
# object definitions from this precached file, rather than the standard
# object configuration files (see the cfg_file and cfg_dir options above).
-# Using a precached object file can speed up the time needed to (re)start
+# Using a precached object file can speed up the time needed to (re)start
# the Nagios process if you've got a large and/or complex configuration.
# Read the documentation section on optimizing Nagios to find our more
# about how this feature works.
@@ -83,7 +86,7 @@ status_file=/var/cache/nagios3/status.dat
# STATUS FILE UPDATE INTERVAL
# This option determines the frequency (in seconds) that
-# Nagios will periodically dump program, host, and
+# Nagios will periodically dump program, host, and
# service status data.
status_update_interval=10
@@ -91,7 +94,7 @@ status_update_interval=10
# NAGIOS USER
-# This determines the effective user that Nagios should run as.
+# This determines the effective user that Nagios should run as.
# You can either supply a username or a UID.
nagios_user=nagios
@@ -99,7 +102,7 @@ nagios_user=nagios
# NAGIOS GROUP
-# This determines the effective group that Nagios should run as.
+# This determines the effective group that Nagios should run as.
# You can either supply a group name or a GID.
nagios_group=nagios
@@ -125,7 +128,7 @@ check_external_commands=1
# Nagios to check for external commands every minute. If you specify a
# number followed by an "s" (i.e. 15s), this will be interpreted to mean
# actual seconds rather than a multiple of the interval_length variable.
-# Note: In addition to reading the external command file at regularly
+# Note: In addition to reading the external command file at regularly
# scheduled intervals, Nagios will also check for external commands after
# event handlers are executed.
# NOTE: Setting this value to -1 causes Nagios to check the external
@@ -140,7 +143,7 @@ command_check_interval=-1
# This is the file that Nagios checks for external command requests.
# It is also where the command CGI will write commands that are submitted
# by users, so it must be writeable by the user that the web server
-# is running as (usually 'nobody'). Permissions should be set at the
+# is running as (usually 'nobody'). Permissions should be set at the
# directory level instead of on the file, as the file is deleted every
# time its contents are processed.
# Debian Users: In case you didn't read README.Debian yet, _NOW_ is the
@@ -152,9 +155,9 @@ command_file=/var/lib/nagios3/rw/nagios.cmd
# EXTERNAL COMMAND BUFFER SLOTS
# This settings is used to tweak the number of items or "slots" that
-# the Nagios daemon should allocate to the buffer that holds incoming
-# external commands before they are processed. As external commands
-# are processed by the daemon, they are removed from the buffer.
+# the Nagios daemon should allocate to the buffer that holds incoming
+# external commands before they are processed. As external commands
+# are processed by the daemon, they are removed from the buffer.
external_command_buffer_slots=4096
@@ -232,12 +235,12 @@ event_broker_options=-1
# w = Weekly rotation (midnight on Saturday evening)
# m = Monthly rotation (midnight last day of month)
-log_rotation_method=d
+log_rotation_method=n
# LOG ARCHIVE PATH
-# This is the directory where archived (rotated) log files should be
+# This is the directory where archived (rotated) log files should be
# placed (assuming you've chosen to do log rotation).
log_archive_path=/var/log/nagios3/archives
@@ -248,7 +251,7 @@ log_archive_path=/var/log/nagios3/archives
# If you want messages logged to the syslog facility, as well as the
# Nagios log file set this option to 1. If not, set it to 0.
-use_syslog=1
+use_syslog=0
@@ -400,7 +403,7 @@ max_host_check_spread=30
# MAXIMUM CONCURRENT SERVICE CHECKS
-# This option allows you to specify the maximum number of
+# This option allows you to specify the maximum number of
# service checks that can be run in parallel at any given time.
# Specifying a value of 1 for this variable essentially prevents
# any service checks from being parallelized. A value of 0
@@ -422,7 +425,7 @@ check_result_reaper_frequency=10
# MAX CHECK RESULT REAPER TIME
# This is the max amount of time (in seconds) that a single
-# check result reaper event will be allowed to run before
+# check result reaper event will be allowed to run before
# returning control back to Nagios so it can perform other
# duties.
@@ -436,7 +439,7 @@ max_check_result_reaper_time=30
# service checks that have not yet been processed.
#
# Note: Make sure that only one instance of Nagios has access
-# to this directory!
+# to this directory!
check_result_path=/var/lib/nagios3/spool/checkresults
@@ -445,7 +448,7 @@ check_result_path=/var/lib/nagios3/spool/checkresults
# MAX CHECK RESULT FILE AGE
# This option determines the maximum age (in seconds) which check
-# result files are considered to be valid. Files older than this
+# result files are considered to be valid. Files older than this
# threshold will be mercilessly deleted without further processing.
max_check_result_file_age=3600
@@ -507,14 +510,14 @@ enable_predictive_service_dependency_checks=1
# SOFT STATE DEPENDENCIES
-# This option determines whether or not Nagios will use soft state
-# information when checking host and service dependencies. Normally
-# Nagios will only use the latest hard host or service state when
+# This option determines whether or not Nagios will use soft state
+# information when checking host and service dependencies. Normally
+# Nagios will only use the latest hard host or service state when
# checking dependencies. If you want it to use the latest state (regardless
-# of whether its a soft or hard state type), enable this option.
+# of whether its a soft or hard state type), enable this option.
# Values:
-# 0 = Don't use soft state dependencies (default)
-# 1 = Use soft state dependencies
+# 0 = Don't use soft state dependencies (default)
+# 1 = Use soft state dependencies
soft_state_dependencies=0
@@ -532,7 +535,7 @@ soft_state_dependencies=0
# This option determines whether or not Nagios will attempt to
# automatically reschedule active host and service checks to
# "smooth" them out over time. This can help balance the load on
-# the monitoring server.
+# the monitoring server.
# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE
# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY
@@ -595,7 +598,7 @@ perfdata_timeout=5
# This setting determines whether or not Nagios will save state
# information for services and hosts before it shuts down. Upon
# startup Nagios will reload all saved service and host state
-# information before starting to monitor. This is useful for
+# information before starting to monitor. This is useful for
# maintaining long-term data on state statistics, etc, but will
# slow Nagios down a bit when it (re)starts. Since its only
# a one-time penalty, I think its well worth the additional
@@ -607,7 +610,7 @@ retain_state_information=1
# STATE RETENTION FILE
# This is the file that Nagios should use to store host and
-# service state information before it shuts down. The state
+# service state information before it shuts down. The state
# information in this file is also read immediately prior to
# starting to monitor the network when Nagios is restarted.
# This file is used only if the preserve_state_information
@@ -630,7 +633,7 @@ retention_update_interval=60
# USE RETAINED PROGRAM STATE
-# This setting determines whether or not Nagios will set
+# This setting determines whether or not Nagios will set
# program status variables based on the values saved in the
# retention file. If you want to use retained program status
# information, set this value to 1. If not, set this value
@@ -657,7 +660,7 @@ use_retained_scheduling_info=1
# program restarts.
#
# The values of the masks are bitwise ANDs of values specified
-# by the "MODATTR_" definitions found in include/common.h.
+# by the "MODATTR_" definitions found in include/common.h.
# For example, if you do not want the current enabled/disabled state
# of flap detection and event handlers for hosts to be retained, you
# would use a value of 24 for the host attribute mask...
@@ -708,7 +711,7 @@ use_aggressive_host_checking=0
# SERVICE CHECK EXECUTION OPTION
# This determines whether or not Nagios will actively execute
-# service checks when it initially starts. If this option is
+# service checks when it initially starts. If this option is
# disabled, checks are not actively made, but Nagios can still
# receive and process passive check results that come in. Unless
# you're implementing redundant hosts or have a special need for
@@ -730,7 +733,7 @@ accept_passive_service_checks=1
# HOST CHECK EXECUTION OPTION
# This determines whether or not Nagios will actively execute
-# host checks when it initially starts. If this option is
+# host checks when it initially starts. If this option is
# disabled, checks are not actively made, but Nagios can still
# receive and process passive check results that come in. Unless
# you're implementing redundant hosts or have a special need for
@@ -787,7 +790,7 @@ process_performance_data=0
# These commands are run after every host and service check is
# performed. These commands are executed only if the
# enable_performance_data option (above) is set to 1. The command
-# argument is the short name of a command definition that you
+# argument is the short name of a command definition that you
# define in your host configuration file. Read the HTML docs for
# more information on performance data.
@@ -867,7 +870,7 @@ obsess_over_services=0
# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND
# This is the command that is run for every service check that is
# processed by Nagios. This command is executed only if the
-# obsess_over_services option (above) is set to 1. The command
+# obsess_over_services option (above) is set to 1. The command
# argument is the short name of a command definition that you
# define in your host configuration file. Read the HTML docs for
# more information on implementing distributed monitoring.
@@ -891,7 +894,7 @@ obsess_over_hosts=0
# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND
# This is the command that is run for every host check that is
# processed by Nagios. This command is executed only if the
-# obsess_over_hosts option (above) is set to 1. The command
+# obsess_over_hosts option (above) is set to 1. The command
# argument is the short name of a command definition that you
# define in your host configuration file. Read the HTML docs for
# more information on implementing distributed monitoring.
@@ -930,9 +933,9 @@ passive_host_checks_are_soft=0
# ORPHANED HOST/SERVICE CHECK OPTIONS
-# These options determine whether or not Nagios will periodically
+# These options determine whether or not Nagios will periodically
# check for orphaned host service checks. Since service checks are
-# not rescheduled until the results of their previous execution
+# not rescheduled until the results of their previous execution
# instance are processed, there exists a possibility that some
# checks may never get rescheduled. A similar situation exists for
# host checks, although the exact scheduling details differ a bit
@@ -1000,9 +1003,9 @@ additional_freshness_latency=15
# FLAP DETECTION OPTION
# This option determines whether or not Nagios will try
-# and detect hosts and services that are "flapping".
+# and detect hosts and services that are "flapping".
# Flapping occurs when a host or service changes between
-# states too frequently. When Nagios detects that a
+# states too frequently. When Nagios detects that a
# host or service is flapping, it will temporarily suppress
# notifications for that host/service until it stops
# flapping. Flap detection is very experimental, so read
@@ -1046,7 +1049,7 @@ date_format=iso8601
# the system configured timezone.
#
# NOTE: In order to display the correct timezone in the CGIs, you
-# will also need to alter the Apache directives for the CGI path
+# will also need to alter the Apache directives for the CGI path
# to include your timezone. Example:
#
# <Directory "/usr/local/nagios/sbin/">
@@ -1083,7 +1086,7 @@ enable_embedded_perl=1
# This option determines whether or not Nagios will process Perl plugins
# and scripts with the embedded Perl interpreter if the plugins/scripts
# do not explicitly indicate whether or not it is okay to do so. Read
-# the HTML documentation on the embedded Perl interpreter for more
+# the HTML documentation on the embedded Perl interpreter for more
# information on how this option works.
use_embedded_perl_implicitly=1
@@ -1130,7 +1133,7 @@ use_regexp_matching=0
# "TRUE" REGULAR EXPRESSION MATCHING
-# This option controls whether or not "true" regular expression
+# This option controls whether or not "true" regular expression
# matching takes place in the object config files. This option
# only has an effect if regular expression matching is enabled
# (see above). If this option is DISABLED, regular expression
@@ -1183,7 +1186,7 @@ use_large_installation_tweaks=0
# This option determines whether or not Nagios will make all standard
# macros available as environment variables when host/service checks
# and system commands (event handlers, notifications, etc.) are
-# executed. Enabling this option can cause performance issues in
+# executed. Enabling this option can cause performance issues in
# large installations, as it will consume a bit more memory and (more
# importantly) consume more CPU.
# Values: 1 - Enable environment variable macros (default)
@@ -1224,7 +1227,7 @@ enable_environment_macros=1
# This option determines how much (if any) debugging information will
# be written to the debug file. OR values together to log multiple
# types of information.
-# Values:
+# Values:
# -1 = Everything
# 0 = Nothing
# 1 = Functions
diff --git a/puppet/modules/site_nagios/manifests/add_host.pp b/puppet/modules/site_nagios/manifests/add_host.pp
deleted file mode 100644
index 498552b5..00000000
--- a/puppet/modules/site_nagios/manifests/add_host.pp
+++ /dev/null
@@ -1,31 +0,0 @@
-define site_nagios::add_host {
- $nagios_host = $name
- $nagios_hostname = $name['domain_internal']
- $nagios_ip = $name['ip_address']
- $nagios_services = $name['services']
- $nagios_openvpn_gw = $name['openvpn_gateway_address']
-
- # Add Nagios host
- nagios_host { $nagios_hostname:
- address => $nagios_ip,
- use => 'generic-host',
- }
-
- # Add Nagios service
-
- # First, we need to turn the serice array into hash, using a "hash template"
- # see https://github.com/ashak/puppet-resource-looping
- $nagios_service_hashpart = {
- 'hostname' => $nagios_hostname,
- 'ip_address' => $nagios_ip,
- 'openvpn_gw' => $nagios_openvpn_gw,
- }
- $dynamic_parameters = {
- 'service' => '%s'
- }
- $nagios_servicename = "${nagios_hostname}_%s"
-
- $nagios_service_hash = create_resources_hash_from($nagios_servicename, $nagios_services, $nagios_service_hashpart, $dynamic_parameters)
-
- create_resources ( site_nagios::add_service, $nagios_service_hash )
-}
diff --git a/puppet/modules/site_nagios/manifests/add_host_services.pp b/puppet/modules/site_nagios/manifests/add_host_services.pp
new file mode 100644
index 00000000..279809d1
--- /dev/null
+++ b/puppet/modules/site_nagios/manifests/add_host_services.pp
@@ -0,0 +1,28 @@
+define site_nagios::add_host_services (
+ $domain_full_suffix,
+ $domain_internal,
+ $ip_address,
+ $services,
+ $ssh_port,
+ $openvpn_gateway_address='' ) {
+
+ $nagios_hostname = $domain_internal
+
+ # Add Nagios service
+
+ # First, we need to turn the serice array into hash, using a "hash template"
+ # see https://github.com/ashak/puppet-resource-looping
+ $nagios_service_hashpart = {
+ 'hostname' => $nagios_hostname,
+ 'ip_address' => $ip_address,
+ 'openvpn_gw' => $openvpn_gateway_address,
+ }
+ $dynamic_parameters = {
+ 'service' => '%s'
+ }
+ $nagios_servicename = "${nagios_hostname}_%s"
+
+ $nagios_service_hash = create_resources_hash_from($nagios_servicename, $services, $nagios_service_hashpart, $dynamic_parameters)
+
+ create_resources ( site_nagios::add_service, $nagios_service_hash )
+}
diff --git a/puppet/modules/site_nagios/manifests/add_service.pp b/puppet/modules/site_nagios/manifests/add_service.pp
index 6ef3cbf5..8d2a310b 100644
--- a/puppet/modules/site_nagios/manifests/add_service.pp
+++ b/puppet/modules/site_nagios/manifests/add_service.pp
@@ -3,19 +3,19 @@ define site_nagios::add_service (
case $service {
'webapp': {
- $check_command = 'check_https_cert'
- $service_description = 'Website Certificate'
+ nagios_service {
+ "${name}_cert":
+ use => 'generic-service',
+ check_command => 'check_https_cert',
+ service_description => 'Website Certificate',
+ host_name => $hostname;
+ "${name}_website":
+ use => 'generic-service',
+ check_command => 'check_https',
+ service_description => 'Website',
+ host_name => $hostname
+ }
}
- default: {
- #notice ("No Nagios service check for service \"$service\"")
- }
- }
-
- if ( $check_command != '' ) {
- nagios_service { $name:
- use => 'generic-service',
- check_command => $check_command,
- service_description => $service_description,
- host_name => $hostname }
+ default: {}
}
}
diff --git a/puppet/modules/site_nagios/manifests/init.pp b/puppet/modules/site_nagios/manifests/init.pp
index cab32905..eb08cdcb 100644
--- a/puppet/modules/site_nagios/manifests/init.pp
+++ b/puppet/modules/site_nagios/manifests/init.pp
@@ -1,4 +1,6 @@
class site_nagios {
tag 'leap_service'
+ Class['site_config::default'] -> Class['site_nagios']
+
include site_nagios::server
}
diff --git a/puppet/modules/site_nagios/manifests/server.pp b/puppet/modules/site_nagios/manifests/server.pp
index c114a39a..85443917 100644
--- a/puppet/modules/site_nagios/manifests/server.pp
+++ b/puppet/modules/site_nagios/manifests/server.pp
@@ -1,26 +1,34 @@
class site_nagios::server inherits nagios::base {
# First, purge old nagios config (see #1467)
- class { 'site_nagios::server::purge':
- stage => setup
- }
+ class { 'site_nagios::server::purge': }
- $nagios_hiera=hiera('nagios')
+ $nagios_hiera = hiera('nagios')
$nagiosadmin_pw = htpasswd_sha1($nagios_hiera['nagiosadmin_pw'])
- $hosts = $nagios_hiera['hosts']
+ $nagios_hosts = $nagios_hiera['hosts']
include nagios::defaults
include nagios::base
- #Class ['nagios'] -> Class ['nagios::defaults']
- class {'nagios::apache':
+ class {'nagios':
+ # don't manage apache class from nagios, cause we already include
+ # it in site_apache::common
+ httpd => 'absent',
allow_external_cmd => true,
stored_config => false,
- #before => Class ['nagios::defaults']
}
+ file { '/etc/apache2/conf.d/nagios3.conf':
+ ensure => link,
+ target => '/usr/share/doc/nagios3-common/examples/apache2.conf',
+ notify => Service['apache']
+ }
+
+ include site_apache::common
+ include site_apache::module::headers
+
File ['nagios_htpasswd'] {
source => undef,
- content => "nagiosadmin:$nagiosadmin_pw",
+ content => "nagiosadmin:${nagiosadmin_pw}",
mode => '0640',
}
@@ -33,6 +41,18 @@ class site_nagios::server inherits nagios::base {
group => 'nagios',
}
- site_nagios::add_host {$hosts:}
+ create_resources ( site_nagios::add_host_services, $nagios_hosts )
+
+ include site_nagios::server::apache
+ include site_check_mk::server
include site_shorewall::monitor
+
+ augeas {
+ 'logrotate_nagios':
+ context => '/files/etc/logrotate.d/nagios/rule',
+ changes => [ 'set file /var/log/nagios3/nagios.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_nagios/manifests/server/apache.pp b/puppet/modules/site_nagios/manifests/server/apache.pp
new file mode 100644
index 00000000..8dbc7e9b
--- /dev/null
+++ b/puppet/modules/site_nagios/manifests/server/apache.pp
@@ -0,0 +1,7 @@
+class site_nagios::server::apache {
+ include x509::variables
+ include site_config::x509::commercial::cert
+ include site_config::x509::commercial::key
+ include site_config::x509::commercial::ca
+
+}
diff --git a/puppet/modules/site_nagios/manifests/server/purge.pp b/puppet/modules/site_nagios/manifests/server/purge.pp
index 39735cd3..6815a703 100644
--- a/puppet/modules/site_nagios/manifests/server/purge.pp
+++ b/puppet/modules/site_nagios/manifests/server/purge.pp
@@ -1,7 +1,19 @@
-class site_nagios::server::purge {
- exec {'purge_conf.d':
- command => '/bin/rm -rf /etc/nagios3/conf.d/*',
- onlyif => 'test -e /etc/nagios3/conf.d'
+class site_nagios::server::purge inherits nagios::base {
+ # we don't want to get /etc/nagios3 and /etc/nagios3/conf.d
+ # purged, cause the check-mk-config-nagios3 package
+ # places its templates in /etc/nagios3/conf.d/check_mk,
+ # and check_mk -O updated it's nagios config in /etc/nagios3/conf.d/check_mk
+ File['nagios_cfgdir'] {
+ purge => false
+ }
+ File['nagios_confd'] {
+ purge => false
}
+ # only purge files in the /etc/nagios3/conf.d/ dir, not in any subdir
+ exec {'purge_conf.d':
+ command => '/usr/bin/find /etc/nagios3/conf.d/ -maxdepth 1 -type f -exec rm {} \;',
+ onlyif => '/usr/bin/find /etc/nagios3/conf.d/ -maxdepth 1 -type f | grep -q "/etc/nagios3/conf.d"',
+ require => Package['nagios']
+ }
}
diff --git a/puppet/modules/site_nickserver/manifests/init.pp b/puppet/modules/site_nickserver/manifests/init.pp
index 7dfa2603..eaf90d55 100644
--- a/puppet/modules/site_nickserver/manifests/init.pp
+++ b/puppet/modules/site_nickserver/manifests/init.pp
@@ -1,37 +1,47 @@
#
-# TODO: currently, this is dependent on some things that are set up in site_webapp
+# TODO: currently, this is dependent on some things that are set up in
+# site_webapp
#
# (1) HAProxy -> couchdb
# (2) Apache
#
-# It would be good in the future to make nickserver installable independently of site_webapp.
+# It would be good in the future to make nickserver installable independently of
+# site_webapp.
#
class site_nickserver {
tag 'leap_service'
- include site_config::ruby
+ Class['site_config::default'] -> Class['site_nickserver']
+
+ include site_config::ruby::dev
#
# VARIABLES
#
$nickserver = hiera('nickserver')
- $nickserver_port = $nickserver['port'] # the port that public connects to (should be 6425)
- $nickserver_local_port = '64250' # the port that nickserver is actually running on
$nickserver_domain = $nickserver['domain']
+ $couchdb_user = $nickserver['couchdb_nickserver_user']['username']
+ $couchdb_password = $nickserver['couchdb_nickserver_user']['password']
+
+ # the port that public connects to (should be 6425)
+ $nickserver_port = $nickserver['port']
+ # the port that nickserver is actually running on
+ $nickserver_local_port = '64250'
- $couchdb_user = $nickserver['couchdb_user']['username']
- $couchdb_password = $nickserver['couchdb_user']['password']
- $couchdb_host = 'localhost' # couchdb is available on localhost via haproxy, which is bound to 4096.
- $couchdb_port = '4096' # See site_webapp/templates/haproxy_couchdb.cfg.erg
+ # couchdb is available on localhost via haproxy, which is bound to 4096.
+ $couchdb_host = 'localhost'
+ # See site_webapp/templates/haproxy_couchdb.cfg.erg
+ $couchdb_port = '4096'
# temporarily for now:
$domain = hiera('domain')
$address_domain = $domain['full_suffix']
- $x509 = hiera('x509')
- $x509_key = $x509['key']
- $x509_cert = $x509['cert']
- $x509_ca = $x509['ca_cert']
+
+
+ include site_config::x509::cert
+ include site_config::x509::key
+ include site_config::x509::ca
#
# USER AND GROUP
@@ -41,6 +51,7 @@ class site_nickserver {
ensure => present,
allowdupe => false;
}
+
user { 'nickserver':
ensure => present,
allowdupe => false,
@@ -50,31 +61,33 @@ class site_nickserver {
}
#
- # NICKSERVER CODE
- # NOTE: in order to support TLS, libssl-dev must be installed before EventMachine gem
- # is built/installed.
+ # NICKSERVER CODE NOTE: in order to support TLS, libssl-dev must be installed
+ # before EventMachine gem is built/installed.
#
- package {
- 'libssl-dev': ensure => installed;
- }
+ package { 'libssl-dev': ensure => installed }
+
vcsrepo { '/srv/leap/nickserver':
ensure => present,
revision => 'origin/master',
provider => git,
- source => 'git://code.leap.se/nickserver',
+ source => 'https://leap.se/git/nickserver',
owner => 'nickserver',
group => 'nickserver',
require => [ User['nickserver'], Group['nickserver'] ],
notify => Exec['nickserver_bundler_update'];
}
+
exec { 'nickserver_bundler_update':
cwd => '/srv/leap/nickserver',
command => '/bin/bash -c "/usr/bin/bundle check || /usr/bin/bundle install --path vendor/bundle"',
unless => '/usr/bin/bundle check',
user => 'nickserver',
timeout => 600,
- require => [ Class['bundler::install'], Vcsrepo['/srv/leap/nickserver'], Package['libssl-dev'] ],
+ require => [
+ Class['bundler::install'], Vcsrepo['/srv/leap/nickserver'],
+ Package['libssl-dev'], Class['site_config::ruby::dev'] ],
+
notify => Service['nickserver'];
}
@@ -82,7 +95,7 @@ class site_nickserver {
# NICKSERVER CONFIG
#
- file { '/etc/leap/nickserver.yml':
+ file { '/etc/nickserver.yml':
content => template('site_nickserver/nickserver.yml.erb'),
owner => nickserver,
group => nickserver,
@@ -99,8 +112,11 @@ class site_nickserver {
ensure => link,
target => '/srv/leap/nickserver/bin/nickserver',
require => Vcsrepo['/srv/leap/nickserver'];
+
'/etc/init.d/nickserver':
- owner => root, group => 0, mode => '0755',
+ owner => root,
+ group => 0,
+ mode => '0755',
source => '/srv/leap/nickserver/dist/debian-init-script',
require => Vcsrepo['/srv/leap/nickserver'];
}
@@ -110,7 +126,11 @@ class site_nickserver {
enable => true,
hasrestart => true,
hasstatus => true,
- require => File['/etc/init.d/nickserver'];
+ require => [
+ File['/etc/init.d/nickserver'],
+ Class['Site_config::X509::Key'],
+ Class['Site_config::X509::Cert'],
+ Class['Site_config::X509::Ca'] ];
}
#
@@ -119,7 +139,7 @@ class site_nickserver {
#
file { '/etc/shorewall/macro.nickserver':
- content => "PARAM - - tcp $nickserver_port",
+ content => "PARAM - - tcp ${nickserver_port}",
notify => Service['shorewall'],
require => Package['shorewall'];
}
@@ -142,21 +162,8 @@ class site_nickserver {
}
apache::vhost::file {
- 'nickserver': content => template('site_nickserver/nickserver-proxy.conf.erb')
- }
-
- x509::key { 'nickserver':
- content => $x509_key,
- notify => Service[apache];
+ 'nickserver':
+ content => template('site_nickserver/nickserver-proxy.conf.erb')
}
- x509::cert { 'nickserver':
- content => $x509_cert,
- notify => Service[apache];
- }
-
- x509::ca { 'nickserver':
- content => $x509_ca,
- notify => Service[apache];
- }
-} \ No newline at end of file
+}
diff --git a/puppet/modules/site_nickserver/templates/nickserver-proxy.conf.erb b/puppet/modules/site_nickserver/templates/nickserver-proxy.conf.erb
index 67896cd3..ae06410e 100644
--- a/puppet/modules/site_nickserver/templates/nickserver-proxy.conf.erb
+++ b/puppet/modules/site_nickserver/templates/nickserver-proxy.conf.erb
@@ -14,9 +14,9 @@ Listen 0.0.0.0:<%= @nickserver_port -%>
SSLHonorCipherOrder on
SSLCACertificatePath /etc/ssl/certs
- SSLCertificateChainFile /etc/ssl/certs/nickserver.pem
- SSLCertificateKeyFile /etc/x509/keys/nickserver.key
- SSLCertificateFile /etc/x509/certs/nickserver.crt
+ SSLCertificateChainFile <%= scope.lookupvar('x509::variables::local_CAs') %>/<%= scope.lookupvar('site_config::params::ca_name') %>.crt
+ SSLCertificateKeyFile <%= scope.lookupvar('x509::variables::keys') %>/<%= scope.lookupvar('site_config::params::cert_name') %>.key
+ SSLCertificateFile <%= scope.lookupvar('x509::variables::certs') %>/<%= scope.lookupvar('site_config::params::cert_name') %>.crt
ProxyPass / http://localhost:<%= @nickserver_local_port %>/
ProxyPreserveHost On # preserve Host header in HTTP request
diff --git a/puppet/modules/site_nickserver/templates/nickserver.yml.erb b/puppet/modules/site_nickserver/templates/nickserver.yml.erb
index 7aab5605..e717cbaa 100644
--- a/puppet/modules/site_nickserver/templates/nickserver.yml.erb
+++ b/puppet/modules/site_nickserver/templates/nickserver.yml.erb
@@ -6,7 +6,7 @@ domain: "<%= @address_domain %>"
couch_host: "<%= @couchdb_host %>"
couch_port: <%= @couchdb_port %>
-couch_database: "users"
+couch_database: "identities"
couch_user: "<%= @couchdb_user %>"
couch_password: "<%= @couchdb_password %>"
diff --git a/puppet/modules/site_openvpn/manifests/dh_key.pp b/puppet/modules/site_openvpn/manifests/dh_key.pp
new file mode 100644
index 00000000..13cc0f5b
--- /dev/null
+++ b/puppet/modules/site_openvpn/manifests/dh_key.pp
@@ -0,0 +1,10 @@
+class site_openvpn::dh_key {
+
+ $x509_config = hiera('x509')
+
+ file { '/etc/openvpn/keys/dh.pem':
+ content => $x509_config['dh'],
+ mode => '0644',
+ }
+
+}
diff --git a/puppet/modules/site_openvpn/manifests/init.pp b/puppet/modules/site_openvpn/manifests/init.pp
index 4f900623..7aec0faa 100644
--- a/puppet/modules/site_openvpn/manifests/init.pp
+++ b/puppet/modules/site_openvpn/manifests/init.pp
@@ -5,8 +5,9 @@
# (2) unlimited only
# (3) limited only
#
-# The difference is that 'unlimited' gateways only allow client certs that match the 'unlimited_prefix',
-# and 'limited' gateways only allow certs that match the 'limited_prefix'.
+# The difference is that 'unlimited' gateways only allow client certs that match
+# the 'unlimited_prefix', and 'limited' gateways only allow certs that match the
+# 'limited_prefix'.
#
# We potentially create four openvpn config files (thus four daemons):
#
@@ -19,23 +20,30 @@
class site_openvpn {
tag 'leap_service'
- $openvpn_config = hiera('openvpn')
- $x509_config = hiera('x509')
- $openvpn_ports = $openvpn_config['ports']
+ include site_config::x509::cert
+ include site_config::x509::key
+ include site_config::x509::ca_bundle
+
+
+ Class['site_config::default'] -> Class['site_openvpn']
+
+ $openvpn = hiera('openvpn')
+ $openvpn_ports = $openvpn['ports']
+ $openvpn_config = $openvpn['configuration']
if $::ec2_instance_id {
$openvpn_gateway_address = $::ipaddress
} else {
- $openvpn_gateway_address = $openvpn_config['gateway_address']
- if $openvpn_config['second_gateway_address'] {
- $openvpn_second_gateway_address = $openvpn_config['second_gateway_address']
+ $openvpn_gateway_address = $openvpn['gateway_address']
+ if $openvpn['second_gateway_address'] {
+ $openvpn_second_gateway_address = $openvpn['second_gateway_address']
} else {
$openvpn_second_gateway_address = undef
}
}
- $openvpn_allow_unlimited = $openvpn_config['allow_unlimited']
- $openvpn_unlimited_prefix = $openvpn_config['unlimited_prefix']
+ $openvpn_allow_unlimited = $openvpn['allow_unlimited']
+ $openvpn_unlimited_prefix = $openvpn['unlimited_prefix']
$openvpn_unlimited_tcp_network_prefix = '10.41.0'
$openvpn_unlimited_tcp_netmask = '255.255.248.0'
$openvpn_unlimited_tcp_cidr = '21'
@@ -44,9 +52,9 @@ class site_openvpn {
$openvpn_unlimited_udp_cidr = '21'
if !$::ec2_instance_id {
- $openvpn_allow_limited = $openvpn_config['allow_limited']
- $openvpn_limited_prefix = $openvpn_config['limited_prefix']
- $openvpn_rate_limit = $openvpn_config['rate_limit']
+ $openvpn_allow_limited = $openvpn['allow_limited']
+ $openvpn_limited_prefix = $openvpn['limited_prefix']
+ $openvpn_rate_limit = $openvpn['rate_limit']
$openvpn_limited_tcp_network_prefix = '10.43.0'
$openvpn_limited_tcp_netmask = '255.255.248.0'
$openvpn_limited_tcp_cidr = '21'
@@ -55,8 +63,14 @@ class site_openvpn {
$openvpn_limited_udp_cidr = '21'
}
- # deploy ca + server keys
- include site_openvpn::keys
+ # find out the netmask in cidr format of the primary IF
+ # thx to https://blog.kumina.nl/tag/puppet-tips-and-tricks/
+ # we can do this using an inline_template:
+ $factname_primary_netmask = "netmask_cidr_${::site_config::params::interface}"
+ $primary_netmask = inline_template('<%= scope.lookupvar(factname_primary_netmask) %>')
+
+ # deploy dh keys
+ include site_openvpn::dh_key
if $openvpn_allow_unlimited and $openvpn_allow_limited {
$unlimited_gateway_address = $openvpn_gateway_address
@@ -77,7 +91,8 @@ class site_openvpn {
tls_remote => "\"${openvpn_unlimited_prefix}\"",
server => "${openvpn_unlimited_tcp_network_prefix}.0 ${openvpn_unlimited_tcp_netmask}",
push => "\"dhcp-option DNS ${openvpn_unlimited_tcp_network_prefix}.1\"",
- management => '127.0.0.1 1000'
+ management => '127.0.0.1 1000',
+ config => $openvpn_config
}
site_openvpn::server_config { 'udp_config':
port => '1194',
@@ -86,11 +101,12 @@ class site_openvpn {
tls_remote => "\"${openvpn_unlimited_prefix}\"",
server => "${openvpn_unlimited_udp_network_prefix}.0 ${openvpn_unlimited_udp_netmask}",
push => "\"dhcp-option DNS ${openvpn_unlimited_udp_network_prefix}.1\"",
- management => '127.0.0.1 1001'
+ management => '127.0.0.1 1001',
+ config => $openvpn_config
}
} else {
- tidy { "/etc/openvpn/tcp_config.conf": }
- tidy { "/etc/openvpn/udp_config.conf": }
+ tidy { '/etc/openvpn/tcp_config.conf': }
+ tidy { '/etc/openvpn/udp_config.conf': }
}
if $openvpn_allow_limited {
@@ -101,7 +117,8 @@ class site_openvpn {
tls_remote => "\"${openvpn_limited_prefix}\"",
server => "${openvpn_limited_tcp_network_prefix}.0 ${openvpn_limited_tcp_netmask}",
push => "\"dhcp-option DNS ${openvpn_limited_tcp_network_prefix}.1\"",
- management => '127.0.0.1 1002'
+ management => '127.0.0.1 1002',
+ config => $openvpn_config
}
site_openvpn::server_config { 'limited_udp_config':
port => '1194',
@@ -110,11 +127,12 @@ class site_openvpn {
tls_remote => "\"${openvpn_limited_prefix}\"",
server => "${openvpn_limited_udp_network_prefix}.0 ${openvpn_limited_udp_netmask}",
push => "\"dhcp-option DNS ${openvpn_limited_udp_network_prefix}.1\"",
- management => '127.0.0.1 1003'
+ management => '127.0.0.1 1003',
+ config => $openvpn_config
}
} else {
- tidy { "/etc/openvpn/limited_tcp_config.conf": }
- tidy { "/etc/openvpn/limited_udp_config.conf": }
+ tidy { '/etc/openvpn/limited_tcp_config.conf': }
+ tidy { '/etc/openvpn/limited_udp_config.conf': }
}
file {
@@ -131,7 +149,12 @@ class site_openvpn {
command => '/etc/init.d/openvpn restart',
refreshonly => true,
subscribe => File['/etc/openvpn'],
- require => [ Package['openvpn'], File['/etc/openvpn'] ];
+ require => [
+ Package['openvpn'],
+ File['/etc/openvpn'],
+ Class['Site_config::X509::Key'],
+ Class['Site_config::X509::Cert'],
+ Class['Site_config::X509::Ca_bundle'] ];
}
cron { 'add_gateway_ips.sh':
@@ -155,7 +178,9 @@ class site_openvpn {
ensure => running,
hasrestart => true,
hasstatus => true,
- require => Exec['concat_/etc/default/openvpn'];
+ require => [
+ Package['openvpn'],
+ Exec['concat_/etc/default/openvpn'] ];
}
file {
@@ -193,4 +218,7 @@ class site_openvpn {
target => '/etc/default/openvpn',
order => 10;
}
+
+ include site_check_mk::agent::openvpn
+
}
diff --git a/puppet/modules/site_openvpn/manifests/keys.pp b/puppet/modules/site_openvpn/manifests/keys.pp
deleted file mode 100644
index f3c5b423..00000000
--- a/puppet/modules/site_openvpn/manifests/keys.pp
+++ /dev/null
@@ -1,51 +0,0 @@
-class site_openvpn::keys {
-
- x509::key {
- 'leap_openvpn':
- content => $site_openvpn::x509_config['key'],
- notify => Service[openvpn];
- }
-
- x509::cert {
- 'leap_openvpn':
- content => $site_openvpn::x509_config['cert'],
- notify => Service[openvpn];
- }
-
- x509::ca {
- 'leap_ca':
- content => $site_openvpn::x509_config['ca_cert'],
- notify => Service[openvpn];
- }
-
- file { '/etc/openvpn/keys/dh.pem':
- content => $site_openvpn::x509_config['dh'],
- mode => '0644',
- }
-
- #
- # CA bundle -- we want to have the possibility of allowing multiple CAs.
- # For now, the reason is to transition to using client CA. In the future,
- # we will want to be able to smoothly phase out one CA and phase in another.
- # I tried "--capath" for this, but it did not work.
- #
-
- concat {
- '/etc/openvpn/ca_bundle.pem':
- owner => root,
- group => root,
- mode => 644,
- warn => true,
- notify => Service['openvpn'];
- }
-
- concat::fragment {
- 'client_ca_cert':
- content => $site_openvpn::x509_config['client_ca_cert'],
- target => '/etc/openvpn/ca_bundle.pem';
- 'ca_cert':
- content => $site_openvpn::x509_config['ca_cert'],
- target => '/etc/openvpn/ca_bundle.pem';
- }
-
-}
diff --git a/puppet/modules/site_openvpn/manifests/resolver.pp b/puppet/modules/site_openvpn/manifests/resolver.pp
index c1bce858..c74fb509 100644
--- a/puppet/modules/site_openvpn/manifests/resolver.pp
+++ b/puppet/modules/site_openvpn/manifests/resolver.pp
@@ -60,25 +60,25 @@ class site_openvpn::resolver {
path => '/etc/unbound/unbound.conf',
line => 'server: include: /etc/unbound/conf.d/vpn_unlimited_tcp_resolver',
notify => Service['unbound'],
- require => Package['unbound'];
+ require => [ Package['openvpn'], Package['unbound'] ];
'add_unlimited_udp_resolver':
ensure => $ensure_unlimited,
path => '/etc/unbound/unbound.conf',
line => 'server: include: /etc/unbound/conf.d/vpn_unlimited_udp_resolver',
notify => Service['unbound'],
- require => Package['unbound'];
+ require => [ Package['openvpn'], Package['unbound'] ];
'add_limited_tcp_resolver':
ensure => $ensure_limited,
path => '/etc/unbound/unbound.conf',
line => 'server: include: /etc/unbound/conf.d/vpn_limited_tcp_resolver',
notify => Service['unbound'],
- require => Package['unbound'];
- 'add_limited_udp_resolver':
+ require => [ Package['openvpn'], Package['unbound'] ];
+ 'add_limited_udp_resolver':
ensure => $ensure_limited,
path => '/etc/unbound/unbound.conf',
line => 'server: include: /etc/unbound/conf.d/vpn_limited_udp_resolver',
notify => Service['unbound'],
- require => Package['unbound']
+ require => [ Package['openvpn'], Package['unbound'] ];
}
}
diff --git a/puppet/modules/site_openvpn/manifests/server_config.pp b/puppet/modules/site_openvpn/manifests/server_config.pp
index 6106cfbb..b1f4997c 100644
--- a/puppet/modules/site_openvpn/manifests/server_config.pp
+++ b/puppet/modules/site_openvpn/manifests/server_config.pp
@@ -54,7 +54,7 @@
define site_openvpn::server_config(
$port, $proto, $local, $server, $push,
- $management, $tls_remote = undef) {
+ $management, $config, $tls_remote = undef) {
$openvpn_configname = $name
@@ -70,97 +70,97 @@ define site_openvpn::server_config(
if $tls_remote != undef {
openvpn::option {
- "tls-remote $openvpn_configname":
- key => 'tls-remote',
- value => $tls_remote,
- server => $openvpn_configname;
+ "tls-remote ${openvpn_configname}":
+ key => 'tls-remote',
+ value => $tls_remote,
+ server => $openvpn_configname;
}
}
openvpn::option {
- "ca $openvpn_configname":
+ "ca ${openvpn_configname}":
key => 'ca',
- value => '/etc/openvpn/ca_bundle.pem',
+ value => "${x509::variables::local_CAs}/${site_config::params::ca_bundle_name}.crt",
server => $openvpn_configname;
- "cert $openvpn_configname":
+ "cert ${openvpn_configname}":
key => 'cert',
- value => '/etc/x509/certs/leap_openvpn.crt',
+ value => "${x509::variables::certs}/${site_config::params::cert_name}.crt",
server => $openvpn_configname;
- "key $openvpn_configname":
+ "key ${openvpn_configname}":
key => 'key',
- value => '/etc/x509/keys/leap_openvpn.key',
+ value => "${x509::variables::keys}/${site_config::params::cert_name}.key",
server => $openvpn_configname;
- "dh $openvpn_configname":
+ "dh ${openvpn_configname}":
key => 'dh',
value => '/etc/openvpn/keys/dh.pem',
server => $openvpn_configname;
- "tls-cipher $openvpn_configname":
+ "tls-cipher ${openvpn_configname}":
key => 'tls-cipher',
- value => 'DHE-RSA-AES128-SHA',
+ value => $config['tls-cipher'],
server => $openvpn_configname;
- "auth $openvpn_configname":
+ "auth ${openvpn_configname}":
key => 'auth',
- value => 'SHA1',
+ value => $config['auth'],
server => $openvpn_configname;
- "cipher $openvpn_configname":
+ "cipher ${openvpn_configname}":
key => 'cipher',
- value => 'AES-128-CBC',
+ value => $config['cipher'],
server => $openvpn_configname;
- "dev $openvpn_configname":
+ "dev ${openvpn_configname}":
key => 'dev',
value => 'tun',
server => $openvpn_configname;
- "duplicate-cn $openvpn_configname":
+ "duplicate-cn ${openvpn_configname}":
key => 'duplicate-cn',
server => $openvpn_configname;
- "keepalive $openvpn_configname":
+ "keepalive ${openvpn_configname}":
key => 'keepalive',
- value => '5 20',
+ value => $config['keepalive'],
server => $openvpn_configname;
- "local $openvpn_configname":
+ "local ${openvpn_configname}":
key => 'local',
value => $local,
server => $openvpn_configname;
- "mute $openvpn_configname":
+ "mute ${openvpn_configname}":
key => 'mute',
value => '5',
server => $openvpn_configname;
- "mute-replay-warnings $openvpn_configname":
+ "mute-replay-warnings ${openvpn_configname}":
key => 'mute-replay-warnings',
server => $openvpn_configname;
- "management $openvpn_configname":
+ "management ${openvpn_configname}":
key => 'management',
value => $management,
server => $openvpn_configname;
- "proto $openvpn_configname":
+ "proto ${openvpn_configname}":
key => 'proto',
value => $proto,
server => $openvpn_configname;
- "push1 $openvpn_configname":
+ "push1 ${openvpn_configname}":
key => 'push',
value => $push,
server => $openvpn_configname;
- "push2 $openvpn_configname":
+ "push2 ${openvpn_configname}":
key => 'push',
value => '"redirect-gateway def1"',
server => $openvpn_configname;
- "script-security $openvpn_configname":
+ "script-security ${openvpn_configname}":
key => 'script-security',
value => '2',
server => $openvpn_configname;
- "server $openvpn_configname":
+ "server ${openvpn_configname}":
key => 'server',
value => $server,
server => $openvpn_configname;
- "status $openvpn_configname":
+ "status ${openvpn_configname}":
key => 'status',
value => '/var/run/openvpn-status 10',
server => $openvpn_configname;
- "status-version $openvpn_configname":
+ "status-version ${openvpn_configname}":
key => 'status-version',
value => '3',
server => $openvpn_configname;
- "topology $openvpn_configname":
+ "topology ${openvpn_configname}":
key => 'topology',
value => 'subnet',
server => $openvpn_configname;
@@ -169,7 +169,7 @@ define site_openvpn::server_config(
# key => 'up',
# value => '/etc/openvpn/server-up.sh',
# server => $openvpn_configname;
- "verb $openvpn_configname":
+ "verb ${openvpn_configname}":
key => 'verb',
value => '3',
server => $openvpn_configname;
diff --git a/puppet/modules/site_openvpn/templates/add_gateway_ips.sh.erb b/puppet/modules/site_openvpn/templates/add_gateway_ips.sh.erb
index 05f3d16b..e76b756b 100644
--- a/puppet/modules/site_openvpn/templates/add_gateway_ips.sh.erb
+++ b/puppet/modules/site_openvpn/templates/add_gateway_ips.sh.erb
@@ -1,11 +1,11 @@
#!/bin/sh
-ip addr show dev <%= scope.lookupvar('site_config::params::interface') %> | grep -q <%= @openvpn_gateway_address %>/24 ||
- ip addr add <%= @openvpn_gateway_address %>/24 dev <%= scope.lookupvar('site_config::params::interface') %>
+ip addr show dev <%= scope.lookupvar('site_config::params::interface') %> | grep -q <%= @openvpn_gateway_address %>/<%= @primary_netmask %> ||
+ ip addr add <%= @openvpn_gateway_address %>/<%= @primary_netmask %> dev <%= scope.lookupvar('site_config::params::interface') %>
<% if @openvpn_second_gateway_address %>
-ip addr show dev <%= scope.lookupvar('site_config::params::interface') %> | grep -q <%= @openvpn_second_gateway_address %>/24 ||
- ip addr add <%= @openvpn_second_gateway_address %>/24 dev <%= scope.lookupvar('site_config::params::interface') %>
+ip addr show dev <%= scope.lookupvar('site_config::params::interface') %> | grep -q <%= @openvpn_second_gateway_address %>/<%= @primary_netmask %> ||
+ ip addr add <%= @openvpn_second_gateway_address %>/<%= @primary_netmask %> dev <%= scope.lookupvar('site_config::params::interface') %>
<% end %>
/bin/echo 1 > /proc/sys/net/ipv4/ip_forward
diff --git a/puppet/modules/site_postfix/files/checks/received_anon b/puppet/modules/site_postfix/files/checks/received_anon
new file mode 100644
index 00000000..2822973e
--- /dev/null
+++ b/puppet/modules/site_postfix/files/checks/received_anon
@@ -0,0 +1,2 @@
+/^Received: from (.* \([-._[:alnum:]]+ \[[.[:digit:]]{7,15}\]\))([[:space:]]+).*(\(using [.[:alnum:]]+ with cipher [-A-Z0-9]+ \([0-9]+\/[0-9]+ bits\)\))[[:space:]]+\(Client CN "([[:alnum:]]+)", Issuer "[[:print:]]+" \(verified OK\)\)[[:space:]]+by ([.[:alnum:]]+) \(([^)]+)\) with (E?SMTPS?A?) id ([A-F[:digit:]]+).*/
+ REPLACE Received: from [127.0.0.1] (localhost [127.0.0.1])${2}${3}${2}(Authenticated sender: $4)${2}with $7 id $8
diff --git a/puppet/modules/site_postfix/manifests/debug.pp b/puppet/modules/site_postfix/manifests/debug.pp
new file mode 100644
index 00000000..f370d166
--- /dev/null
+++ b/puppet/modules/site_postfix/manifests/debug.pp
@@ -0,0 +1,9 @@
+class site_postfix::debug {
+
+ postfix::config {
+ 'debug_peer_list': value => '127.0.0.1';
+ 'debug_peer_level': value => '1';
+ 'smtpd_tls_loglevel': value => '1';
+ }
+
+}
diff --git a/puppet/modules/site_postfix/manifests/mx.pp b/puppet/modules/site_postfix/manifests/mx.pp
new file mode 100644
index 00000000..bdfee665
--- /dev/null
+++ b/puppet/modules/site_postfix/manifests/mx.pp
@@ -0,0 +1,74 @@
+class site_postfix::mx {
+
+ $domain_hash = hiera ('domain')
+ $domain = $domain_hash['full_suffix']
+ $host_domain = $domain_hash['full']
+ $cert_name = hiera('name')
+ $mynetworks = join(hiera('mynetworks'), ' ')
+
+ $root_mail_recipient = hiera ('contacts')
+ $postfix_smtp_listen = 'all'
+
+ include site_config::x509::cert
+ include site_config::x509::key
+ include site_config::x509::client_ca::ca
+ include site_config::x509::client_ca::key
+
+ postfix::config {
+ 'mynetworks':
+ value => "127.0.0.0/8 [::1]/128 [fe80::]/64 ${mynetworks}";
+ 'mydestination':
+ value => "\$myorigin, localhost, localhost.\$mydomain, ${domain}";
+ 'myhostname':
+ value => $host_domain;
+ 'mailbox_size_limit':
+ value => '0';
+ 'home_mailbox':
+ value => 'Maildir/';
+ 'virtual_alias_maps':
+ value => 'tcp:localhost:4242';
+ 'luser_relay':
+ value => 'vmail';
+ 'smtpd_tls_received_header':
+ value => 'yes';
+ # 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';
+ }
+
+ include site_postfix::mx::smtpd_checks
+ include site_postfix::mx::checks
+ include site_postfix::mx::smtp_tls
+ include site_postfix::mx::smtpd_tls
+ include site_postfix::mx::reserved_aliases
+
+ # greater verbosity for debugging, take out for production
+ #include site_postfix::debug
+
+ user { 'vmail':
+ ensure => present,
+ comment => 'Leap Mailspool',
+ home => '/var/mail/vmail',
+ shell => '/bin/false',
+ managehome => true,
+ }
+
+ class { 'postfix':
+ preseed => true,
+ root_mail_recipient => $root_mail_recipient,
+ smtp_listen => 'all',
+ mastercf_tail =>
+ "smtps inet n - - - - smtpd
+ -o smtpd_tls_wrappermode=yes
+ -o smtpd_tls_security_level=encrypt
+ -o smtpd_recipient_restrictions=\$smtps_recipient_restrictions
+ -o smtpd_helo_restrictions=\$smtps_helo_restrictions",
+ require => [
+ Class['Site_config::X509::Key'],
+ Class['Site_config::X509::Cert'],
+ Class['Site_config::X509::Client_ca::Key'],
+ Class['Site_config::X509::Client_ca::Ca'],
+ User['vmail'] ]
+ }
+}
diff --git a/puppet/modules/site_postfix/manifests/mx/checks.pp b/puppet/modules/site_postfix/manifests/mx/checks.pp
new file mode 100644
index 00000000..5d75a5e5
--- /dev/null
+++ b/puppet/modules/site_postfix/manifests/mx/checks.pp
@@ -0,0 +1,41 @@
+class site_postfix::mx::checks {
+
+ file {
+ '/etc/postfix/checks':
+ ensure => directory,
+ mode => '0755',
+ owner => root,
+ group => postfix,
+ require => Package['postfix'];
+
+ '/etc/postfix/checks/helo_checks':
+ content => template('site_postfix/checks/helo_access.erb'),
+ mode => '0644',
+ owner => root,
+ group => root;
+ }
+
+ exec {
+ '/usr/sbin/postmap /etc/postfix/checks/helo_checks':
+ refreshonly => true,
+ subscribe => File['/etc/postfix/checks/helo_checks'];
+ }
+
+ # Anonymize the user's home IP from the email headers (Feature #3866)
+ package { 'postfix-pcre': ensure => installed, require => Package['postfix'] }
+
+ file { '/etc/postfix/checks/received_anon':
+ source => 'puppet:///modules/site_postfix/checks/received_anon',
+ mode => '0644',
+ owner => root,
+ group => root,
+ notify => Service['postfix']
+ }
+
+ postfix::config {
+ 'header_checks':
+ value => 'pcre:/etc/postfix/checks/received_anon',
+ require => File['/etc/postfix/checks/received_anon'];
+ }
+
+}
diff --git a/puppet/modules/site_postfix/manifests/mx/reserved_aliases.pp b/puppet/modules/site_postfix/manifests/mx/reserved_aliases.pp
new file mode 100644
index 00000000..83e27376
--- /dev/null
+++ b/puppet/modules/site_postfix/manifests/mx/reserved_aliases.pp
@@ -0,0 +1,15 @@
+# Defines which mail addresses shouldn't be available and where they should fwd
+class site_postfix::mx::reserved_aliases {
+
+ postfix::mailalias {
+ [ 'abuse', 'admin', 'arin-admin', 'administrator', 'bin', 'cron',
+ 'certmaster', 'domainadmin', 'games', 'ftp', 'hostmaster', 'lp',
+ 'maildrop', 'mysql', 'news', 'nobody', 'noc', 'postmaster', 'postgresql',
+ 'security', 'ssladmin', 'sys', 'usenet', 'uucp', 'webmaster', 'www',
+ 'www-data',
+ ]:
+ ensure => present,
+ recipient => 'root'
+ }
+
+}
diff --git a/puppet/modules/site_postfix/manifests/mx/smtp_auth.pp b/puppet/modules/site_postfix/manifests/mx/smtp_auth.pp
new file mode 100644
index 00000000..afa70527
--- /dev/null
+++ b/puppet/modules/site_postfix/manifests/mx/smtp_auth.pp
@@ -0,0 +1,6 @@
+class site_postfix::mx::smtp_auth {
+
+ postfix::config {
+ 'smtpd_tls_ask_ccert': value => 'yes';
+ }
+}
diff --git a/puppet/modules/site_postfix/manifests/mx/smtp_tls.pp b/puppet/modules/site_postfix/manifests/mx/smtp_tls.pp
new file mode 100644
index 00000000..d9b59f40
--- /dev/null
+++ b/puppet/modules/site_postfix/manifests/mx/smtp_tls.pp
@@ -0,0 +1,27 @@
+class site_postfix::mx::smtp_tls {
+
+ include x509::variables
+ $ca_path = "${x509::variables::local_CAs}/${site_config::params::ca_name}.crt"
+ $cert_path = "${x509::variables::certs}/${site_config::params::cert_name}.crt"
+ $key_path = "${x509::variables::keys}/${site_config::params::cert_name}.key"
+
+ # smtp TLS
+ postfix::config {
+ 'smtp_use_tls': value => 'yes';
+ 'smtp_tls_CApath': value => '/etc/ssl/certs/';
+ 'smtp_tls_CAfile': value => $ca_path;
+ 'smtp_tls_cert_file': value => $cert_path;
+ 'smtp_tls_key_file': value => $key_path;
+ 'smtp_tls_loglevel': value => '1';
+ 'smtp_tls_exclude_ciphers':
+ value => 'aNULL, MD5, DES';
+ # upstream default is md5 (since 2.5 and older used it), we force sha1
+ 'smtp_tls_fingerprint_digest':
+ value => 'sha1';
+ 'smtp_tls_session_cache_database':
+ value => 'btree:${data_directory}/smtp_cache';
+ # see issue #4011
+ 'smtp_tls_protocols':
+ value => '!SSLv2, !SSLv3';
+ }
+}
diff --git a/puppet/modules/site_postfix/manifests/mx/smtpd_checks.pp b/puppet/modules/site_postfix/manifests/mx/smtpd_checks.pp
new file mode 100644
index 00000000..0ec40277
--- /dev/null
+++ b/puppet/modules/site_postfix/manifests/mx/smtpd_checks.pp
@@ -0,0 +1,31 @@
+class site_postfix::mx::smtpd_checks {
+
+ postfix::config {
+ 'smtpd_helo_required':
+ value => 'yes';
+ 'checks_dir':
+ value => '$config_directory/checks';
+ 'smtpd_client_restrictions':
+ value => 'permit_mynetworks,permit';
+ 'smtpd_data_restrictions':
+ value => 'permit_mynetworks, reject_unauth_pipelining, permit';
+ 'smtpd_delay_reject':
+ value => 'yes';
+ 'smtpd_helo_restrictions':
+ value => 'permit_mynetworks, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, check_helo_access hash:$checks_dir/helo_checks, permit';
+ 'smtpd_recipient_restrictions':
+ value => 'reject_unknown_recipient_domain, permit_mynetworks, check_recipient_access tcp:localhost:2244, reject_unauth_destination, permit';
+ # We should change from permit_tls_all_clientcerts to permit_tls_clientcerts
+ # with a lookup on $relay_clientcerts! Right now we are listing the only
+ # valid CA that client certificates can use in the $smtp_tls_CAfile parameter
+ # but we cannot cut off a certificate that should no longer be used unless
+ # we use permit_tls_clientcerts with the $relay_clientcerts lookup
+ 'smtps_recipient_restrictions':
+ value => 'permit_tls_all_clientcerts, check_recipient_access tcp:localhost:2244, reject_unauth_destination, permit';
+ 'smtps_helo_restrictions':
+ value => 'permit_mynetworks, check_helo_access hash:$checks_dir/helo_checks, permit';
+ 'smtpd_sender_restrictions':
+ value => 'permit_mynetworks, reject_non_fqdn_sender, reject_unknown_sender_domain, permit';
+ }
+
+}
diff --git a/puppet/modules/site_postfix/manifests/mx/smtpd_tls.pp b/puppet/modules/site_postfix/manifests/mx/smtpd_tls.pp
new file mode 100644
index 00000000..0809c75f
--- /dev/null
+++ b/puppet/modules/site_postfix/manifests/mx/smtpd_tls.pp
@@ -0,0 +1,55 @@
+class site_postfix::mx::smtpd_tls {
+
+ include x509::variables
+ $ca_path = "${x509::variables::local_CAs}/${site_config::params::client_ca_name}.crt"
+ $cert_path = "${x509::variables::certs}/${site_config::params::cert_name}.crt"
+ $key_path = "${x509::variables::keys}/${site_config::params::cert_name}.key"
+
+
+ postfix::config {
+ 'smtpd_use_tls': value => 'yes';
+ 'smtpd_tls_CAfile': value => $ca_path;
+ 'smtpd_tls_cert_file': value => $cert_path;
+ 'smtpd_tls_key_file': value => $key_path;
+ 'smtpd_tls_ask_ccert': value => 'yes';
+ 'smtpd_tls_security_level':
+ value => 'may';
+ 'smtpd_tls_eecdh_grade':
+ value => 'ultra';
+ 'smtpd_tls_session_cache_database':
+ value => 'btree:${data_directory}/smtpd_scache';
+ }
+
+ # Setup DH parameters
+ # Instead of using the dh parameters that are created by leap cli, it is more
+ # secure to generate new parameter files that will only be used for postfix,
+ # for each machine
+
+ include site_config::packages::gnutls
+
+ # Note, the file name is called dh_1024.pem, but we are generating 2048bit dh
+ # parameters Neither Postfix nor OpenSSL actually care about the size of the
+ # prime in "smtpd_tls_dh1024_param_file". You can make it 2048 bits
+
+ exec { 'certtool-postfix-gendh':
+ command => 'certtool --generate-dh-params --bits 2048 --outfile /etc/postfix/smtpd_tls_dh_param.pem',
+ user => root,
+ group => root,
+ creates => '/etc/postfix/smtpd_tls_dh_param.pem',
+ require => [ Package['gnutls-bin'], Package['postfix'] ]
+ }
+
+ # Make sure the dh params file has correct ownership and mode
+ file {
+ '/etc/postfix/smtpd_tls_dh_param.pem':
+ owner => root,
+ group => root,
+ mode => '0600',
+ require => Exec['certtool-postfix-gendh'];
+ }
+
+ postfix::config { 'smtpd_tls_dh1024_param_file':
+ value => '/etc/postfix/smtpd_tls_dh_param.pem',
+ require => File['/etc/postfix/smtpd_tls_dh_param.pem']
+ }
+}
diff --git a/puppet/modules/site_postfix/manifests/satellite.pp b/puppet/modules/site_postfix/manifests/satellite.pp
new file mode 100644
index 00000000..5725e6b8
--- /dev/null
+++ b/puppet/modules/site_postfix/manifests/satellite.pp
@@ -0,0 +1,47 @@
+class site_postfix::satellite {
+
+ $root_mail_recipient = hiera ('contacts')
+ $mail = hiera ('mail')
+ $relayhost = $mail['smarthost']
+ $cert_name = hiera('name')
+
+ class { '::postfix::satellite':
+ relayhost => $relayhost,
+ root_mail_recipient => $root_mail_recipient
+ }
+
+ # There are special conditions for satellite hosts that will make them not be
+ # able to contact their relayhost:
+ #
+ # 1. they are on openstack/amazon/PC and are on the same cluster as the relay
+ # host, the MX lookup for the relay host will use the public IP, which cannot
+ # be contacted
+ #
+ # 2. When a domain is used that is not in DNS, because it is internal,
+ # a testing domain, etc. eg. a .local domain cannot be looked up in DNS
+ #
+ # to resolve this, so the satellite can contact the relayhost, we need to set
+ # the http://www.postfix.org/postconf.5.html#smtp_host_lookup to be 'native'
+ # which will cause the lookup to use the native naming service
+ # (nsswitch.conf), which typically defaults to 'files, dns' allowing the
+ # /etc/hosts to be consulted first, then DNS if the entry doesn't exist.
+ #
+ # NOTE: this will make it not possible to enable DANE support through DNSSEC
+ # with http://www.postfix.org/postconf.5.html#smtp_dns_support_level - but
+ # this parameter is not available until 2.11. If this ends up being important
+ # we could also make this an optional parameter for providers without
+ # dns / local domains
+
+ postfix::config {
+ 'smtp_host_lookup':
+ value => 'native';
+
+ # Note: we are setting this here, instead of in site_postfix::mx::smtp_tls
+ # because the mx server has to have a different value
+ 'smtp_tls_security_level':
+ value => 'encrypt';
+ }
+
+ include site_postfix::mx::smtp_tls
+
+}
diff --git a/puppet/modules/site_postfix/templates/checks/helo_access.erb b/puppet/modules/site_postfix/templates/checks/helo_access.erb
new file mode 100644
index 00000000..bef3c11d
--- /dev/null
+++ b/puppet/modules/site_postfix/templates/checks/helo_access.erb
@@ -0,0 +1,21 @@
+# THIS FILE IS MANAGED BY PUPPET
+# To make changes to this file, please edit your platform directory under
+# puppet/modules/site_postfix/templates/checks/helo_access.erb and then deploy
+
+# The format of this file is the HELO/EHLO domain followed by an action.
+# The action could be OK to allow it, REJECT to reject it, or a custom
+# status code and message. Any lines that are prefixed by an octothorpe (#)
+# will be considered comments.
+
+# Some examples:
+#
+# Reject anyone that HELO's with foobar:
+# foobar REJECT
+#
+# Allow the switches to skip this check:
+# switch1 OK
+# switch2 OK
+
+# 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 %>
diff --git a/puppet/modules/site_shorewall/manifests/defaults.pp b/puppet/modules/site_shorewall/manifests/defaults.pp
index c62c9307..8f56ac42 100644
--- a/puppet/modules/site_shorewall/manifests/defaults.pp
+++ b/puppet/modules/site_shorewall/manifests/defaults.pp
@@ -1,9 +1,12 @@
class site_shorewall::defaults {
+
include shorewall
include site_config::params
# be safe for development
- #if ( $::virtual == 'virtualbox') { $shorewall_startup='0' }
+ # if ( $::site_config::params::environment == 'local' ) {
+ # $shorewall_startup='0'
+ # }
# If you want logging:
shorewall::params {
@@ -18,8 +21,6 @@ class site_shorewall::defaults {
options => 'tcpflags,blacklist,nosmurfs';
}
- shorewall::routestopped { $site_config::params::interface: }
-
shorewall::policy {
'fw-to-all':
sourcezone => 'fw',
@@ -42,5 +43,32 @@ class site_shorewall::defaults {
order => 200;
}
+ package { 'shorewall-init':
+ ensure => installed
+ }
+
+ augeas {
+ # stop instead of clear firewall on shutdown
+ 'shorewall_SAFESTOP':
+ changes => 'set /files/etc/shorewall/shorewall.conf/SAFESTOP Yes',
+ lens => 'Shellvars.lns',
+ incl => '/etc/shorewall/shorewall.conf',
+ require => Package['shorewall'],
+ notify => Service[shorewall];
+ # 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];
+ # configure shorewall-init
+ 'shorewall-init':
+ changes => 'set /files/etc/default/shorewall-init/PRODUCTS shorewall',
+ lens => 'Shellvars.lns',
+ incl => '/etc/default/shorewall-init',
+ require => [ Package['shorewall-init'], Service['shorewall'] ]
+ }
+
include site_shorewall::sshd
}
diff --git a/puppet/modules/site_shorewall/manifests/mx.pp b/puppet/modules/site_shorewall/manifests/mx.pp
new file mode 100644
index 00000000..332f164e
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/mx.pp
@@ -0,0 +1,24 @@
+class site_shorewall::mx {
+
+ include site_shorewall::defaults
+
+ $smtpd_ports = '25,465,587'
+
+ # define macro for incoming services
+ file { '/etc/shorewall/macro.leap_mx':
+ content => "PARAM - - tcp ${smtpd_ports} ",
+ notify => Service['shorewall'],
+ require => Package['shorewall']
+ }
+
+
+ shorewall::rule {
+ 'net2fw-mx':
+ source => 'net',
+ destination => '$FW',
+ action => 'leap_mx(ACCEPT)',
+ order => 200;
+ }
+
+ include site_shorewall::service::smtp
+}
diff --git a/puppet/modules/site_shorewall/manifests/service/smtp.pp b/puppet/modules/site_shorewall/manifests/service/smtp.pp
new file mode 100644
index 00000000..7fbdf14e
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/service/smtp.pp
@@ -0,0 +1,13 @@
+class site_shorewall::service::smtp {
+
+ include site_shorewall::defaults
+
+ shorewall::rule {
+ 'fw2net-http':
+ source => '$FW',
+ destination => 'net',
+ action => 'SMTP(ACCEPT)',
+ order => 200;
+ }
+
+}
diff --git a/puppet/modules/site_shorewall/manifests/soledad.pp b/puppet/modules/site_shorewall/manifests/soledad.pp
new file mode 100644
index 00000000..518d8689
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/soledad.pp
@@ -0,0 +1,23 @@
+class site_shorewall::soledad {
+
+ $soledad = hiera('soledad')
+ $soledad_port = $soledad['port']
+
+ include site_shorewall::defaults
+
+ # define macro for incoming services
+ file { '/etc/shorewall/macro.leap_soledad':
+ content => "PARAM - - tcp ${soledad_port}",
+ notify => Service['shorewall'],
+ require => Package['shorewall']
+ }
+
+ shorewall::rule {
+ 'net2fw-soledad':
+ source => 'net',
+ destination => '$FW',
+ action => 'leap_soledad(ACCEPT)',
+ order => 200;
+ }
+}
+
diff --git a/puppet/modules/site_shorewall/manifests/sshd.pp b/puppet/modules/site_shorewall/manifests/sshd.pp
index a8e09e42..88b4102c 100644
--- a/puppet/modules/site_shorewall/manifests/sshd.pp
+++ b/puppet/modules/site_shorewall/manifests/sshd.pp
@@ -21,4 +21,10 @@ class site_shorewall::sshd {
action => 'leap_sshd(ACCEPT)',
order => 200;
}
+
+ # setup a routestopped rule to allow ssh when shorewall is stopped
+ shorewall::routestopped { $site_config::params::interface:
+ options => "- tcp ${ssh_port}"
+ }
+
}
diff --git a/puppet/modules/site_squid_deb_proxy/manifests/client.pp b/puppet/modules/site_squid_deb_proxy/manifests/client.pp
new file mode 100644
index 00000000..27844270
--- /dev/null
+++ b/puppet/modules/site_squid_deb_proxy/manifests/client.pp
@@ -0,0 +1,5 @@
+class site_squid_deb_proxy::client {
+ include squid_deb_proxy::client
+ include site_shorewall::defaults
+ include shorewall::rules::mdns
+}
diff --git a/puppet/modules/site_sshd/manifests/authorized_keys.pp b/puppet/modules/site_sshd/manifests/authorized_keys.pp
index c18f691c..f36fe20f 100644
--- a/puppet/modules/site_sshd/manifests/authorized_keys.pp
+++ b/puppet/modules/site_sshd/manifests/authorized_keys.pp
@@ -1,4 +1,7 @@
define site_sshd::authorized_keys ($keys, $ensure = 'present', $home = '') {
+ # We use a custom define here to deploy the authorized_keys file
+ # cause puppet doesn't allow purgin before populating this file
+ # (see https://tickets.puppetlabs.com/browse/PUP-1174)
# This line allows default homedir based on $title variable.
# If $home is empty, the default is used.
$homedir = $home ? {'' => "/home/${title}", default => $home}
diff --git a/puppet/modules/site_sshd/manifests/init.pp b/puppet/modules/site_sshd/manifests/init.pp
index 90dd2d0e..d9bc1d51 100644
--- a/puppet/modules/site_sshd/manifests/init.pp
+++ b/puppet/modules/site_sshd/manifests/init.pp
@@ -1,5 +1,6 @@
class site_sshd {
$ssh = hiera_hash('ssh')
+ $hosts = hiera('hosts', '')
##
## SETUP AUTHORIZED KEYS
@@ -12,6 +13,23 @@ class site_sshd {
}
##
+ ## SETUP KNOWN HOSTS and SSH_CONFIG
+ ##
+
+ file {
+ '/etc/ssh/ssh_known_hosts':
+ owner => root,
+ group => root,
+ mode => '0644',
+ content => template('site_sshd/ssh_known_hosts.erb');
+ '/etc/ssh/ssh_config':
+ owner => root,
+ group => root,
+ mode => '0644',
+ content => template('site_sshd/ssh_config.erb');
+ }
+
+ ##
## OPTIONAL MOSH SUPPORT
##
diff --git a/puppet/modules/site_sshd/templates/authorized_keys.erb b/puppet/modules/site_sshd/templates/authorized_keys.erb
index 3c65e8ab..69f4d8e6 100644
--- a/puppet/modules/site_sshd/templates/authorized_keys.erb
+++ b/puppet/modules/site_sshd/templates/authorized_keys.erb
@@ -2,5 +2,9 @@
# all manually added keys will be overridden
<% keys.sort.each do |user, hash| -%>
+<% if user == 'monitor' -%>
+command="/usr/bin/check_mk_agent",no-port-forwarding,no-x11-forwarding,no-agent-forwarding,no-pty,no-user-rc, <%=hash['type']-%> <%=hash['key']%> <%=user%>
+<% else -%>
<%=hash['type']-%> <%=hash['key']%> <%=user%>
+<% end -%>
<% end -%>
diff --git a/puppet/modules/site_sshd/templates/ssh_config.erb b/puppet/modules/site_sshd/templates/ssh_config.erb
new file mode 100644
index 00000000..7e967413
--- /dev/null
+++ b/puppet/modules/site_sshd/templates/ssh_config.erb
@@ -0,0 +1,23 @@
+# This file is generated by Puppet
+# This is the ssh client system-wide configuration file. See
+# ssh_config(5) for more information. This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+Host *
+ SendEnv LANG LC_*
+ HashKnownHosts yes
+ GSSAPIAuthentication yes
+ GSSAPIDelegateCredentials no
+<% if scope.lookupvar('::site_config::params::environment') == 'local' -%>
+ #
+ # Vagrant nodes should have strict host key checking
+ # turned off. The problem is that the host key for a vagrant
+ # node is specific to the particular instance of the vagrant
+ # node you have running locally. For this reason, we can't
+ # track the host keys, or your host key for vpn1 would conflict
+ # with my host key for vpn1.
+ #
+ StrictHostKeyChecking no
+<% end -%>
+
diff --git a/puppet/modules/site_sshd/templates/ssh_known_hosts.erb b/puppet/modules/site_sshd/templates/ssh_known_hosts.erb
new file mode 100644
index 00000000..002ab732
--- /dev/null
+++ b/puppet/modules/site_sshd/templates/ssh_known_hosts.erb
@@ -0,0 +1,7 @@
+# This file is generated by Puppet
+
+<% @hosts.sort.each do |name, hash| -%>
+<% if hash['host_pub_key'] -%>
+<%= name%>,<%=hash['domain_full']%>,<%=hash['domain_internal']%>,<%=hash['ip_address']%> <%=hash['host_pub_key']%>
+<% end -%>
+<% end -%>
diff --git a/puppet/modules/site_static/README b/puppet/modules/site_static/README
new file mode 100644
index 00000000..bc719782
--- /dev/null
+++ b/puppet/modules/site_static/README
@@ -0,0 +1,3 @@
+Deploy one or more static websites to a node.
+
+For now, it only supports `amber` based static sites. Should support plain html and jekyll in the future.
diff --git a/puppet/modules/site_static/manifests/domain.pp b/puppet/modules/site_static/manifests/domain.pp
new file mode 100644
index 00000000..8af2230f
--- /dev/null
+++ b/puppet/modules/site_static/manifests/domain.pp
@@ -0,0 +1,28 @@
+define site_static::domain (
+ $locations,
+ $ca_cert,
+ $key,
+ $cert,
+ $tls_only) {
+
+ $domain = $name
+ $base_dir = '/srv/static'
+
+ create_resources(site_static::location, $locations)
+
+ x509::cert { $domain: content => $cert }
+ x509::key { $domain: content => $key }
+ x509::ca { "${domain}_ca": content => $ca_cert }
+
+ class { '::apache': no_default_site => true, ssl => true }
+ include site_apache::module::headers
+ include site_apache::module::alias
+ include site_apache::module::expires
+ include site_apache::module::removeip
+ include site_apache::module::rewrite
+
+ apache::vhost::file { $domain:
+ content => template('site_static/apache.conf.erb')
+ }
+
+}
diff --git a/puppet/modules/site_static/manifests/init.pp b/puppet/modules/site_static/manifests/init.pp
new file mode 100644
index 00000000..91a4a7a9
--- /dev/null
+++ b/puppet/modules/site_static/manifests/init.pp
@@ -0,0 +1,17 @@
+class site_static {
+ tag 'leap_service'
+ $static = hiera('static')
+ $domains = $static['domains']
+ $formats = $static['formats']
+
+ if (member($formats, 'amber')) {
+ include site_config::ruby::dev
+ rubygems::gem{'amber': }
+ }
+
+ create_resources(site_static::domain, $domains)
+
+ include site_shorewall::defaults
+ include site_shorewall::service::http
+ include site_shorewall::service::https
+} \ No newline at end of file
diff --git a/puppet/modules/site_static/manifests/location.pp b/puppet/modules/site_static/manifests/location.pp
new file mode 100644
index 00000000..1ba6807e
--- /dev/null
+++ b/puppet/modules/site_static/manifests/location.pp
@@ -0,0 +1,25 @@
+define site_static::location($path, $format, $source) {
+
+ $file_path = "/srv/static/${name}"
+
+ if ($format == 'amber') {
+ exec {"amber_build_${name}":
+ cwd => $file_path,
+ command => 'amber rebuild',
+ user => 'www-data',
+ timeout => 600,
+ subscribe => Vcsrepo[$file_path]
+ }
+ }
+
+ vcsrepo { $file_path:
+ ensure => present,
+ force => true,
+ revision => $source['revision'],
+ provider => $source['type'],
+ source => $source['repo'],
+ owner => 'www-data',
+ group => 'www-data'
+ }
+
+}
diff --git a/puppet/modules/site_static/templates/apache.conf.erb b/puppet/modules/site_static/templates/apache.conf.erb
new file mode 100644
index 00000000..2abe1a98
--- /dev/null
+++ b/puppet/modules/site_static/templates/apache.conf.erb
@@ -0,0 +1,77 @@
+<%-
+ ##
+ ## An apache config for static websites.
+ ##
+ def location_directory(name, location)
+ if location['format'] == 'amber'
+ File.join(@base_dir, name, 'public')
+ else
+ File.join(@base_dir, name)
+ end
+ end
+ document_root = '/var/www'
+ @locations.each do |name, location|
+ if location['path'] == '/'
+ document_root = location_directory(name, location)
+ end
+ end
+ document_root = document_root.gsub(%r{^/|/$}, '')
+-%>
+
+<VirtualHost *:80>
+ ServerName <%= @domain %>
+ ServerAlias www.<%= @domain %>
+ RewriteEngine On
+ RewriteRule ^.*$ https://<%= @domain -%>%{REQUEST_URI} [R=permanent,L]
+</VirtualHost>
+
+<VirtualHost *:443>
+ ServerName <%= @domain %>
+ ServerAlias www.<%= @domain %>
+
+ #RewriteLog "/var/log/apache2/rewrite.log"
+ #RewriteLogLevel 3
+
+ SSLEngine on
+ SSLProtocol all -SSLv2
+ SSLHonorCipherOrder on
+ SSLCompression off
+ SSLCipherSuite "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK"
+
+ Header add Strict-Transport-Security: "max-age=15768000;includeSubdomains"
+ Header set X-Frame-Options "deny"
+
+ SSLCertificateKeyFile /etc/x509/keys/<%= @domain %>.key
+ SSLCertificateFile /etc/x509/certs/<%= @domain %>.crt
+ SSLCertificateChainFile /etc/ssl/certs/<%= @domain %>_ca.pem
+
+ RequestHeader set X_FORWARDED_PROTO 'https'
+
+ DocumentRoot "/<%= document_root %>/"
+ AccessFileName .htaccess
+
+<%- @locations.each do |name, location| -%>
+ <%- path = location['path'].gsub(%r{^/|/$}, '') -%>
+ <%- directory = location_directory(name, location) -%>
+ ##
+ ## <%= name %>
+ ##
+ <%- if path == '' -%>
+ <Directory "/<%= document_root %>/">
+ AllowOverride FileInfo Indexes Options=All,MultiViews
+ Order deny,allow
+ Allow from all
+ </Directory>
+ <%- else -%>
+ AliasMatch ^/[a-z]{2}/<%=path%>(/.+|/|)$ "/<%=directory%>/$1"
+ Alias /<%=path%> "/<%=directory%>/"
+ <Directory "/<%=directory%>/">
+ AllowOverride FileInfo Indexes Options=All,MultiViews
+ Order deny,allow
+ Allow from all
+ </Directory>
+ <%- end -%>
+
+<%- end -%>
+
+</VirtualHost>
diff --git a/puppet/modules/site_stunnel/manifests/clients.pp b/puppet/modules/site_stunnel/manifests/clients.pp
index ed766e1a..837665a3 100644
--- a/puppet/modules/site_stunnel/manifests/clients.pp
+++ b/puppet/modules/site_stunnel/manifests/clients.pp
@@ -21,6 +21,13 @@ define site_stunnel::clients (
verify => $verify,
pid => "/var/run/stunnel4/${pid}.pid",
rndfile => $rndfile,
- debuglevel => $debuglevel
+ debuglevel => $debuglevel,
+ require => [
+ Class['Site_config::X509::Key'],
+ Class['Site_config::X509::Cert'],
+ Class['Site_config::X509::Ca'] ];
+
}
+
+ include site_check_mk::agent::stunnel
}
diff --git a/puppet/modules/site_stunnel/manifests/setup.pp b/puppet/modules/site_stunnel/manifests/setup.pp
deleted file mode 100644
index 92eeb425..00000000
--- a/puppet/modules/site_stunnel/manifests/setup.pp
+++ /dev/null
@@ -1,24 +0,0 @@
-class site_stunnel::setup ($cert_name, $key, $cert, $ca_name, $ca) {
-
- include site_stunnel
-
- x509::key {
- $cert_name:
- content => $key,
- notify => Service['stunnel'];
- }
-
- x509::cert {
- $cert_name:
- content => $cert,
- notify => Service['stunnel'];
- }
-
- x509::ca {
- $ca_name:
- content => $ca,
- notify => Service['stunnel'];
- }
-
-}
-
diff --git a/puppet/modules/site_tor/manifests/init.pp b/puppet/modules/site_tor/manifests/init.pp
index 50ab636b..02368a0e 100644
--- a/puppet/modules/site_tor/manifests/init.pp
+++ b/puppet/modules/site_tor/manifests/init.pp
@@ -1,11 +1,12 @@
class site_tor {
tag 'leap_service'
+ Class['site_config::default'] -> Class['site_tor']
$tor = hiera('tor')
$bandwidth_rate = $tor['bandwidth_rate']
$tor_type = $tor['type']
$nickname = $tor['nickname']
- $contact_email = $tor['contacts']
+ $contact_emails = join($tor['contacts'],', ')
$address = hiera('ip_address')
@@ -13,17 +14,22 @@ class site_tor {
tor::daemon::relay { $nickname:
port => 9001,
address => $address,
- contact_info => $contact_email,
+ contact_info => obfuscate_email($contact_emails),
bandwidth_rate => $bandwidth_rate,
my_family => '$2A431444756B0E7228A7918C85A8DACFF7E3B050',
}
- tor::daemon::directory { $::hostname: port => 80 }
-
- include site_shorewall::tor
-
- if ( $tor_type != 'exit' ) {
+ if ( $tor_type == 'exit'){
+ tor::daemon::directory { $::hostname: port => 80 }
+ }
+ else {
+ tor::daemon::directory { $::hostname:
+ port => 80,
+ port_front_page => '';
+ }
include site_tor::disable_exit
}
+ include site_shorewall::tor
+
}
diff --git a/puppet/modules/site_webapp/files/migrate_design_documents b/puppet/modules/site_webapp/files/migrate_design_documents
deleted file mode 100644
index 6e24aa5b..00000000
--- a/puppet/modules/site_webapp/files/migrate_design_documents
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-cd /srv/leap/webapp
-
-# use admin credentials
-cp config/couchdb.yml.admin config/couchdb.yml
-chown leap-webapp:leap-webapp config/couchdb.yml
-
-# needs to be run twice
-RAILS_ENV=production /usr/bin/bundle exec rake couchrest:migrate
-RAILS_ENV=production /usr/bin/bundle exec rake couchrest:migrate
-
-# use user credentials and remove admin credentials
-cp config/couchdb.yml.webapp config/couchdb.yml
-chown leap-webapp:leap-webapp config/couchdb.yml
-
diff --git a/puppet/modules/site_webapp/manifests/apache.pp b/puppet/modules/site_webapp/manifests/apache.pp
index 8b340160..21243d34 100644
--- a/puppet/modules/site_webapp/manifests/apache.pp
+++ b/puppet/modules/site_webapp/manifests/apache.pp
@@ -4,61 +4,20 @@ class site_webapp::apache {
$api_domain = $web_api['domain']
$api_port = $web_api['port']
- $x509 = hiera('x509')
- $commercial_key = $x509['commercial_key']
- $commercial_cert = $x509['commercial_cert']
- $commercial_root = $x509['commercial_ca_cert']
- $api_key = $x509['key']
- $api_cert = $x509['cert']
- $api_root = $x509['ca_cert']
+ $web_domain = hiera('domain')
+ $domain_name = $web_domain['name']
- class { '::apache': no_default_site => true, ssl => true }
-
- apache::module {
- 'alias': ensure => present;
- 'rewrite': ensure => present;
- 'headers': ensure => present;
- }
+ include site_apache::common
+ include site_apache::module::headers
+ include site_apache::module::alias
+ include site_apache::module::expires
+ include site_apache::module::removeip
class { 'passenger': use_munin => false }
apache::vhost::file {
- 'leap_webapp':
- content => template('site_apache/vhosts.d/leap_webapp.conf.erb')
- }
-
- apache::vhost::file {
'api':
content => template('site_apache/vhosts.d/api.conf.erb')
}
- x509::key {
- 'leap_webapp':
- content => $commercial_key,
- notify => Service[apache];
-
- 'leap_api':
- content => $api_key,
- notify => Service[apache];
- }
-
- x509::cert {
- 'leap_webapp':
- content => $commercial_cert,
- notify => Service[apache];
-
- 'leap_api':
- content => $api_cert,
- notify => Service[apache];
- }
-
- x509::ca {
- 'leap_webapp':
- content => $commercial_root,
- notify => Service[apache];
-
- 'leap_api':
- content => $api_root,
- notify => Service[apache];
- }
}
diff --git a/puppet/modules/site_webapp/manifests/client_ca.pp b/puppet/modules/site_webapp/manifests/client_ca.pp
deleted file mode 100644
index 0d9b15d6..00000000
--- a/puppet/modules/site_webapp/manifests/client_ca.pp
+++ /dev/null
@@ -1,25 +0,0 @@
-##
-## This is for the special CA that is used exclusively for generating
-## client certificates by the webapp.
-##
-
-class site_webapp::client_ca {
- include x509::variables
-
- $x509 = hiera('x509')
- $cert_path = "${x509::variables::certs}/leap_client_ca.crt"
- $key_path = "${x509::variables::keys}/leap_client_ca.key"
-
- x509::key {
- 'leap_client_ca':
- source => $x509['client_ca_key'],
- group => 'leap-webapp',
- notify => Service[apache];
- }
-
- x509::cert {
- 'leap_client_ca':
- source => $x509['client_ca_cert'],
- notify => Service[apache];
- }
-}
diff --git a/puppet/modules/site_webapp/manifests/couchdb.pp b/puppet/modules/site_webapp/manifests/couchdb.pp
index b4ef0980..ff743fba 100644
--- a/puppet/modules/site_webapp/manifests/couchdb.pp
+++ b/puppet/modules/site_webapp/manifests/couchdb.pp
@@ -4,8 +4,6 @@ class site_webapp::couchdb {
# haproxy listener on port localhost:4096, see site_webapp::haproxy
$couchdb_host = 'localhost'
$couchdb_port = '4096'
- $couchdb_admin_user = $webapp['couchdb_admin_user']['username']
- $couchdb_admin_password = $webapp['couchdb_admin_user']['password']
$couchdb_webapp_user = $webapp['couchdb_webapp_user']['username']
$couchdb_webapp_password = $webapp['couchdb_webapp_user']['password']
@@ -14,65 +12,38 @@ class site_webapp::couchdb {
$couch_client_connect = $couch_client['connect']
include x509::variables
- $x509 = hiera('x509')
- $key = $x509['key']
- $cert = $x509['cert']
- $ca = $x509['ca_cert']
- $cert_name = 'leap_couchdb'
- $ca_name = 'leap_ca'
- $ca_path = "${x509::variables::local_CAs}/${ca_name}.crt"
- $cert_path = "${x509::variables::certs}/${cert_name}.crt"
- $key_path = "${x509::variables::keys}/${cert_name}.key"
file {
- '/srv/leap/webapp/config/couchdb.yml.admin':
- content => template('site_webapp/couchdb.yml.admin.erb'),
+ '/srv/leap/webapp/config/couchdb.yml':
+ content => template('site_webapp/couchdb.yml.erb'),
owner => leap-webapp,
group => leap-webapp,
mode => '0600',
require => Vcsrepo['/srv/leap/webapp'];
- '/srv/leap/webapp/config/couchdb.yml.webapp':
- content => template('site_webapp/couchdb.yml.erb'),
+ '/srv/leap/webapp/log':
+ ensure => directory,
owner => leap-webapp,
group => leap-webapp,
- mode => '0600',
+ mode => '0755',
require => Vcsrepo['/srv/leap/webapp'];
- '/srv/leap/webapp/logs/production.log':
+ '/srv/leap/webapp/log/production.log':
+ ensure => present,
owner => leap-webapp,
group => leap-webapp,
mode => '0666',
require => Vcsrepo['/srv/leap/webapp'];
-
- '/usr/local/sbin/migrate_design_documents':
- source => 'puppet:///modules/site_webapp/migrate_design_documents',
- owner => root,
- group => root,
- mode => '0744';
}
- class { 'site_stunnel::setup':
- cert_name => $cert_name,
- key => $key,
- cert => $cert,
- ca_name => $ca_name,
- ca => $ca
- }
-
- exec { 'migrate_design_documents':
- cwd => '/srv/leap/webapp',
- command => '/usr/local/sbin/migrate_design_documents',
- require => Exec['bundler_update'],
- notify => Service['apache'];
- }
+ include site_stunnel
$couchdb_stunnel_client_defaults = {
'connect_port' => $couch_client_connect,
- 'client' => true,
- 'cafile' => $ca_path,
- 'key' => $key_path,
- 'cert' => $cert_path,
+ 'client' => true,
+ 'cafile' => "${x509::variables::local_CAs}/${site_config::params::ca_name}.crt",
+ 'key' => "${x509::variables::keys}/${site_config::params::cert_name}.key",
+ 'cert' => "${x509::variables::certs}/${site_config::params::cert_name}.crt",
}
create_resources(site_stunnel::clients, $couch_client, $couchdb_stunnel_client_defaults)
diff --git a/puppet/modules/site_webapp/manifests/cron.pp b/puppet/modules/site_webapp/manifests/cron.pp
new file mode 100644
index 00000000..811ad11d
--- /dev/null
+++ b/puppet/modules/site_webapp/manifests/cron.pp
@@ -0,0 +1,17 @@
+class site_webapp::cron {
+
+ # cron tasks that need to be performed to cleanup the database
+ cron {
+ 'remove_expired_sessions':
+ command => 'cd /srv/leap/webapp && bundle exec rake cleanup:sessions',
+ environment => 'RAILS_ENV=production',
+ hour => 2,
+ minute => 30;
+
+ 'remove_expired_tokens':
+ command => 'cd /srv/leap/webapp && bundle exec rake cleanup:tokens',
+ environment => 'RAILS_ENV=production',
+ hour => 3,
+ minute => 0;
+ }
+}
diff --git a/puppet/modules/site_webapp/manifests/haproxy.pp b/puppet/modules/site_webapp/manifests/haproxy.pp
index 4a7e3c25..b69c69da 100644
--- a/puppet/modules/site_webapp/manifests/haproxy.pp
+++ b/puppet/modules/site_webapp/manifests/haproxy.pp
@@ -3,7 +3,6 @@ class site_webapp::haproxy {
include site_haproxy
$haproxy = hiera('haproxy')
- $local_ports = $haproxy['local_ports']
# Template uses $global_options, $defaults_options
concat::fragment { 'leap_haproxy_webapp_couchdb':
diff --git a/puppet/modules/site_webapp/manifests/init.pp b/puppet/modules/site_webapp/manifests/init.pp
index e743dc07..d02a7261 100644
--- a/puppet/modules/site_webapp/manifests/init.pp
+++ b/puppet/modules/site_webapp/manifests/init.pp
@@ -11,11 +11,18 @@ class site_webapp {
$api_version = $webapp['api_version']
$secret_token = $webapp['secret_token']
- include site_config::ruby
+ Class['site_config::default'] -> Class['site_webapp']
+
+ include site_config::ruby::dev
include site_webapp::apache
include site_webapp::couchdb
- include site_webapp::client_ca
include site_webapp::haproxy
+ include site_webapp::cron
+ 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
group { 'leap-webapp':
ensure => present,
@@ -31,19 +38,12 @@ class site_webapp {
require => [ Group['leap-webapp'] ];
}
- file { '/srv/leap/webapp':
- ensure => directory,
- owner => 'leap-webapp',
- group => 'leap-webapp',
- require => User['leap-webapp'];
- }
-
vcsrepo { '/srv/leap/webapp':
ensure => present,
force => true,
- revision => 'origin/master',
+ revision => $webapp['git']['revision'],
provider => git,
- source => 'git://code.leap.se/leap_web',
+ source => $webapp['git']['source'],
owner => 'leap-webapp',
group => 'leap-webapp',
require => [ User['leap-webapp'], Group['leap-webapp'] ],
@@ -56,38 +56,58 @@ class site_webapp {
unless => '/usr/bin/bundle check',
user => 'leap-webapp',
timeout => 600,
- require => [ Class['bundler::install'], Vcsrepo['/srv/leap/webapp'] ],
+ require => [
+ Class['bundler::install'],
+ Vcsrepo['/srv/leap/webapp'],
+ Class['site_config::ruby::dev'],
+ Service['shorewall'] ],
notify => Service['apache'];
}
+ #
+ # NOTE: in order to support a webapp that is running on a subpath and not the
+ # root of the domain assets:precompile needs to be run with
+ # RAILS_RELATIVE_URL_ROOT=/application-root
+ #
+
exec { 'compile_assets':
- cwd => '/srv/leap/webapp',
- command => '/bin/bash -c "/usr/bin/bundle exec rake assets:precompile"',
- user => 'leap-webapp',
- require => Exec['bundler_update'],
- notify => Service['apache'];
+ cwd => '/srv/leap/webapp',
+ command => '/bin/bash -c "RAILS_ENV=production /usr/bin/bundle exec rake assets:precompile"',
+ user => 'leap-webapp',
+ logoutput => on_failure,
+ require => Exec['bundler_update'],
+ notify => Service['apache'];
}
file {
- '/srv/leap/webapp/public/provider.json':
+ '/srv/leap/webapp/config/provider':
+ ensure => directory,
+ require => Vcsrepo['/srv/leap/webapp'],
+ 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';
+ # old provider.json location. this can be removed after everyone upgrades.
+ '/srv/leap/webapp/public/provider.json':
+ ensure => absent;
+
'/srv/leap/webapp/public/ca.crt':
ensure => link,
require => Vcsrepo['/srv/leap/webapp'],
- target => '/usr/local/share/ca-certificates/leap_api.crt';
+ target => "${x509::variables::local_CAs}/${site_config::params::ca_name}.crt";
"/srv/leap/webapp/public/${api_version}":
- ensure => directory,
+ 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,
+ 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,
@@ -106,25 +126,24 @@ class site_webapp {
}
try::file {
- '/srv/leap/webapp/public/favicon.ico':
- ensure => 'link',
- require => Vcsrepo['/srv/leap/webapp'],
- target => $webapp['favicon'];
-
- '/srv/leap/webapp/app/assets/stylesheets/tail.scss':
- ensure => 'link',
- require => Vcsrepo['/srv/leap/webapp'],
- target => $webapp['tail_scss'];
-
- '/srv/leap/webapp/app/assets/stylesheets/head.scss':
- ensure => 'link',
+ '/srv/leap/webapp/config/customization':
+ ensure => directory,
+ recurse => true,
+ purge => true,
+ force => true,
+ owner => leap-webapp,
+ group => leap-webapp,
+ mode => 'u=rwX,go=rX',
require => Vcsrepo['/srv/leap/webapp'],
- target => $webapp['head_scss'];
+ notify => Exec['compile_assets'],
+ source => $webapp['customization_dir'];
+ }
- '/srv/leap/webapp/public/img':
- ensure => 'link',
+ git::changes {
+ 'public/favicon.ico':
+ cwd => '/srv/leap/webapp',
require => Vcsrepo['/srv/leap/webapp'],
- target => $webapp['img_dir'];
+ user => 'leap-webapp';
}
file {
@@ -138,5 +157,5 @@ class site_webapp {
}
include site_shorewall::webapp
-
+ include site_check_mk::agent::webapp
}
diff --git a/puppet/modules/site_webapp/templates/config.yml.erb b/puppet/modules/site_webapp/templates/config.yml.erb
index df562cd9..98f8564e 100644
--- a/puppet/modules/site_webapp/templates/config.yml.erb
+++ b/puppet/modules/site_webapp/templates/config.yml.erb
@@ -1,9 +1,10 @@
<%- cert_options = @webapp['client_certificates'] -%>
production:
- admins: [admin]
+ admins: <%= @webapp['admins'].inspect %>
domain: <%= @provider_domain %>
- client_ca_key: <%= scope.lookupvar('site_webapp::client_ca::key_path') %>
- client_ca_cert: <%= scope.lookupvar('site_webapp::client_ca::cert_path') %>
+ force_ssl: <%= @webapp['secure'] %>
+ client_ca_key: <%= scope.lookupvar('x509::variables::keys') %>/<%= scope.lookupvar('site_config::params::client_ca_name') %>.key
+ client_ca_cert: <%= scope.lookupvar('x509::variables::local_CAs') %>/<%= scope.lookupvar('site_config::params::client_ca_name') %>.crt
secret_token: "<%= @secret_token %>"
client_cert_lifespan: <%= cert_options['life_span'].to_i %>
client_cert_bit_size: <%= cert_options['bit_size'].to_i %>
@@ -13,3 +14,4 @@ production:
allow_anonymous_certs: <%= @webapp['allow_anonymous_certs'].inspect %>
limited_cert_prefix: "<%= cert_options['limited_prefix'] %>"
unlimited_cert_prefix: "<%= cert_options['unlimited_prefix'] %>"
+ minimum_client_version: "<%= @webapp['client_version']['min'] %>"
diff --git a/puppet/modules/site_webapp/templates/couchdb.yml.admin.erb b/puppet/modules/site_webapp/templates/couchdb.yml.admin.erb
deleted file mode 100644
index a0921add..00000000
--- a/puppet/modules/site_webapp/templates/couchdb.yml.admin.erb
+++ /dev/null
@@ -1,9 +0,0 @@
-production:
- prefix: ""
- protocol: 'http'
- host: <%= @couchdb_host %>
- port: <%= @couchdb_port %>
- auto_update_design_doc: false
- username: <%= @couchdb_admin_user %>
- password: <%= @couchdb_admin_password %>
-
diff --git a/puppet/modules/site_webapp/templates/haproxy_couchdb.cfg.erb b/puppet/modules/site_webapp/templates/haproxy_couchdb.cfg.erb
index f08161ee..1fa01b96 100644
--- a/puppet/modules/site_webapp/templates/haproxy_couchdb.cfg.erb
+++ b/puppet/modules/site_webapp/templates/haproxy_couchdb.cfg.erb
@@ -1,16 +1,23 @@
listen bigcouch-in
- mode http
+ mode http
balance roundrobin
- option httplog
- option dontlognull
- option httpchk GET /
- option http-server-close
-
+ option httplog
+ option dontlognull
+ option httpchk GET / # health check using simple get to root
+ option http-server-close # use client keep-alive, but close server connection.
+ option allbackups # balance among all backups, not just one.
+
bind localhost:4096
-<% for port in @local_ports -%>
- server couchdb_<%=port%> localhost:<%=port%> check inter 3000 fastinter 1000 downinter 1000 rise 2 fall 1
-<% end -%>
+ default-server inter 3000 fastinter 1000 downinter 1000 rise 2 fall 1
+
+<%- if @haproxy['servers'] -%>
+<%- @haproxy['servers'].sort.each do |name,server| -%>
+<%- backup = server['backup'] ? 'backup' : '' -%>
+ # <%=name%>
+ server couchdb_<%=server['port']%> <%=server['host']%>:<%=server['port']%> <%=backup%> weight <%=server['weight']%> check
+<%- end -%>
+<%- end -%>
diff --git a/puppet/modules/soledad/manifests/common.pp b/puppet/modules/soledad/manifests/common.pp
new file mode 100644
index 00000000..8a1d664a
--- /dev/null
+++ b/puppet/modules/soledad/manifests/common.pp
@@ -0,0 +1,10 @@
+class soledad::common {
+
+ include soledad
+
+ package { 'soledad-common':
+ ensure => latest,
+ require => User['soledad']
+ }
+
+}
diff --git a/puppet/modules/soledad/manifests/init.pp b/puppet/modules/soledad/manifests/init.pp
new file mode 100644
index 00000000..7cf0b729
--- /dev/null
+++ b/puppet/modules/soledad/manifests/init.pp
@@ -0,0 +1,29 @@
+class soledad {
+
+ group { 'soledad':
+ ensure => present,
+ allowdupe => false;
+ }
+
+ user { 'soledad':
+ ensure => present,
+ allowdupe => false,
+ gid => 'soledad',
+ home => '/srv/leap/soledad',
+ require => Group['soledad'];
+ }
+
+ file {
+ '/srv/leap/soledad':
+ ensure => directory,
+ owner => 'soledad',
+ group => 'soledad',
+ require => User['soledad'];
+
+ '/var/lib/soledad':
+ ensure => directory,
+ owner => 'soledad',
+ group => 'soledad',
+ require => User['soledad'];
+ }
+}
diff --git a/puppet/modules/soledad/manifests/server.pp b/puppet/modules/soledad/manifests/server.pp
new file mode 100644
index 00000000..394e6032
--- /dev/null
+++ b/puppet/modules/soledad/manifests/server.pp
@@ -0,0 +1,63 @@
+class soledad::server {
+ tag 'leap_service'
+ include soledad
+ include site_apt::preferences::twisted
+
+ $soledad = hiera('soledad')
+ $couchdb_user = $soledad['couchdb_soledad_user']['username']
+ $couchdb_password = $soledad['couchdb_soledad_user']['password']
+
+ $couchdb_host = 'localhost'
+ $couchdb_port = '5984'
+
+ $soledad_port = $soledad['port']
+
+ include site_config::x509::cert
+ include site_config::x509::key
+ include site_config::x509::ca
+
+ #
+ # SOLEDAD CONFIG
+ #
+
+ file { '/etc/leap/soledad-server.conf':
+ content => template('soledad/soledad-server.conf.erb'),
+ owner => 'soledad',
+ group => 'soledad',
+ mode => '0600',
+ notify => Service['soledad-server'],
+ require => Class['soledad'];
+ }
+
+ package { 'soledad-server':
+ ensure => latest,
+ require => [
+ Class['site_apt::preferences::twisted'],
+ Class['site_apt::leap_repo'] ];
+ }
+
+ file { '/etc/default/soledad':
+ content => template('soledad/default-soledad.erb'),
+ owner => 'soledad',
+ group => 'soledad',
+ mode => '0600',
+ notify => Service['soledad-server'],
+ require => Class['soledad'];
+ }
+
+ service { 'soledad-server':
+ ensure => running,
+ enable => true,
+ hasstatus => true,
+ hasrestart => true,
+ require => Class['soledad'],
+ subscribe => [
+ Package['soledad-server'],
+ Class['Site_config::X509::Key'],
+ Class['Site_config::X509::Cert'],
+ Class['Site_config::X509::Ca'] ];
+ }
+
+ include site_shorewall::soledad
+ include site_check_mk::agent::soledad
+}
diff --git a/puppet/modules/soledad/templates/default-soledad.erb b/puppet/modules/soledad/templates/default-soledad.erb
new file mode 100644
index 00000000..32504e38
--- /dev/null
+++ b/puppet/modules/soledad/templates/default-soledad.erb
@@ -0,0 +1,5 @@
+# this file is managed by puppet
+START=yes
+CERT_PATH=<%= scope.lookupvar('x509::variables::certs') %>/<%= scope.lookupvar('site_config::params::cert_name') %>.crt
+PRIVKEY_PATH=<%= scope.lookupvar('x509::variables::keys') %>/<%= scope.lookupvar('site_config::params::cert_name') %>.key
+HTTPS_PORT=<%=@soledad_port%>
diff --git a/puppet/modules/soledad/templates/soledad-server.conf.erb b/puppet/modules/soledad/templates/soledad-server.conf.erb
new file mode 100644
index 00000000..47d1f6e4
--- /dev/null
+++ b/puppet/modules/soledad/templates/soledad-server.conf.erb
@@ -0,0 +1,3 @@
+[soledad-server]
+couch_url = http://<%= @couchdb_user %>:<%= @couchdb_password %>@<%= @couchdb_host %>:<%= @couchdb_port %>
+
diff --git a/puppet/modules/squid_deb_proxy b/puppet/modules/squid_deb_proxy
new file mode 160000
+Subproject e796aac43aa9781069e167459253d040504c209
diff --git a/puppet/modules/sshd b/puppet/modules/sshd
-Subproject bd2e283ab59430a7b3194804f1c8da7a9b58f8f
+Subproject 1eabfe1b590f6663c2558f949408a08fc5f58fa
diff --git a/puppet/modules/stdlib b/puppet/modules/stdlib
-Subproject 66e0fa8f1bc5062e9d753598ad17602c378a299
+Subproject 71cb0f4c2c3bf95f62c9f189f5cef155b09a968
diff --git a/puppet/modules/stunnel b/puppet/modules/stunnel
-Subproject fc1589a5f09d80f58d730d4e1f6a8058483f61f
+Subproject ec49fd93c2469bc5c13f7e6a7d25468613e1b84
diff --git a/puppet/modules/sysctl b/puppet/modules/sysctl
new file mode 160000
+Subproject 975852b7acc1125b4cd9d4d490b9abd8d31217e
diff --git a/puppet/modules/tapicero/files/tapicero.init b/puppet/modules/tapicero/files/tapicero.init
new file mode 100755
index 00000000..7a9af45f
--- /dev/null
+++ b/puppet/modules/tapicero/files/tapicero.init
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+### BEGIN INIT INFO
+# Provides: tapicero
+# Required-Start: $remote_fs $syslog
+# Required-Stop: $remote_fs $syslog
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: tapicero initscript
+# Description: Controls tapicero daemon
+### END INIT INFO
+
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+BUNDLER=/usr/bin/bundle
+NAME=tapicero
+HOME="/srv/leap"
+DAEMON="${HOME}/${NAME}/bin/${NAME}"
+BUNDLE_GEMFILE="${HOME}/${NAME}/Gemfile"
+
+export BUNDLE_GEMFILE
+
+# exit if the daemon doesn't exist
+[ -x "$DAEMON" ] || exit 0
+
+. /lib/init/vars.sh
+. /lib/lsb/init-functions
+
+if [ "$VERBOSE" != no ]; then
+ OPTIONS="--verbose"
+else
+ OPTIONS=""
+fi
+
+case "$1" in
+ start)
+ $BUNDLER exec $DAEMON start $OPTIONS
+ exit $?
+ ;;
+ stop)
+ $BUNDLER exec $DAEMON stop $OPTIONS
+ exit $?
+ ;;
+ restart)
+ $BUNDLER exec $DAEMON restart $OPTIONS
+ exit $?
+ ;;
+ reload)
+ $BUNDLER exec $DAEMON reload $OPTIONS
+ exit $?
+ ;;
+ status)
+ $BUNDLER exec $DAEMON status $OPTIONS
+ exit $?
+ ;;
+ *)
+ echo "Usage: /etc/init.d/$NAME {start|stop|reload|restart|status}"
+ exit 1
+esac
+
+exit 0
diff --git a/puppet/modules/tapicero/manifests/init.pp b/puppet/modules/tapicero/manifests/init.pp
new file mode 100644
index 00000000..743e8a84
--- /dev/null
+++ b/puppet/modules/tapicero/manifests/init.pp
@@ -0,0 +1,123 @@
+class tapicero {
+ tag 'leap_service'
+
+ $couchdb = hiera('couch')
+ $couchdb_port = $couchdb['port']
+
+ $couchdb_users = $couchdb['users']
+
+ $couchdb_admin_user = $couchdb_users['admin']['username']
+ $couchdb_admin_password = $couchdb_users['admin']['password']
+
+ $couchdb_soledad_user = $couchdb_users['soledad']['username']
+ $couchdb_leap_mx_user = $couchdb_users['leap_mx']['username']
+
+
+ Class['site_config::default'] -> Class['tapicero']
+
+ include site_config::ruby::dev
+
+ #
+ # USER AND GROUP
+ #
+
+ group { 'tapicero':
+ ensure => present,
+ allowdupe => false;
+ }
+
+ user { 'tapicero':
+ ensure => present,
+ allowdupe => false,
+ gid => 'tapicero',
+ home => '/srv/leap/tapicero',
+ require => Group['tapicero'];
+ }
+
+ #
+ # TAPICERO FILES
+ #
+
+ file {
+
+ ##
+ ## TAPICERO DIRECTORIES
+ ##
+
+ '/srv/leap/tapicero':
+ ensure => directory,
+ owner => 'tapicero',
+ group => 'tapicero',
+ require => User['tapicero'];
+
+ '/var/lib/leap/tapicero':
+ ensure => directory,
+ owner => 'tapicero',
+ group => 'tapicero',
+ require => User['tapicero'];
+
+ ##
+ ## TAPICERO CONFIG
+ ##
+
+ '/etc/leap/tapicero.yaml':
+ content => template('tapicero/tapicero.yaml.erb'),
+ owner => 'tapicero',
+ group => 'tapicero',
+ mode => '0600',
+ notify => Service['tapicero'];
+
+ ##
+ ## TAPICERO INIT
+ ##
+
+ '/etc/init.d/tapicero':
+ source => 'puppet:///modules/tapicero/tapicero.init',
+ owner => root,
+ group => 0,
+ mode => '0755',
+ require => Vcsrepo['/srv/leap/tapicero'];
+ }
+
+ #
+ # TAPICERO CODE
+ #
+
+ vcsrepo { '/srv/leap/tapicero':
+ ensure => present,
+ force => true,
+ revision => 'origin/master',
+ provider => git,
+ source => 'https://leap.se/git/tapicero',
+ owner => 'tapicero',
+ group => 'tapicero',
+ require => [ User['tapicero'], Group['tapicero'] ],
+ notify => Exec['tapicero_bundler_update']
+ }
+
+ exec { 'tapicero_bundler_update':
+ cwd => '/srv/leap/tapicero',
+ command => '/bin/bash -c "/usr/bin/bundle check || /usr/bin/bundle install --path vendor/bundle --without test development"',
+ unless => '/usr/bin/bundle check',
+ user => 'tapicero',
+ timeout => 600,
+ require => [
+ Class['bundler::install'],
+ Vcsrepo['/srv/leap/tapicero'],
+ Class['site_config::ruby::dev'] ],
+ notify => Service['tapicero'];
+ }
+
+ #
+ # TAPICERO DAEMON
+ #
+
+ service { 'tapicero':
+ ensure => running,
+ enable => true,
+ hasstatus => true,
+ hasrestart => true,
+ require => File['/etc/init.d/tapicero'];
+ }
+
+}
diff --git a/puppet/modules/tapicero/templates/tapicero.yaml.erb b/puppet/modules/tapicero/templates/tapicero.yaml.erb
new file mode 100644
index 00000000..8e19b22f
--- /dev/null
+++ b/puppet/modules/tapicero/templates/tapicero.yaml.erb
@@ -0,0 +1,42 @@
+#
+# Default configuration options for Tapicero
+#
+
+# couch connection configuration
+connection:
+ protocol: "http"
+ host: "localhost"
+ port: <%= @couchdb_port %>
+ username: <%= @couchdb_admin_user %>
+ password: <%= @couchdb_admin_password %>
+ prefix : ""
+ suffix : ""
+
+# file to store the last processed user record in so we can resume after
+# a restart:
+seq_file: "/var/lib/leap/tapicero/tapicero.seq"
+
+# Configure log_file like this if you want to log to a file instead of syslog:
+# log_file: "/var/leap/log/tapicero.log"
+log_level: info
+
+# tapicero specific options
+options:
+ # prefix for per user databases:
+ db_prefix: "user-"
+
+ # security settings to be used for the per user databases
+ security:
+ admins:
+ names:
+ # We explicitly allow the admin user to access per user databases, even
+ # though admin access ignores per database security we just do this to be
+ # explicit about this
+ - <%= @couchdb_admin_user %>
+ roles: []
+ readers:
+ names:
+ - <%= @couchdb_soledad_user %>
+ - <%= @couchdb_leap_mx_user %>
+ roles: []
+
diff --git a/puppet/modules/tor b/puppet/modules/tor
-Subproject a780e84001177f10a86a7bf824589c0553f513a
+Subproject dcb6e748864e7dfd3c14f4f2aba4c9120f12b78
diff --git a/puppet/modules/try/manifests/file.pp b/puppet/modules/try/manifests/file.pp
index 47a8c269..cd1bb035 100644
--- a/puppet/modules/try/manifests/file.pp
+++ b/puppet/modules/try/manifests/file.pp
@@ -1,60 +1,112 @@
#
-# like built-in type "file", but gets gracefully ignored if the target does not exist or is undefined.
+# Works like the built-in type "file", but gets gracefully ignored if the target/source does not exist or is undefined.
#
-# /bin/true and /usr/bin/test are hardcoded to their paths in debian.
+# Also, if the source or target doesn't exist, and the destination is a git repo, then the file is restored from git.
+#
+# All executable paths are hardcoded to their paths in debian.
+#
+# known limitations:
+# * this is far too noisy
+# * $restore does not work for directories
+# * only file:// $source is supported
+# * $content is not supported, only $target or $source.
+# * does not auto-require all the parent directories like 'file' does
#
-
define try::file (
$ensure = undef,
$target = undef,
+ $source = undef,
+ $owner = undef,
+ $group = undef,
+ $recurse = undef,
+ $purge = undef,
+ $force = undef,
+ $mode = undef,
$restore = true) {
- if $target != undef {
- exec { "check_${name}":
- command => "/bin/true",
- onlyif => "/usr/bin/test -e '${target}'",
- loglevel => info;
+ # dummy exec to propagate requires:
+ # metaparameter 'require' will get triggered by this dummy exec
+ # so then we just need to depend on this to capture all requires.
+ # exec { $name: command => "/bin/true" }
+
+ exec {
+ "chmod_${name}":
+ command => "/bin/chmod -R ${mode} '${name}'",
+ onlyif => "/usr/bin/test $mode",
+ refreshonly => true,
+ loglevel => debug;
+ "chown_${name}":
+ command => "/bin/chown -R ${owner} '${name}'",
+ onlyif => "/usr/bin/test $owner",
+ refreshonly => true,
+ loglevel => debug;
+ "chgrp_${name}":
+ command => "/bin/chgrp -R ${group} '${name}'",
+ onlyif => "/usr/bin/test $group",
+ refreshonly => true,
+ loglevel => debug;
+ }
+
+ if $target {
+ exec { "symlink_${name}":
+ command => "/bin/ln -s ${target} ${name}",
+ onlyif => "/usr/bin/test -d '${target}'",
}
- file { "$name":
- ensure => $ensure,
- target => $target,
- require => $require ? {
- undef => Exec["check_${name}"],
- default => [ $require, Exec["check_${name}"] ]
- },
- loglevel => info;
+ } elsif $source {
+ if $ensure == 'directory' {
+ if $purge {
+ exec { "rsync_${name}":
+ command => "/usr/bin/rsync -r --delete '${source}/' '${name}'",
+ onlyif => "/usr/bin/test -d '${source}'",
+ unless => "/usr/bin/diff -rq '${source}' '${name}'",
+ notify => [Exec["chmod_${name}"], Exec["chown_${name}"], Exec["chgrp_${name}"]]
+ }
+ } else {
+ exec { "cp_r_${name}":
+ command => "/bin/cp -r '${source}' '${name}'",
+ onlyif => "/usr/bin/test -d '${source}'",
+ unless => "/usr/bin/diff -rq '${source}' '${name}'",
+ notify => [Exec["chmod_${name}"], Exec["chown_${name}"], Exec["chgrp_${name}"]]
+ }
+ }
+ } else {
+ exec { "cp_${name}":
+ command => "/bin/cp --remove-destination '${source}' '${name}'",
+ onlyif => "/usr/bin/test -e '${source}'",
+ unless => "/usr/bin/test ! -h '${name}' && /usr/bin/diff -q '${source}' '${name}'",
+ notify => [Exec["chmod_${name}"], Exec["chown_${name}"], Exec["chgrp_${name}"]]
+ }
}
}
#
- # if the target does not exist (or is undef), and the file happens to be in a git repo,
+ # if the target/source does not exist (or is undef), and the file happens to be in a git repo,
# then restore the file to its original state.
#
- if $target == undef or $restore {
+
+ if $target {
+ $target_or_source = $target
+ } else {
+ $target_or_source = $source
+ }
+
+ if ($target_or_source == undef) or $restore {
$file_basename = basename($name)
$file_dirname = dirname($name)
$command = "git rev-parse && unlink '${name}'; git checkout -- '${file_basename}' && chown --reference='${file_dirname}' '${name}'; true"
debug($command)
- if $target == undef {
+ if $target_or_source == undef {
exec { "restore_${name}":
command => $command,
cwd => $file_dirname,
- require => $require ? {
- undef => undef,
- default => [ $require ]
- },
loglevel => info;
}
} else {
exec { "restore_${name}":
- unless => "/usr/bin/test -e '${target}'",
+ unless => "/usr/bin/test -e '${target_or_source}'",
command => $command,
cwd => $file_dirname,
- require => $require ? {
- undef => undef,
- default => [ $require ]
- },
loglevel => info;
}
}
diff --git a/puppet/modules/vcsrepo b/puppet/modules/vcsrepo
-Subproject 4db1120c78763f5244dc6c9d2e0d064a6ef363e
+Subproject f92d09226cfddb0c7e5e342dd199d8ea05b497c