diff options
Diffstat (limited to 'puppet/modules/site_webapp')
-rw-r--r-- | puppet/modules/site_webapp/files/server-status.conf | 26 | ||||
-rw-r--r-- | puppet/modules/site_webapp/manifests/apache.pp | 28 | ||||
-rw-r--r-- | puppet/modules/site_webapp/manifests/common_vhost.pp | 18 | ||||
-rw-r--r-- | puppet/modules/site_webapp/manifests/couchdb.pp | 52 | ||||
-rw-r--r-- | puppet/modules/site_webapp/manifests/cron.pp | 37 | ||||
-rw-r--r-- | puppet/modules/site_webapp/manifests/hidden_service.pp | 52 | ||||
-rw-r--r-- | puppet/modules/site_webapp/manifests/init.pp | 179 | ||||
-rw-r--r-- | puppet/modules/site_webapp/templates/config.yml.erb | 36 | ||||
-rw-r--r-- | puppet/modules/site_webapp/templates/couchdb.admin.yml.erb | 9 | ||||
-rw-r--r-- | puppet/modules/site_webapp/templates/couchdb.yml.erb | 9 |
10 files changed, 446 insertions, 0 deletions
diff --git a/puppet/modules/site_webapp/files/server-status.conf b/puppet/modules/site_webapp/files/server-status.conf new file mode 100644 index 00000000..10b2d4ed --- /dev/null +++ b/puppet/modules/site_webapp/files/server-status.conf @@ -0,0 +1,26 @@ +# Keep track of extended status information for each request +ExtendedStatus On + +# Determine if mod_status displays the first 63 characters of a request or +# the last 63, assuming the request itself is greater than 63 chars. +# Default: Off +#SeeRequestTail On + +Listen 127.0.0.1:8162 + +<VirtualHost 127.0.0.1:8162> + +<Location /server-status> + SetHandler server-status + Require all granted + Allow from 127.0.0.1 +</Location> + +</VirtualHost> + + +<IfModule mod_proxy.c> + # Show Proxy LoadBalancer status in mod_status + ProxyStatus On +</IfModule> + diff --git a/puppet/modules/site_webapp/manifests/apache.pp b/puppet/modules/site_webapp/manifests/apache.pp new file mode 100644 index 00000000..80c7b29b --- /dev/null +++ b/puppet/modules/site_webapp/manifests/apache.pp @@ -0,0 +1,28 @@ +# configure apache and passenger to serve the webapp +class site_webapp::apache { + + $web_api = hiera('api') + $api_domain = $web_api['domain'] + $api_port = $web_api['port'] + + $web_domain = hiera('domain') + $domain_name = $web_domain['name'] + + $webapp = hiera('webapp') + $webapp_domain = $webapp['domain'] + + include site_apache::common + include apache::module::headers + include apache::module::alias + include apache::module::expires + include apache::module::removeip + include site_webapp::common_vhost + + class { 'passenger': use_munin => false } + + apache::vhost::file { + 'api': + content => template('site_apache/vhosts.d/api.conf.erb'); + } + +} diff --git a/puppet/modules/site_webapp/manifests/common_vhost.pp b/puppet/modules/site_webapp/manifests/common_vhost.pp new file mode 100644 index 00000000..c57aad57 --- /dev/null +++ b/puppet/modules/site_webapp/manifests/common_vhost.pp @@ -0,0 +1,18 @@ +class site_webapp::common_vhost { + # installs x509 cert + key and common config + # that both nagios + leap webapp use + + 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] + + apache::vhost::file { + 'common': + content => template('site_apache/vhosts.d/common.conf.erb') + } +} diff --git a/puppet/modules/site_webapp/manifests/couchdb.pp b/puppet/modules/site_webapp/manifests/couchdb.pp new file mode 100644 index 00000000..71450370 --- /dev/null +++ b/puppet/modules/site_webapp/manifests/couchdb.pp @@ -0,0 +1,52 @@ +class site_webapp::couchdb { + + $webapp = hiera('webapp') + # haproxy listener on port localhost:4096, see site_webapp::haproxy + $couchdb_host = 'localhost' + $couchdb_port = '4096' + $couchdb_webapp_user = $webapp['couchdb_webapp_user']['username'] + $couchdb_webapp_password = $webapp['couchdb_webapp_user']['password'] + $couchdb_admin_user = $webapp['couchdb_admin_user']['username'] + $couchdb_admin_password = $webapp['couchdb_admin_user']['password'] + + include x509::variables + + file { + '/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']; + + # couchdb.admin.yml is a symlink to prevent the vcsrepo resource + # from changing its user permissions every time. + '/srv/leap/webapp/config/couchdb.admin.yml': + ensure => 'link', + target => '/etc/leap/couchdb.admin.yml', + require => Vcsrepo['/srv/leap/webapp']; + + '/etc/leap/couchdb.admin.yml': + content => template('site_webapp/couchdb.admin.yml.erb'), + owner => 'root', + group => 'root', + mode => '0600', + require => File['/etc/leap']; + + '/srv/leap/webapp/log': + ensure => directory, + owner => 'leap-webapp', + group => 'leap-webapp', + mode => '0755', + require => Vcsrepo['/srv/leap/webapp']; + + '/srv/leap/webapp/log/production.log': + ensure => present, + owner => 'leap-webapp', + group => 'leap-webapp', + mode => '0666', + require => Vcsrepo['/srv/leap/webapp']; + } + + include site_stunnel +} diff --git a/puppet/modules/site_webapp/manifests/cron.pp b/puppet/modules/site_webapp/manifests/cron.pp new file mode 100644 index 00000000..70b9da04 --- /dev/null +++ b/puppet/modules/site_webapp/manifests/cron.pp @@ -0,0 +1,37 @@ +# setup webapp cronjobs +class site_webapp::cron { + + # cron tasks that need to be performed to cleanup the database + cron { + 'rotate_databases': + command => 'cd /srv/leap/webapp && bundle exec rake db:rotate', + environment => 'RAILS_ENV=production', + user => 'root', + hour => [0,6,12,18], + minute => 0; + + 'delete_tmp_databases': + command => 'cd /srv/leap/webapp && bundle exec rake db:deletetmp', + environment => 'RAILS_ENV=production', + user => 'root', + hour => 1, + minute => 1; + + # there is no longer a need to remove expired sessions, since the database + # will get destroyed. + 'remove_expired_sessions': + ensure => absent, + command => 'cd /srv/leap/webapp && bundle exec rake cleanup:sessions', + environment => 'RAILS_ENV=production', + user => 'leap-webapp', + hour => 2, + minute => 30; + + 'remove_expired_tokens': + command => 'cd /srv/leap/webapp && bundle exec rake cleanup:tokens', + environment => 'RAILS_ENV=production', + user => 'leap-webapp', + hour => 3, + minute => 0; + } +} diff --git a/puppet/modules/site_webapp/manifests/hidden_service.pp b/puppet/modules/site_webapp/manifests/hidden_service.pp new file mode 100644 index 00000000..72a2ce95 --- /dev/null +++ b/puppet/modules/site_webapp/manifests/hidden_service.pp @@ -0,0 +1,52 @@ +class site_webapp::hidden_service { + $tor = hiera('tor') + $hidden_service = $tor['hidden_service'] + $tor_domain = "${hidden_service['address']}.onion" + + include site_apache::common + include apache::module::headers + include apache::module::alias + include apache::module::expires + include apache::module::removeip + + include tor::daemon + tor::daemon::hidden_service { 'webapp': ports => [ '80 127.0.0.1:80'] } + + file { + '/var/lib/tor/webapp/': + ensure => directory, + owner => 'debian-tor', + group => 'debian-tor', + mode => '2700'; + + '/var/lib/tor/webapp/private_key': + ensure => present, + source => "/srv/leap/files/nodes/${::hostname}/tor.key", + owner => 'debian-tor', + group => 'debian-tor', + mode => '0600'; + + '/var/lib/tor/webapp/hostname': + ensure => present, + content => $tor_domain, + owner => 'debian-tor', + group => 'debian-tor', + mode => '0600'; + } + + # it is necessary to zero out the config of the status module + # because we are configuring our own version that is unavailable + # over the hidden service (see: #7456 and #7776) + apache::module { 'status': ensure => present, conf_content => ' ' } + # the access_compat module is required to enable Allow directives + apache::module { 'access_compat': ensure => present } + + apache::vhost::file { + 'hidden_service': + content => template('site_apache/vhosts.d/hidden_service.conf.erb'); + 'server_status': + vhost_source => 'modules/site_webapp/server-status.conf'; + } + + include site_shorewall::tor +} diff --git a/puppet/modules/site_webapp/manifests/init.pp b/puppet/modules/site_webapp/manifests/init.pp new file mode 100644 index 00000000..15925aba --- /dev/null +++ b/puppet/modules/site_webapp/manifests/init.pp @@ -0,0 +1,179 @@ +# configure webapp service +class site_webapp { + tag 'leap_service' + $definition_files = hiera('definition_files') + $provider = $definition_files['provider'] + $eip_service = $definition_files['eip_service'] + $soledad_service = $definition_files['soledad_service'] + $smtp_service = $definition_files['smtp_service'] + $node_domain = hiera('domain') + $provider_domain = $node_domain['full_suffix'] + $webapp = hiera('webapp') + $api_version = $webapp['api_version'] + $secret_token = $webapp['secret_token'] + $tor = hiera('tor', false) + $sources = hiera('sources') + + Class['site_config::default'] -> Class['site_webapp'] + + include site_config::ruby::dev + include site_webapp::apache + include site_webapp::couchdb + include site_haproxy + include site_webapp::cron + include site_config::default + include site_config::x509::cert + include site_config::x509::key + include site_config::x509::ca + include site_config::x509::client_ca::ca + include site_config::x509::client_ca::key + include site_nickserver + + # remove leftovers from previous installations on webapp nodes + include site_config::remove::webapp + + group { 'leap-webapp': + ensure => present, + allowdupe => false; + } + + user { 'leap-webapp': + ensure => present, + allowdupe => false, + gid => 'leap-webapp', + groups => 'ssl-cert', + home => '/srv/leap/webapp', + require => [ Group['leap-webapp'] ]; + } + + vcsrepo { '/srv/leap/webapp': + ensure => present, + force => true, + revision => $sources['webapp']['revision'], + provider => $sources['webapp']['type'], + source => $sources['webapp']['source'], + owner => 'leap-webapp', + group => 'leap-webapp', + require => [ User['leap-webapp'], Group['leap-webapp'] ], + notify => Exec['bundler_update'] + } + + exec { 'bundler_update': + cwd => '/srv/leap/webapp', + command => '/bin/bash -c "/usr/bin/bundle check --path vendor/bundle || /usr/bin/bundle install --path vendor/bundle --without test development debug"', + unless => '/usr/bin/bundle check --path vendor/bundle', + user => 'leap-webapp', + timeout => 600, + 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 "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/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'; + + '/srv/leap/webapp/public/ca.crt': + ensure => link, + require => Vcsrepo['/srv/leap/webapp'], + target => "${x509::variables::local_CAs}/${site_config::params::ca_name}.crt"; + + "/srv/leap/webapp/public/${api_version}": + ensure => directory, + require => Vcsrepo['/srv/leap/webapp'], + owner => leap-webapp, group => leap-webapp, mode => '0755'; + + "/srv/leap/webapp/public/${api_version}/config/": + ensure => directory, + require => Vcsrepo['/srv/leap/webapp'], + owner => leap-webapp, group => leap-webapp, mode => '0755'; + + "/srv/leap/webapp/public/${api_version}/config/eip-service.json": + content => $eip_service, + require => Vcsrepo['/srv/leap/webapp'], + owner => leap-webapp, group => leap-webapp, mode => '0644'; + + "/srv/leap/webapp/public/${api_version}/config/soledad-service.json": + content => $soledad_service, + require => Vcsrepo['/srv/leap/webapp'], + owner => leap-webapp, group => leap-webapp, mode => '0644'; + + "/srv/leap/webapp/public/${api_version}/config/smtp-service.json": + content => $smtp_service, + require => Vcsrepo['/srv/leap/webapp'], + owner => leap-webapp, group => leap-webapp, mode => '0644'; + } + + try::file { + '/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'], + notify => Exec['compile_assets'], + source => $webapp['customization_dir']; + } + + git::changes { + 'public/favicon.ico': + cwd => '/srv/leap/webapp', + require => Vcsrepo['/srv/leap/webapp'], + user => 'leap-webapp'; + } + + file { + '/srv/leap/webapp/config/config.yml': + content => template('site_webapp/config.yml.erb'), + owner => leap-webapp, + group => leap-webapp, + mode => '0600', + require => Vcsrepo['/srv/leap/webapp'], + notify => Service['apache']; + } + + if $tor { + $hidden_service = $tor['hidden_service'] + if $hidden_service['active'] { + include site_webapp::hidden_service + } + } + + + # needed for the soledad-sync check which is run on the + # webapp node + include soledad::client + + leap::logfile { '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 new file mode 100644 index 00000000..dd55d3e9 --- /dev/null +++ b/puppet/modules/site_webapp/templates/config.yml.erb @@ -0,0 +1,36 @@ +<% +cert_options = @webapp['client_certificates'] +production = { + "admins" => @webapp['admins'], + "default_locale" => @webapp['default_locale'], + "available_locales" => @webapp['locales'], + "domain" => @provider_domain, + "force_ssl" => @webapp['secure'], + "client_ca_key" => "%s/%s.key" % [scope.lookupvar('x509::variables::keys'), scope.lookupvar('site_config::params::client_ca_name')], + "client_ca_cert" => "%s/%s.crt" % [scope.lookupvar('x509::variables::local_CAs'), scope.lookupvar('site_config::params::client_ca_name')], + "secret_token" => @secret_token, + "client_cert_lifespan" => cert_options['life_span'], + "client_cert_bit_size" => cert_options['bit_size'].to_i, + "client_cert_hash" => cert_options['digest'], + "allow_limited_certs" => @webapp['allow_limited_certs'], + "allow_unlimited_certs" => @webapp['allow_unlimited_certs'], + "allow_anonymous_certs" => @webapp['allow_anonymous_certs'], + "limited_cert_prefix" => cert_options['limited_prefix'], + "unlimited_cert_prefix" => cert_options['unlimited_prefix'], + "minimum_client_version" => @webapp['client_version']['min'], + "default_service_level" => @webapp['default_service_level'], + "service_levels" => @webapp['service_levels'], + "allow_registration" => @webapp['allow_registration'], + "handle_blacklist" => @webapp['forbidden_usernames'], + "invite_required" => @webapp['invite_required'], + "api_tokens" => @webapp['api_tokens'] +} + +if @webapp['engines'] && @webapp['engines'].any? + production["engines"] = @webapp['engines'] +end +-%> +# +# This file is generated by puppet. This file inherits from defaults.yml. +# +<%= scope.function_sorted_yaml([{"production" => production}]) %> diff --git a/puppet/modules/site_webapp/templates/couchdb.admin.yml.erb b/puppet/modules/site_webapp/templates/couchdb.admin.yml.erb new file mode 100644 index 00000000..a0921add --- /dev/null +++ b/puppet/modules/site_webapp/templates/couchdb.admin.yml.erb @@ -0,0 +1,9 @@ +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/couchdb.yml.erb b/puppet/modules/site_webapp/templates/couchdb.yml.erb new file mode 100644 index 00000000..2bef0af5 --- /dev/null +++ b/puppet/modules/site_webapp/templates/couchdb.yml.erb @@ -0,0 +1,9 @@ +production: + prefix: "" + protocol: 'http' + host: <%= @couchdb_host %> + port: <%= @couchdb_port %> + auto_update_design_doc: false + username: <%= @couchdb_webapp_user %> + password: <%= @couchdb_webapp_password %> + |