diff options
8 files changed, 95 insertions, 32 deletions
diff --git a/puppet/modules/site_couchdb/files/designs/tmp_users/User.json b/puppet/modules/site_couchdb/files/designs/tmp_users/User.json deleted file mode 120000 index ed3d0af9..00000000 --- a/puppet/modules/site_couchdb/files/designs/tmp_users/User.json +++ /dev/null @@ -1 +0,0 @@ -../users/User.json
\ No newline at end of file diff --git a/puppet/modules/site_couchdb/lib/puppet/parser/functions/rotated_db_name.rb b/puppet/modules/site_couchdb/lib/puppet/parser/functions/rotated_db_name.rb new file mode 100644 index 00000000..6458ae81 --- /dev/null +++ b/puppet/modules/site_couchdb/lib/puppet/parser/functions/rotated_db_name.rb @@ -0,0 +1,24 @@ +module Puppet::Parser::Functions + newfunction(:rotated_db_name, :type => :rvalue, :doc => <<-EOS +This function takes a database name string and returns a database name with the current rotation stamp appended. +The first argument is the base name of the database. Subsequent arguments may contain these options: + * 'next' -- return the db name for the next rotation, not the current one. + * 'monthly' -- rotate monthly (default) + * 'weekly' -- rotate weekly +*Examples:* + rotated_db_name('tokens') => 'tokens_551' + EOS + ) do |arguments| + if arguments.include?('weekly') + rotation_period = 604800 # 1 week + else + rotation_period = 2592000 # 1 month + end + suffix = Time.now.utc.to_i / rotation_period + if arguments.include?('next') + suffix += 1 + end + "#{arguments.first}_#{suffix}" + end +end + diff --git a/puppet/modules/site_couchdb/manifests/create_dbs.pp b/puppet/modules/site_couchdb/manifests/create_dbs.pp index f9a08807..b743127a 100644 --- a/puppet/modules/site_couchdb/manifests/create_dbs.pp +++ b/puppet/modules/site_couchdb/manifests/create_dbs.pp @@ -4,8 +4,6 @@ class site_couchdb::create_dbs { -> Class['site_couchdb::bigcouch::settle_cluster'] -> Class['site_couchdb::create_dbs'] - # Couchdb databases - ### customer database ### r/w: webapp, couchdb::create_db { 'customers': @@ -30,7 +28,14 @@ class site_couchdb::create_dbs { ## sessions database ## r/w: webapp - couchdb::create_db { 'sessions': + $sessions_db = rotated_db_name('sessions', 'monthly') + couchdb::create_db { $sessions_db: + members => "{ \"names\": [\"$site_couchdb::couchdb_webapp_user\"], \"roles\": [\"replication\"] }", + require => Couchdb::Query::Setup['localhost'] + } + + $sessions_next_db = rotated_db_name('sessions', 'monthly', 'next') + couchdb::create_db { $sessions_next_db: members => "{ \"names\": [\"$site_couchdb::couchdb_webapp_user\"], \"roles\": [\"replication\"] }", require => Couchdb::Query::Setup['localhost'] } @@ -52,7 +57,14 @@ class site_couchdb::create_dbs { ## tokens database ## r: soledad - needs to be restricted with a design document ## r/w: webapp - couchdb::create_db { 'tokens': + $tokens_db = rotated_db_name('tokens', 'monthly') + couchdb::create_db { $tokens_db: + members => "{ \"names\": [], \"roles\": [\"replication\", \"tokens\"] }", + require => Couchdb::Query::Setup['localhost'] + } + + $tokens_next_db = rotated_db_name('tokens', 'monthly', 'next') + couchdb::create_db { $tokens_next_db: members => "{ \"names\": [], \"roles\": [\"replication\", \"tokens\"] }", require => Couchdb::Query::Setup['localhost'] } diff --git a/puppet/modules/site_couchdb/manifests/designs.pp b/puppet/modules/site_couchdb/manifests/designs.pp index 9e88de64..1ab1c6a1 100644 --- a/puppet/modules/site_couchdb/manifests/designs.pp +++ b/puppet/modules/site_couchdb/manifests/designs.pp @@ -11,10 +11,35 @@ class site_couchdb::designs { mode => '0755' } - exec { '/srv/leap/couchdb/scripts/load_design_documents.sh': - require => Vcsrepo['/srv/leap/couchdb/scripts'], - refreshonly => false + 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'; + 'shared_docs': + db => 'shared', + design => 'shared/docs.json'; + 'shared_syncs': + db => 'shared', + design => 'shared/syncs.json'; + 'shared_transactions': + db => 'shared', + design => 'shared/transactions.json'; } -} + $sessions_db = rotated_db_name('sessions', 'monthly') + $sessions_next_db = rotated_db_name('sessions', 'monthly', 'next') + site_couchdb::upload_design { + $sessions_db: design => 'sessions/Session.json'; + $sessions_next_db: design => 'sessions/Session.json'; + } + $tokens_db = rotated_db_name('tokens', 'monthly') + $tokens_next_db = rotated_db_name('tokens', 'monthly', 'next') + site_couchdb::upload_design { + $tokens_db: design => 'tokens/Token.json'; + $tokens_next_db: design => 'tokens/Token.json'; + } +} diff --git a/puppet/modules/site_couchdb/manifests/upload_design.pp b/puppet/modules/site_couchdb/manifests/upload_design.pp new file mode 100644 index 00000000..7b0cabd7 --- /dev/null +++ b/puppet/modules/site_couchdb/manifests/upload_design.pp @@ -0,0 +1,13 @@ +define site_couchdb::upload_design($db = $title, $design) { + $design_name = regsubst($design, '^.*\/(.*)\.json$', '\1') + $id = "_design/${design_name}" + $file = "/srv/leap/couchdb/designs/${design}" + exec { + "upload_design_${name}": + command => "/usr/local/bin/couch-doc-update --host 127.0.0.1:5984 --db '${db}' --id '${id}' --data '{}' --file '${file}'", + refreshonly => false, + loglevel => debug, + logoutput => on_failure, + require => File['/srv/leap/couchdb/designs']; + } +} diff --git a/puppet/modules/site_webapp/manifests/init.pp b/puppet/modules/site_webapp/manifests/init.pp index 5071d9bc..ea64048b 100644 --- a/puppet/modules/site_webapp/manifests/init.pp +++ b/puppet/modules/site_webapp/manifests/init.pp @@ -50,7 +50,7 @@ class site_webapp { owner => 'leap-webapp', group => 'leap-webapp', require => [ User['leap-webapp'], Group['leap-webapp'] ], - notify => [ Exec['bundler_update'], Exec['rotate_dbs'] ] + notify => Exec['bundler_update'] } exec { 'bundler_update': @@ -67,19 +67,6 @@ class site_webapp { notify => Service['apache']; } - # this only needs to be called before the first time the web app is run. - # after that, the cron job will take care of running db:rotate regularly. - exec { 'rotate_dbs': - cwd => '/srv/leap/webapp', - command => '/bin/bash -c "RAILS_ENV=production /usr/bin/bundle exec rake db:rotate"', - user => 'leap-webapp', - timeout => 600, - refreshonly => true, - require => [ - Vcsrepo['/srv/leap/webapp'], - Class['site_config::ruby::dev']]; - } - # # 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 diff --git a/puppet/modules/tapicero/templates/tapicero.yaml.erb b/puppet/modules/tapicero/templates/tapicero.yaml.erb index fb3b93aa..8b08b49c 100644 --- a/puppet/modules/tapicero/templates/tapicero.yaml.erb +++ b/puppet/modules/tapicero/templates/tapicero.yaml.erb @@ -20,7 +20,8 @@ connection: seq_dir: "/var/lib/leap/tapicero/" # Configure log_file like this if you want to log to a file instead of syslog: -# log_file: "/var/leap/log/tapicero.log" +#log_file: "/var/log/leap/tapicero.log" +#log_level: debug log_level: info # tapicero specific options diff --git a/tests/white-box/couchdb.rb b/tests/white-box/couchdb.rb index 450c4201..d0f5ce88 100644 --- a/tests/white-box/couchdb.rb +++ b/tests/white-box/couchdb.rb @@ -82,7 +82,10 @@ class CouchDB < LeapTest end def test_05_Do_required_databases_exist? - dbs_that_should_exist = ["customers","identities","keycache","sessions","shared","tickets","tokens","users"] + dbs_that_should_exist = ["customers","identities","keycache","shared","tickets","users", "tmp_users"] + rotation_suffix = Time.now.utc.to_i / 2592000 # monthly + dbs_that_should_exist << "tokens_#{rotation_suffix}" + dbs_that_should_exist << "sessions_#{rotation_suffix}" dbs_that_should_exist.each do |db_name| url = couchdb_url("/"+db_name, :username => 'admin') assert_get(url) do |body| @@ -113,9 +116,9 @@ class CouchDB < LeapTest #end def test_07_Can_records_be_created? - token = Token.new - url = couchdb_url("/tokens", :username => 'admin') - assert_post(url, token, :format => :json) do |body| + record = DummyRecord.new + url = couchdb_url("/tmp_users", :username => 'admin') + assert_post(url, record, :format => :json) do |body| assert response = JSON.parse(body), "POST response should be JSON" assert response["ok"], "POST response should be OK" assert_delete(File.join(url, response["id"]), :rev => response["rev"]) do |body| @@ -144,11 +147,10 @@ class CouchDB < LeapTest require 'securerandom' require 'digest/sha2' - class Token < Hash + class DummyRecord < Hash def initialize - self['token'] = SecureRandom.urlsafe_base64(32).gsub(/^_*/, '') - self['_id'] = Digest::SHA512.hexdigest(self['token']) - self['last_seen_at'] = Time.now + self['data'] = SecureRandom.urlsafe_base64(32).gsub(/^_*/, '') + self['_id'] = Digest::SHA512.hexdigest(self['data']) end end |