diff options
19 files changed, 239 insertions, 81 deletions
| diff --git a/Vagrantfile b/Vagrantfile index c9c68284..ba5451aa 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -9,6 +9,11 @@ Vagrant.configure("2") do |vagrant_config|      config.vm.box = "LEAP/wheezy"      #config.vm.network :private_network, ip: "10.5.5.102" + +    # forward leap_web ports +    config.vm.network "forwarded_port", guest: 80,  host:8080 +    config.vm.network "forwarded_port", guest: 443, host:4443 +      config.vm.provider "virtualbox" do |v|        v.memory = 1024        v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] diff --git a/lib/leap_cli/commands/compile.rb b/lib/leap_cli/commands/compile.rb index 8f6c7769..c388e5c3 100644 --- a/lib/leap_cli/commands/compile.rb +++ b/lib/leap_cli/commands/compile.rb @@ -265,56 +265,86 @@ remove this directory if you don't use it.      # serial is any number less than 2^32 (4294967296)      #      def compile_zone_file -      provider = manager.env('default').provider +      provider   = manager.env('default').provider        hosts_seen = {} -      f = $stdout -      f.puts ZONE_HEADER % {:domain => provider.domain, :ns => provider.domain, :contact => provider.contacts.default.first.sub('@','.')} -      max_width = manager.nodes.values.inject(0) {|max, node| [max, relative_hostname(node.domain.full, provider).length].max } -      put_line = lambda do |host, line| -        host = '@' if host == '' -        f.puts("%-#{max_width}s %s" % [host, line]) -      end +      lines      = [] + +      # +      # header +      # +      lines << ZONE_HEADER % {:domain => provider.domain, :ns => provider.domain, :contact => provider.contacts.default.first.sub('@','.')} -      f.puts ORIGIN_HEADER +      # +      # common records +      # +      lines << ORIGIN_HEADER        # 'A' records for primary domain        manager.nodes[:environment => '!local'].each_node do |node|          if node.dns['aliases'] && node.dns.aliases.include?(provider.domain) -          put_line.call "", "IN A      #{node.ip_address}" +          lines << ["@", "IN A      #{node.ip_address}"]          end        end -        # NS records        if provider['dns'] && provider.dns['nameservers']          provider.dns.nameservers.each do |ns| -          put_line.call "", "IN NS #{ns}." +          lines << ["@", "IN NS #{ns}."]          end        end -      # all other records +      # environment records        manager.environment_names.each do |env|          next if env == 'local'          nodes = manager.nodes[:environment => env]          next unless nodes.any? -        f.puts ENV_HEADER % (env.nil? ? 'default' : env) +        spf = nil +        lines << ENV_HEADER % (env.nil? ? 'default' : env)          nodes.each_node do |node|            if node.dns.public -            hostname = relative_hostname(node.domain.full, provider) -            put_line.call relative_hostname(node.domain.full, provider), "IN A      #{node.ip_address}" +            lines << [relative_hostname(node.domain.full, provider), "IN A      #{node.ip_address}"]            end            if node.dns['aliases']              node.dns.aliases.each do |host_alias|                if host_alias != node.domain.full && host_alias != provider.domain -                put_line.call relative_hostname(host_alias, provider), "IN A      #{node.ip_address}" +                lines << [relative_hostname(host_alias, provider), "IN A      #{node.ip_address}"]                end              end            end            if node.services.include? 'mx' -            put_line.call relative_hostname(node.domain.full_suffix, provider), "IN MX 10  #{relative_hostname(node.domain.full, provider)}" +            mx_domain = relative_hostname(node.domain.full_suffix, provider) +            lines << [mx_domain, "IN MX 10  #{relative_hostname(node.domain.full, provider)}"] +            spf ||= [mx_domain, spf_record(node)]            end          end +        lines << spf if spf +      end + +      # print the lines +      max_width = lines.inject(0) {|max, line| line.is_a?(Array) ? [max, line[0].length].max : max} +      lines.each do |host, line| +        if line.nil? +          puts(host) +        else +          host = '@' if host == '' +          puts("%-#{max_width}s %s" % [host, line]) +        end        end      end +    # +    # allow mail from any mx node, plus the webapp nodes. +    # +    # TODO: ipv6 +    # +    def spf_record(node) +      ips = node.nodes_like_me['services' => 'webapp'].values.collect {|n| +        "ip4:" + n.ip_address +      } +      # TXT strings may not be longer than 255 characters, although +      # you can chain multiple strings together. +      strings = "v=spf1 MX #{ips.join(' ')} -all".scan(/.{1,255}/).join('" "') +      %(IN TXT    "#{strings}") +    end +      ENV_HEADER = %[  ;;  ;; ENVIRONMENT %s diff --git a/puppet/modules/site_apache/manifests/common.pp b/puppet/modules/site_apache/manifests/common.pp index 2b83ffa5..64beb231 100644 --- a/puppet/modules/site_apache/manifests/common.pp +++ b/puppet/modules/site_apache/manifests/common.pp @@ -1,27 +1,8 @@  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') -  } - -  apache::config::include{ 'ssl_common.inc': } +  include site_apache::common::tls  } diff --git a/puppet/modules/site_apache/manifests/common/tls.pp b/puppet/modules/site_apache/manifests/common/tls.pp new file mode 100644 index 00000000..040868bf --- /dev/null +++ b/puppet/modules/site_apache/manifests/common/tls.pp @@ -0,0 +1,6 @@ +class site_apache::common::tls { +  # class to setup common SSL configurations + +  apache::config::include{ 'ssl_common.inc': } + +} diff --git a/puppet/modules/site_config/manifests/remove_files.pp b/puppet/modules/site_config/manifests/remove_files.pp index e2ab3c2e..07487d6a 100644 --- a/puppet/modules/site_config/manifests/remove_files.pp +++ b/puppet/modules/site_config/manifests/remove_files.pp @@ -12,6 +12,16 @@  class site_config::remove_files {    # +  # Platform 0.8 removals +  # + +  tidy { +    '/etc/apache/sites-enabled/leap_webapp.conf': +      notify => Service['apache']; +  } + + +  #    # Platform 0.7 removals    # @@ -23,20 +33,22 @@ class site_config::remove_files {      '/etc/logrotate.d/mx':;      '/etc/logrotate.d/stunnel':;      '/var/log/stunnel4/stunnel.log':; -    '/etc/apache/sites-enabled/leap_webapp.conf': -      notify => Service['apache'];      'leap_mx':        path => '/var/log/',        recurse => true,        matches => 'leap_mx*'; -    'leap_mx_rotate': -      path => '/var/log/leap/', -      recurse => true, -      matches => [ 'mx.log.[0-9]', 'mx.log.[0-9]?', 'mx.log.[6-9]?gz'];      '/srv/leap/webapp/public/provider.json':;      '/srv/leap/couchdb/designs/tmp_users':        recurse => true,        rmdirs => true; +    '/etc/leap/soledad-server.conf':; +  } + +  if member($::services, 'webapp') { +    tidy { +      '/etc/apache/sites-enabled/leap_webapp.conf': +        notify => Service['apache']; +    }    }    # leax-mx logged to /var/log/leap_mx.log in the past diff --git a/puppet/modules/site_couchdb/files/designs/invite_codes/InviteCode.json b/puppet/modules/site_couchdb/files/designs/invite_codes/InviteCode.json new file mode 100644 index 00000000..006c1ea1 --- /dev/null +++ b/puppet/modules/site_couchdb/files/designs/invite_codes/InviteCode.json @@ -0,0 +1,22 @@ +{ +   "_id": "_design/InviteCode", +   "language": "javascript", +   "views": { +       "by__id": { +           "map": "                function(doc) {\n                  if ((doc['type'] == 'InviteCode') && (doc['_id'] != null)) {\n                    emit(doc['_id'], 1);\n                  }\n                }\n", +           "reduce": "_sum" +       }, +       "by_invite_code": { +           "map": "                function(doc) {\n                  if ((doc['type'] == 'InviteCode') && (doc['invite_code'] != null)) {\n                    emit(doc['invite_code'], 1);\n                  }\n                }\n", +           "reduce": "_sum" +       }, +       "by_invite_count": { +           "map": "                function(doc) {\n                  if ((doc['type'] == 'InviteCode') && (doc['invite_count'] != null)) {\n                    emit(doc['invite_count'], 1);\n                  }\n                }\n", +           "reduce": "_sum" +       }, +       "all": { +           "map": "                function(doc) {\n                  if (doc['type'] == 'InviteCode') {\n                    emit(doc._id, null);\n                  }\n                }\n" +       } +   }, +   "couchrest-hash": "83fb8f504520b4a9c7ddbb7928cd0ce3" +}
\ No newline at end of file diff --git a/puppet/modules/site_couchdb/manifests/create_dbs.pp b/puppet/modules/site_couchdb/manifests/create_dbs.pp index eea4bbf5..a2d1c655 100644 --- a/puppet/modules/site_couchdb/manifests/create_dbs.pp +++ b/puppet/modules/site_couchdb/manifests/create_dbs.pp @@ -90,4 +90,13 @@ class site_couchdb::create_dbs {      members => "{ \"names\": [\"${site_couchdb::couchdb_webapp_user}\"], \"roles\": [\"replication\"] }",      require => Couchdb::Query::Setup['localhost']    } + +  ## invite_codes db +  ## store invite codes for new signups +  ## r/w: webapp +  couchdb::create_db { 'invite_codes': +    members => "{ \"names\": [\"${site_couchdb::couchdb_webapp_user}\"], \"roles\": [\"replication\"] }", +    require => Couchdb::Query::Setup['localhost'] +  } +  } diff --git a/puppet/modules/site_couchdb/manifests/designs.pp b/puppet/modules/site_couchdb/manifests/designs.pp index 1ab1c6a1..e5fd94c6 100644 --- a/puppet/modules/site_couchdb/manifests/designs.pp +++ b/puppet/modules/site_couchdb/manifests/designs.pp @@ -12,12 +12,13 @@ class site_couchdb::designs {    }    site_couchdb::upload_design { -    'customers':   design => 'customers/Customer.json'; -    'identities':  design => 'identities/Identity.json'; -    'tickets':     design => 'tickets/Ticket.json'; -    'messages':    design => 'messages/Message.json'; -    'users':       design => 'users/User.json'; -    'tmp_users':   design => 'users/User.json'; +    'customers':    design => 'customers/Customer.json'; +    'identities':   design => 'identities/Identity.json'; +    'tickets':      design => 'tickets/Ticket.json'; +    'messages':     design => 'messages/Message.json'; +    'users':        design => 'users/User.json'; +    'tmp_users':    design => 'users/User.json'; +    'invite_codes': design => 'invite_codes/InviteCode.json';      'shared_docs':        db => 'shared',        design => 'shared/docs.json'; diff --git a/puppet/modules/site_couchdb/manifests/setup.pp b/puppet/modules/site_couchdb/manifests/setup.pp index 69bd1c6a..fef48505 100644 --- a/puppet/modules/site_couchdb/manifests/setup.pp +++ b/puppet/modules/site_couchdb/manifests/setup.pp @@ -12,27 +12,40 @@ class site_couchdb::setup {    $user = $site_couchdb::couchdb_admin_user -  # /etc/couchdb/couchdb-admin.netrc is deployed by couchdb::query::setup -  # we symlink to couchdb.netrc for puppet commands. -  # 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) +  # setup /etc/couchdb/couchdb-admin.netrc for couchdb admin access +  couchdb::query::setup { 'localhost': +    user => $user, +    pw   => $site_couchdb::couchdb_admin_pw +  } + +  # We symlink /etc/couchdb/couchdb-admin.netrc to /etc/couchdb/couchdb.netrc +  # for puppet commands, and to to /root/.netrc for couchdb_scripts +  # (eg. backup) and to makes life easier for the admin on the command line +  # (i.e. using curl/wget without passing credentials)    file {      '/etc/couchdb/couchdb.netrc':        ensure  => link,        target  => "/etc/couchdb/couchdb-${user}.netrc"; -      '/root/.netrc':        ensure  => link,        target  => '/etc/couchdb/couchdb.netrc'; +  } -    '/srv/leap/couchdb': -      ensure => directory +  # setup /etc/couchdb/couchdb-soledad-admin.netrc file for couchdb admin +  # access, accessible only for the soledad-admin user to create soledad +  # userdbs +  file { '/etc/couchdb/couchdb-soledad-admin.netrc': +    content => "machine localhost login ${user} password ${site_couchdb::couchdb_admin_pw}", +    mode    => '0400', +    owner   => 'soledad-admin', +    group   => 'root', +    require => [ Package['couchdb'], User['soledad-admin'] ];    } -  couchdb::query::setup { 'localhost': -    user  => $user, -    pw    => $site_couchdb::couchdb_admin_pw, +  # Checkout couchdb_scripts repo +  file { +    '/srv/leap/couchdb': +      ensure => directory    }    vcsrepo { '/srv/leap/couchdb/scripts': diff --git a/puppet/modules/site_nagios/manifests/server.pp b/puppet/modules/site_nagios/manifests/server.pp index cb6c8d95..60a471b7 100644 --- a/puppet/modules/site_nagios/manifests/server.pp +++ b/puppet/modules/site_nagios/manifests/server.pp @@ -32,6 +32,7 @@ class site_nagios::server inherits nagios::base {    }    include site_apache::common +  include site_webapp::common_vhost    include site_apache::module::headers    File ['nagios_htpasswd'] { diff --git a/puppet/modules/site_static/manifests/init.pp b/puppet/modules/site_static/manifests/init.pp index 1efc510b..f69ffba7 100644 --- a/puppet/modules/site_static/manifests/init.pp +++ b/puppet/modules/site_static/manifests/init.pp @@ -9,6 +9,7 @@ class site_static {    $domains       = $static['domains']    $formats       = $static['formats']    $bootstrap     = $static['bootstrap_files'] +  $tor           = hiera('tor', false)    if $bootstrap['enabled'] {      $bootstrap_domain  = $bootstrap['domain'] @@ -27,14 +28,11 @@ class site_static {      }    } -  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::config::include{ 'ssl_common.inc': } - +  include site_apache::common    include site_config::ruby::dev    if (member($formats, 'rack')) { @@ -57,6 +55,13 @@ class site_static {    create_resources(site_static::domain, $domains) +  if $tor { +    $hidden_service = $tor['hidden_service'] +    if $hidden_service['active'] { +      include site_webapp::hidden_service +    } +  } +    include site_shorewall::defaults    include site_shorewall::service::http    include site_shorewall::service::https 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..84cb9ae0 --- /dev/null +++ b/puppet/modules/site_webapp/files/server-status.conf @@ -0,0 +1,28 @@ +# 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 +NameVirtualHost 127.0.0.1:8162 + +<VirtualHost 127.0.0.1:8162> + +<Location /server-status> +    SetHandler server-status +    Order deny,allow +    Deny from all +    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 index 93e172a0..ddd04a91 100644 --- a/puppet/modules/site_webapp/manifests/apache.pp +++ b/puppet/modules/site_webapp/manifests/apache.pp @@ -15,12 +15,13 @@ class site_webapp::apache {    include site_apache::module::alias    include site_apache::module::expires    include site_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') +      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/hidden_service.pp b/puppet/modules/site_webapp/manifests/hidden_service.pp index 16b6e2e7..99a756ca 100644 --- a/puppet/modules/site_webapp/manifests/hidden_service.pp +++ b/puppet/modules/site_webapp/manifests/hidden_service.pp @@ -32,12 +32,18 @@ class site_webapp::hidden_service {        owner   => 'debian-tor',        group   => 'debian-tor',        mode    => '0600'; + +    '/etc/apache2/mods-enabled/status.conf': +      ensure => absent, +      notify => Service['apache'];    }    apache::vhost::file {      'hidden_service': -      content => template('site_apache/vhosts.d/hidden_service.conf.erb') +      content => template('site_apache/vhosts.d/hidden_service.conf.erb'); +    'server_status': +      vhost_source => 'modules/site_webapp/server-status.conf';    }    include site_shorewall::tor -}
\ No newline at end of file +} diff --git a/puppet/modules/site_webapp/templates/config.yml.erb b/puppet/modules/site_webapp/templates/config.yml.erb index 5cb436fc..19ed6b7b 100644 --- a/puppet/modules/site_webapp/templates/config.yml.erb +++ b/puppet/modules/site_webapp/templates/config.yml.erb @@ -21,7 +21,8 @@ production = {    "default_service_level" => @webapp['default_service_level'],    "service_levels" => @webapp['service_levels'],    "allow_registration" => @webapp['allow_registration'], -  "handle_blacklist" => @webapp['forbidden_usernames'] +  "handle_blacklist" => @webapp['forbidden_usernames'], +  "invite_required" => @webapp['invite_required']  }  if @webapp['engines'] && @webapp['engines'].any? diff --git a/puppet/modules/soledad/manifests/init.pp b/puppet/modules/soledad/manifests/init.pp index 7cf0b729..6a2c328e 100644 --- a/puppet/modules/soledad/manifests/init.pp +++ b/puppet/modules/soledad/manifests/init.pp @@ -1,18 +1,29 @@ +# set up users, group and directories for soledad-server +# although the soledad users are already created by the +# soledad-server package  class soledad {    group { 'soledad': -    ensure    => present, -    allowdupe => false; +    ensure => present, +    system => true,    }    user { 'soledad':      ensure    => present, -    allowdupe => false, +    system    => true,      gid       => 'soledad',      home      => '/srv/leap/soledad',      require   => Group['soledad'];    } +  user { 'soledad-admin': +    ensure  => present, +    system  => true, +    gid     => 'soledad', +    home    => '/srv/leap/soledad', +    require => Group['soledad']; +  } +    file {      '/srv/leap/soledad':        ensure  => directory, diff --git a/puppet/modules/soledad/manifests/server.pp b/puppet/modules/soledad/manifests/server.pp index b71fab69..e437c8f2 100644 --- a/puppet/modules/soledad/manifests/server.pp +++ b/puppet/modules/soledad/manifests/server.pp @@ -1,3 +1,4 @@ +# setup soledad-server  class soledad::server {    tag 'leap_service'    include soledad @@ -22,13 +23,19 @@ class soledad::server {    # 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']; +  file { +    '/etc/soledad': +      ensure => directory, +      owner  => 'root', +      group  => 'root', +      mode   => '0755'; +    '/etc/soledad/soledad-server.conf': +      content => template('soledad/soledad-server.conf.erb'), +      owner   => 'soledad', +      group   => 'soledad', +      mode    => '0640', +      notify  => Service['soledad-server'], +      require => Class['soledad'];    }    package { $sources['soledad']['package']: diff --git a/puppet/modules/soledad/templates/soledad-server.conf.erb b/puppet/modules/soledad/templates/soledad-server.conf.erb index 47d1f6e4..42cf44d8 100644 --- a/puppet/modules/soledad/templates/soledad-server.conf.erb +++ b/puppet/modules/soledad/templates/soledad-server.conf.erb @@ -1,3 +1,4 @@  [soledad-server] -couch_url = http://<%= @couchdb_user %>:<%= @couchdb_password %>@<%= @couchdb_host %>:<%= @couchdb_port %> - +couch_url   = http://<%= @couchdb_user %>:<%= @couchdb_password %>@<%= @couchdb_host %>:<%= @couchdb_port %> +create_cmd  = sudo -u soledad-admin /usr/bin/create-user-db +admin_netrc = /etc/couchdb/couchdb-soledad-admin.netrc | 
