diff options
author | Micah <micah@leap.se> | 2016-07-12 16:45:54 -0400 |
---|---|---|
committer | Micah <micah@leap.se> | 2016-07-12 16:45:54 -0400 |
commit | f2019755fd724fb1020cb2d97cdf82b751450ebc (patch) | |
tree | 1c2bd3a4f03b84795ea0ce0b7ccc0f28a2ecbadd /puppet/modules/couchdb/manifests | |
parent | 81210aea5cf136194598e7a399ce307ecbe088f1 (diff) |
git subrepo clone https://leap.se/git/puppet_couchdb puppet/modules/couchdb
subrepo:
subdir: "puppet/modules/couchdb"
merged: "76ff149"
upstream:
origin: "https://leap.se/git/puppet_couchdb"
branch: "master"
commit: "76ff149"
git-subrepo:
version: "0.3.0"
origin: "https://github.com/ingydotnet/git-subrepo"
commit: "1e79595"
Change-Id: I9ccb1a9dfdaa083814ea395132c42a778052f59b
Diffstat (limited to 'puppet/modules/couchdb/manifests')
21 files changed, 591 insertions, 0 deletions
diff --git a/puppet/modules/couchdb/manifests/add_user.pp b/puppet/modules/couchdb/manifests/add_user.pp new file mode 100644 index 00000000..29c6a8c8 --- /dev/null +++ b/puppet/modules/couchdb/manifests/add_user.pp @@ -0,0 +1,39 @@ +define couchdb::add_user ( $roles, $pw, $salt = '' ) { + # Couchdb < 1.2 needs a pre-hashed pw and salt + # If you provide a salt, couchdb::add_user will assume that + # $pw is prehashed and pass both parameters to couchdb::update + # If $salt is empty, couchdb::add_user will assume that the pw + # is plaintext and will pass it to couchdb::update + + if $::couchdb::bigcouch == true { + $port = 5986 + } else { + $port = 5984 + } + + if $salt == '' { + # unhashed, plaintext pw, no salt. For couchdb >= 1.2 + $data = "{\"type\": \"user\", \"name\": \"${name}\", \"roles\": ${roles}, \"password\": \"${pw}\"}" + } else { + # prehashed pw with salt, for couchdb < 1.2 + # salt and encrypt pw + # str_and_salt2sha1 is a function from leap's stdlib module + $pw_and_salt = [ $pw, $salt ] + $sha = str_and_salt2sha1($pw_and_salt) + $data = "{\"type\": \"user\", \"name\": \"${name}\", \"roles\": ${roles}, \"password_sha\": \"${sha}\", \"salt\": \"${salt}\"}" + } + + # update the user with the given password unless they already work + couchdb::document { "update_user_${name}": + host => "127.0.0.1:${port}", + db => '_users', + id => "org.couchdb.user:${name}", + data => $data + } + + couchdb::query::setup { $name: + user => $name, + pw => $pw, + } + +} diff --git a/puppet/modules/couchdb/manifests/backup.pp b/puppet/modules/couchdb/manifests/backup.pp new file mode 100644 index 00000000..a477b5b1 --- /dev/null +++ b/puppet/modules/couchdb/manifests/backup.pp @@ -0,0 +1,51 @@ +# configure backup using couchdb-backup.py +class couchdb::backup { + + include couchdb::params + + # used in ERB templates + $bind_address = $couchdb::params::bind_address + $port = $couchdb::params::port + $backupdir = $couchdb::params::backupdir + + file { $couchdb::params::backupdir: + ensure => directory, + mode => '0755', + require => Package['couchdb'], + } + + file { '/usr/local/sbin/couchdb-backup.py': + ensure => present, + owner => root, + group => root, + mode => '0755', + content => template('couchdb/couchdb-backup.py.erb'), + require => File[$couchdb::params::backupdir], + } + + cron { 'couchdb-backup': + command => '/usr/local/sbin/couchdb-backup.py 2> /dev/null', + hour => 3, + minute => 0, + require => File['/usr/local/sbin/couchdb-backup.py'], + } + + case $::operatingsystem { + /Debian|Ubunu/: { + # note: python-couchdb >= 0.8 required, which is found in debian wheezy. + ensure_packages (['python-couchdb', 'python-simplejson'], { + before => File['/usr/local/sbin/couchdb-backup.py'] + }) + } + /RedHat|Centos/: { + exec {'install python-couchdb using easy_install': + command => 'easy_install http://pypi.python.org/packages/2.6/C/CouchDB/CouchDB-0.8-py2.6.egg', + creates => '/usr/lib/python2.6/site-packages/CouchDB-0.8-py2.6.egg', + } + } + default: { + err('This module has not been written to support your operating system') + } + } + +} diff --git a/puppet/modules/couchdb/manifests/base.pp b/puppet/modules/couchdb/manifests/base.pp new file mode 100644 index 00000000..6c7bf25f --- /dev/null +++ b/puppet/modules/couchdb/manifests/base.pp @@ -0,0 +1,124 @@ +# configure couchdb +class couchdb::base { + + if $::couchdb::bigcouch == true { + $couchdb_user = 'bigcouch' + include couchdb::bigcouch + } else { + $couchdb_user = 'couchdb' + } + + # we use package{} here because bigcouch.pp overwrites it and + # this won't work with ensure_packages() + package {'couchdb': + ensure => installed + } + + service { 'couchdb': + ensure => running, + hasstatus => true, + enable => true, + require => Package['couchdb'] + } + + # todo: make host/port configurable + exec { 'wait_for_couchdb': + command => 'wget --retry-connrefused --tries 10 --quiet "http://127.0.0.1:5984" -O /dev/null', + require => Service['couchdb'] + } + + + # couchrest gem is required for couch-doc-update script, + # and it needs the ruby-dev package installed to build + + if versioncmp($::operatingsystemrelease, '8') < 0 { + $couchrest_version = '1.2' + } + else { + # couchrest v1.2.1 doesn't build with default debian jessie rake version + # shipped as debian package (10.3.2) + # see https://leap.se/code/issues/7754 + $couchrest_version = '1.2.0' + } + + ensure_packages('ruby-dev') + ensure_packages('couchrest', { + provider => 'gem', + ensure => $couchrest_version, + require => Package['ruby-dev'] + }) + + File['/usr/local/bin/couch-doc-update'] -> Couchdb::Update <| |> + File['/usr/local/bin/couch-doc-diff'] -> Couchdb::Update <| |> + + Couchdb::Update <| |> -> Couchdb::Document <| |> + + file { + '/usr/local/bin/couch-doc-update': + source => 'puppet:///modules/couchdb/couch-doc-update', + mode => '0755', + owner => 'root', + group => 'root', + require => Package['couchrest']; + + '/usr/local/bin/couch-doc-diff': + source => 'puppet:///modules/couchdb/couch-doc-diff', + mode => '0755', + owner => 'root', + group => 'root', + require => Package['couchrest']; + + '/etc/couchdb/local.ini': + source => [ "puppet:///modules/site_couchdb/${::fqdn}/local.ini", + 'puppet:///modules/site_couchdb/local.ini', + 'puppet:///modules/couchdb/local.ini' ], + notify => Service[couchdb], + owner => $couchdb_user, + group => $couchdb_user, + mode => '0660', + require => Package['couchdb']; + + '/etc/couchdb/local.d': + ensure => directory, + require => Package['couchdb']; + } + + $alg = $::couchdb::pwhash_alg + $salt = $::couchdb::admin_salt + case $alg { + 'sha1': { + # str_and_salt2sha1 is a function from leap's stdlib module + $pw_and_salt = [ $::couchdb::admin_pw, $salt ] + $sha1 = str_and_salt2sha1($pw_and_salt) + $admin_hash = "-hashed-${sha1},${salt}" + } + 'pbkdf2': { + $pbkdf2 = pbkdf2($::couchdb::admin_pw, $::couchdb::admin_salt, 10) + $sha1 = $pbkdf2['sha1'] + $admin_hash = "-pbkdf2-${sha1},${salt},10" + } + default: { fail ("Unknown fact couchdb_pwhash_alg ${::couchdb_pwhash_alg} - Exiting.") } + } + + file { '/etc/couchdb/local.d/admin.ini': + content => template('couchdb/admin.ini.erb'), + mode => '0600', + owner => $couchdb_user, + group => $couchdb_user, + notify => Service[couchdb], + require => File['/etc/couchdb/local.d']; + } + + case $::couchdb::bigcouch { + true: { $restart_command = '/etc/init.d/bigcouch restart; sleep 6' } + default: { $restart_command = '/etc/init.d/couchdb restart; sleep 6' } + } + + exec { 'couchdb_restart': + command => $restart_command, + path => ['/bin', '/usr/bin',], + subscribe => File['/etc/couchdb/local.d/admin.ini', + '/etc/couchdb/local.ini'], + refreshonly => true + } +} diff --git a/puppet/modules/couchdb/manifests/bigcouch.pp b/puppet/modules/couchdb/manifests/bigcouch.pp new file mode 100644 index 00000000..a97411bf --- /dev/null +++ b/puppet/modules/couchdb/manifests/bigcouch.pp @@ -0,0 +1,51 @@ +class couchdb::bigcouch inherits couchdb::base { + + file { + '/opt/bigcouch': + ensure => directory, + mode => '0755'; + + '/etc/couchdb': + ensure => directory, + mode => '0755', + before => Package['couchdb']; + + '/opt/bigcouch/etc': + ensure => link, + target => '/etc/couchdb', + before => Package['couchdb']; + } + + # there's no bigcouch in the official debian repo, you need + # to setup a repository for that. You can use class + # couchdb::bigcouch::package::cloudant for unauthenticated 0.4.0 packages, + # or site_apt::leap_repo from the leap_platfrom repository + # for signed 0.4.2 packages + + Package['couchdb'] { + name => 'bigcouch' + } + + file { '/opt/bigcouch/etc/vm.args': + content => template('couchdb/bigcouch/vm.args'), + mode => '0640', + owner => 'bigcouch', + group => 'bigcouch', + require => Package['couchdb'], + notify => Service[couchdb] + } + + file { '/opt/bigcouch/etc/default.ini': + content => template('couchdb/bigcouch/default.ini'), + mode => '0640', + owner => 'bigcouch', + group => 'bigcouch', + require => Package['couchdb'], + notify => Service[couchdb] + } + + Service['couchdb'] { + name => 'bigcouch' + } + +} diff --git a/puppet/modules/couchdb/manifests/bigcouch/add_node.pp b/puppet/modules/couchdb/manifests/bigcouch/add_node.pp new file mode 100644 index 00000000..ed9db94b --- /dev/null +++ b/puppet/modules/couchdb/manifests/bigcouch/add_node.pp @@ -0,0 +1,8 @@ +define couchdb::bigcouch::add_node { + + couchdb::bigcouch::document { "add_${name}": + db => 'nodes', + id => "bigcouch@${name}", + ensure => 'present' + } +} diff --git a/puppet/modules/couchdb/manifests/bigcouch/debian.pp b/puppet/modules/couchdb/manifests/bigcouch/debian.pp new file mode 100644 index 00000000..645c6da8 --- /dev/null +++ b/puppet/modules/couchdb/manifests/bigcouch/debian.pp @@ -0,0 +1,11 @@ +class couchdb::bigcouch::debian inherits couchdb::debian { + + File['/etc/init.d/couchdb'] { + ensure => absent + } + + file {'/etc/init.d/bigcouch': + ensure => link, + target => '/usr/bin/sv' + } +} diff --git a/puppet/modules/couchdb/manifests/bigcouch/document.pp b/puppet/modules/couchdb/manifests/bigcouch/document.pp new file mode 100644 index 00000000..13f4ac17 --- /dev/null +++ b/puppet/modules/couchdb/manifests/bigcouch/document.pp @@ -0,0 +1,14 @@ +define couchdb::bigcouch::document ( + $db, + $id, + $host = '127.0.0.1:5986', + $data ='{}', + $ensure ='content') { + couchdb::document { $name: + ensure => $ensure, + host => $host, + db => $db, + id => $id, + data => $data + } +} diff --git a/puppet/modules/couchdb/manifests/bigcouch/package/cloudant.pp b/puppet/modules/couchdb/manifests/bigcouch/package/cloudant.pp new file mode 100644 index 00000000..cfdcf10c --- /dev/null +++ b/puppet/modules/couchdb/manifests/bigcouch/package/cloudant.pp @@ -0,0 +1,35 @@ +class couchdb::bigcouch::package::cloudant ( + $ensure = 'present' +) { + + # cloudant's signing key can be fetched from + # http://packages.cloudant.com/KEYS, please use the apt module to + # distribute it on your servers after verifying its fingerprint + + # cloudant's wheezy repo will fail cause in their Release file + # (http://packages.cloudant.com/debian/dists/wheezy/Release) they + # wrongly marked the packages for squeeze + # so we will use their squeeze repo here + apt::sources_list {'bigcouch-cloudant.list': + ensure => $ensure, + content => 'deb http://packages.cloudant.com/debian squeeze main' + } + + # right now, cloudant only provides authenticated bigcouch 0.4.2 packages + # for squeeze, therefore we need to allow the installation of the depending + # packages libicu44 and libssl0.9.8 from squeeze + + if $::lsbdistcodename == 'wheezy' { + apt::sources_list {'squeeze.list': + ensure => $ensure, + content => 'deb http://http.debian.net/debian squeeze main +deb http://security.debian.org/ squeeze/updates main +' } + apt::preferences_snippet { 'bigcouch_squeeze_deps': + ensure => $ensure, + package => 'libicu44 libssl0.9.8', + priority => '980', + pin => 'release o=Debian,n=squeeze' + } + } +} diff --git a/puppet/modules/couchdb/manifests/create_db.pp b/puppet/modules/couchdb/manifests/create_db.pp new file mode 100644 index 00000000..8a8d1144 --- /dev/null +++ b/puppet/modules/couchdb/manifests/create_db.pp @@ -0,0 +1,21 @@ +define couchdb::create_db ( + $host='127.0.0.1:5984', + $admins="{\"names\": [], \"roles\": [] }", + $members="{\"names\": [], \"roles\": [] }" ) +{ + + couchdb::query { "create_db_${name}": + cmd => 'PUT', + host => $host, + path => $name, + unless => "/usr/bin/curl -s -f --netrc-file /etc/couchdb/couchdb.netrc ${host}/${name}" + } + + couchdb::document { "${name}_security": + db => $name, + id => '_security', + host => $host, + data => "{ \"admins\": ${admins}, \"members\": ${members} }", + require => Couchdb::Query["create_db_${name}"] + } +} diff --git a/puppet/modules/couchdb/manifests/debian.pp b/puppet/modules/couchdb/manifests/debian.pp new file mode 100644 index 00000000..b83b227a --- /dev/null +++ b/puppet/modules/couchdb/manifests/debian.pp @@ -0,0 +1,15 @@ +# installs initscript and dependent packages on debian +class couchdb::debian inherits couchdb::base { + + ensure_packages('libjs-jquery') + + file { '/etc/init.d/couchdb': + source => [ + 'puppet:///modules/site_couchdb/Debian/couchdb', + 'puppet:///modules/couchdb/Debian/couchdb' ], + mode => '0755', + owner => 'root', + group => 'root', + require => Package['couchdb'] + } +} diff --git a/puppet/modules/couchdb/manifests/deploy_config.pp b/puppet/modules/couchdb/manifests/deploy_config.pp new file mode 100644 index 00000000..2ce1fd20 --- /dev/null +++ b/puppet/modules/couchdb/manifests/deploy_config.pp @@ -0,0 +1,12 @@ +class couchdb::deploy_config { + + file { '/etc/couchdb/local.ini': + source => [ "puppet:///modules/site_couchdb/${::fqdn}/local.ini", + 'puppet:///modules/site_couchdb/local.ini', + 'puppet:///modules/couchdb/local.ini' ], + notify => Service[couchdb], + owner => couchdb, + group => couchdb, + mode => '0660' + } +} diff --git a/puppet/modules/couchdb/manifests/document.pp b/puppet/modules/couchdb/manifests/document.pp new file mode 100644 index 00000000..6180474b --- /dev/null +++ b/puppet/modules/couchdb/manifests/document.pp @@ -0,0 +1,47 @@ +# Usage: +# couchdb::document { id: +# db => "database", +# data => "content", +# ensure => {absent,present,*content*} +# } +# +define couchdb::document( + $db, + $id, + $host = '127.0.0.1:5984', + $data = '{}', + $netrc = '/etc/couchdb/couchdb.netrc', + $ensure = 'content') { + + $url = "${host}/${db}/${id}" + + case $ensure { + default: { err ( "unknown ensure value '${ensure}'" ) } + content: { + exec { "couch-doc-update --netrc-file ${netrc} --host ${host} --db ${db} --id ${id} --data \'${data}\'": + require => Exec['wait_for_couchdb'], + unless => "couch-doc-diff $url '$data'" + } + } + + present: { + couchdb::query { "create_${db}_${id}": + cmd => 'PUT', + host => $host, + path => "${db}/${id}", + require => Exec['wait_for_couchdb'], + unless => "/usr/bin/curl -s -f --netrc-file ${netrc} ${url}" + } + } + + absent: { + couchdb::query { "destroy_${db}_${id}": + cmd => 'DELETE', + host => $host, + path => "${db}/${id}", + require => Exec['wait_for_couchdb'], + unless => "/usr/bin/curl -s -f --netrc-file ${netrc} ${url}" + } + } + } +} diff --git a/puppet/modules/couchdb/manifests/init.pp b/puppet/modules/couchdb/manifests/init.pp new file mode 100644 index 00000000..12598ba0 --- /dev/null +++ b/puppet/modules/couchdb/manifests/init.pp @@ -0,0 +1,31 @@ +# initial couchdb class +class couchdb ( + $admin_pw, + $admin_salt = '', + $bigcouch = false, + $bigcouch_cookie = '', + $ednp_port = '9001', + $chttpd_bind_address = '0.0.0.0', + $pwhash_alg = 'pbkdf2' ) +{ + + # stdlib is needed i.e. for ensure_packages() + include ::stdlib + + case $::operatingsystem { + Debian: { + case $::lsbdistcodename { + /lenny|squeeze|wheezy|jessie/: { + include couchdb::debian + if $bigcouch == true { + include couchdb::bigcouch::debian + } + } + default: { fail "couchdb not available for ${::operatingsystem}/${::lsbdistcodename}" } + } + } + RedHat: { include couchdb::redhat } + } + + ensure_packages('curl') +} diff --git a/puppet/modules/couchdb/manifests/mirror_db.pp b/puppet/modules/couchdb/manifests/mirror_db.pp new file mode 100644 index 00000000..b07b6749 --- /dev/null +++ b/puppet/modules/couchdb/manifests/mirror_db.pp @@ -0,0 +1,21 @@ +define couchdb::mirror_db ( + $host='127.0.0.1:5984', + $from='', + $to='', + $user='replication', + $role='replication' + ) +{ + $source = "${from}/${name}" + if $to == '' { $target = $name } + else { $target = "${to}/${name}" } + + couchdb::document { "${name}_replication": + db => "_replicator", + id => "${name}_replication", + netrc => "/etc/couchdb/couchdb-${user}.netrc", + host => $host, + data => "{ \"source\": \"${source}\", \"target\": \"${target}\", \"continuous\": true, \"user_ctx\": { \"name\": \"${user}\", \"roles\": [\"${role}\"] }, \"owner\": \"${user}\" }", + require => Couchdb::Query["create_db_${name}"] + } +} diff --git a/puppet/modules/couchdb/manifests/params.pp b/puppet/modules/couchdb/manifests/params.pp new file mode 100644 index 00000000..02d5f02e --- /dev/null +++ b/puppet/modules/couchdb/manifests/params.pp @@ -0,0 +1,23 @@ +class couchdb::params { + + $bind_address = $::couchdb_bind_address ? { + '' => '127.0.0.1', + default => $::couchdb_bind_address, + } + + $port = $::couchdb_port ? { + '' => '5984', + default => $::couchdb_port, + } + + $backupdir = $::couchdb_backupdir ? { + '' => '/var/backups/couchdb', + default => $::couchdb_backupdir, + } + + $cert_path = $::couchdb_cert_path ? { + "" => '/etc/couchdb', + default => $::couchdb_cert_path, + } + +} diff --git a/puppet/modules/couchdb/manifests/query.pp b/puppet/modules/couchdb/manifests/query.pp new file mode 100644 index 00000000..9507ca1e --- /dev/null +++ b/puppet/modules/couchdb/manifests/query.pp @@ -0,0 +1,12 @@ +define couchdb::query ( + $cmd, $path, + $netrc='/etc/couchdb/couchdb.netrc', + $host='127.0.0.1:5984', + $data = '{}', + $unless = undef) { + + exec { "/usr/bin/curl -s --netrc-file ${netrc} -X ${cmd} ${host}/${path} --data \'${data}\'": + require => [ Package['curl'], Exec['wait_for_couchdb'] ], + unless => $unless + } +} diff --git a/puppet/modules/couchdb/manifests/query/setup.pp b/puppet/modules/couchdb/manifests/query/setup.pp new file mode 100644 index 00000000..451eb536 --- /dev/null +++ b/puppet/modules/couchdb/manifests/query/setup.pp @@ -0,0 +1,10 @@ +define couchdb::query::setup ($user, $pw, $host='127.0.0.1') { + + file { "/etc/couchdb/couchdb-${user}.netrc": + content => "machine ${host} login ${user} password ${pw}", + mode => '0600', + owner => $::couchdb::base::couchdb_user, + group => $::couchdb::base::couchdb_user, + require => Package['couchdb']; + } +} diff --git a/puppet/modules/couchdb/manifests/redhat.pp b/puppet/modules/couchdb/manifests/redhat.pp new file mode 100644 index 00000000..defa0a94 --- /dev/null +++ b/puppet/modules/couchdb/manifests/redhat.pp @@ -0,0 +1 @@ +class couchdb::redhat inherits couchdb::base {} diff --git a/puppet/modules/couchdb/manifests/ssl/deploy_cert.pp b/puppet/modules/couchdb/manifests/ssl/deploy_cert.pp new file mode 100644 index 00000000..d3e743f1 --- /dev/null +++ b/puppet/modules/couchdb/manifests/ssl/deploy_cert.pp @@ -0,0 +1,28 @@ +define couchdb::ssl::deploy_cert ($cert, $key) { + + include couchdb::params + + file { 'couchdb_cert_directory': + ensure => 'directory', + path => $couchdb::params::cert_path, + mode => '0600', + owner => 'couchdb', + group => 'couchdb'; + } + + file { 'couchdb_cert': + path => "${couchdb::params::cert_path}/server_cert.pem", + mode => '0644', + owner => 'couchdb', + group => 'couchdb', + content => $cert + } + + file { 'couchdb_key': + path => "${couchdb::params::cert_path}/server_key.pem", + mode => '0600', + owner => 'couchdb', + group => 'couchdb', + content => $key + } +} diff --git a/puppet/modules/couchdb/manifests/ssl/generate_cert.pp b/puppet/modules/couchdb/manifests/ssl/generate_cert.pp new file mode 100644 index 00000000..a443250e --- /dev/null +++ b/puppet/modules/couchdb/manifests/ssl/generate_cert.pp @@ -0,0 +1,25 @@ +# configures cert for ssl access +class couchdb::ssl::generate_cert { + + ensure_packages('openssl') + + file { $couchdb::cert_path: + ensure => 'directory', + mode => '0600', + owner => 'couchdb', + group => 'couchdb'; + } + +exec { 'generate-certs': + command => "/usr/bin/openssl req -new -inform PEM -x509 -nodes -days 150 -subj \ +'/C=ZZ/ST=AutoSign/O=AutoSign/localityName=AutoSign/commonName=${::hostname}/organizationalUnitName=AutoSign/emailAddress=AutoSign/' \ +-newkey rsa:2048 -out ${couchdb::cert_path}/couchdb_cert.pem -keyout ${couchdb::cert_path}/couchdb_key.pem", + unless => "/usr/bin/test -f ${couchdb::cert_path}/couchdb_cert.pem && +/usr/bin/test -f ${couchdb::params::cert_path}/couchdb_key.pem", + require => [ + File[$couchdb::params::cert_path], + Exec['make-install'] + ], + notify => Service['couchdb'], + } +} diff --git a/puppet/modules/couchdb/manifests/update.pp b/puppet/modules/couchdb/manifests/update.pp new file mode 100644 index 00000000..b1dba84c --- /dev/null +++ b/puppet/modules/couchdb/manifests/update.pp @@ -0,0 +1,12 @@ +define couchdb::update ( + $db, + $id, + $data, + $host='127.0.0.1:5984', + $unless=undef) { + + exec { "couch-doc-update --host ${host} --db ${db} --id ${id} --data \'${data}\'": + require => Exec['wait_for_couchdb'], + unless => $unless + } +} |