diff options
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 +  } +} | 
