diff --git a/Puppetfile b/Puppetfile index 500d52272..0bf62a5a9 100644 --- a/Puppetfile +++ b/Puppetfile @@ -71,7 +71,7 @@ mod 'module-data', :git => 'https://github.com/ripienaar/puppet-module-data.git' mod 'mongodb', - :commit => '0518f864afcce2ebb79f1f2edab5de323c811af7', + :commit => 'fe562b86f388a6d107bb1f3cb3b32a3978f59c2a', :git => 'https://github.com/puppetlabs/puppetlabs-mongodb.git' mod 'mysql', diff --git a/mongodb/.gitignore b/mongodb/.gitignore index 9bbbbed4b..3149ad990 100644 --- a/mongodb/.gitignore +++ b/mongodb/.gitignore @@ -1,5 +1,4 @@ Gemfile.lock -metadata.json *.idea *.swp *.tmp @@ -7,4 +6,4 @@ tmp/ pkg/ spec/fixtures/manifests .rspec_system/ -.vagrant/ \ No newline at end of file +.vagrant/ diff --git a/mongodb/CHANGELOG b/mongodb/CHANGELOG deleted file mode 100644 index 92a220f48..000000000 --- a/mongodb/CHANGELOG +++ /dev/null @@ -1,74 +0,0 @@ -##2014-05-27 - Release 0.8.0 - -This feature features a rewritten mongodb_replset{} provider, includes several -important bugfixes, ruby 1.8 support, and two new features. - -####Features -- Rewritten mongodb_replset{}, featuring puppet resource support, prefetching, -and flushing. -- Add Ruby 1.8 compatibility. -- Adds `syslog`, allowing you to configure mongodb to send all logging to the hosts syslog. -- Add mongodb::replset, a wrapper class for hiera users. -- Improved testing! - -####Bugfixes -- Fixes the package names to work since 10gen renamed them again. -- Fix provider name in the README. -- Disallow `nojournal` and `journal` to be set at the same time. -- Changed - to = for versioned install on Ubuntu. - -####Known Bugs -* No known bugs - -2014-1-29 - Version 0.7.0 - -Summary: - -Added Replica Set Type and Provider - -2014-1-17 - Version 0.6.0 - -Summary: - -Added support for installing MongoDB client on -RHEL family systems. - -2014-01-10 Version 0.5.0 - -Summary: - -Added types for providers for Mongo users and databases. - -2013-12 Version 0.4.0 - -Major refactoring of the MongoDB module. Includes a new 'mongodb::globals' -that consolidates many shared parameters into one location. This is an -API-breaking release in anticipation of a 1.0 release. - -2013-10-31 - Version 0.3.0 - -Summary: - -Adds a number of parameters and fixes some platform -specific bugs in module deployment. - -2013-09-25 - Version 0.2.0 - -Summary: - -This release fixes a duplicate parameter. - -Fixes: -- Fix a duplicated parameter. - -2012-07-13 Puppet Labs - 0.1.0 -* Add support for RHEL/CentOS -* Change default mongodb install location to OS repo - -2012-05-29 Puppet Labs - 0.0.2 -* Fix Modulefile typo. -* Remove repo pin. -* Update spec tests and add travis support. - -2012-05-03 Puppet Labs - 0.0.1 -* Initial Release. diff --git a/mongodb/CHANGELOG.md b/mongodb/CHANGELOG.md new file mode 100644 index 000000000..b85bb68c3 --- /dev/null +++ b/mongodb/CHANGELOG.md @@ -0,0 +1,94 @@ +##2014-11-25 - Release 0.9.0 +###Summary + +This release has a number of new parameters, support for 2.6, improved providers, and several bugfixes. + +####Features +- New parameters: `mongodb::globals` + - `$service_ensure` + - `$service_enable` +- New parameters: `mongodb` + - `$quiet` +- New parameters: `mongodb::server` + - `$service_ensure` + - `$service_enable` + - `$quiet` + - `$config_content` +- Support for mongodb 2.6 +- Reimplement `mongodb_user` and `mongodb_database` provider +- Added `mongodb_conn_validator` type + +####Bugfixes +- Use hkp for the apt keyserver +- Fix mongodb database existance check +- Fix `$server_package_name` problem (MODULES-690) +- Make sure `pidfilepath` doesn't have any spaces +- Providers need the client command before they can work (MODULES-1285) + +##2014-05-27 - Release 0.8.0 +###Summary + +This feature features a rewritten mongodb_replset{} provider, includes several +important bugfixes, ruby 1.8 support, and two new features. + +####Features +- Rewritten mongodb_replset{}, featuring puppet resource support, prefetching, +and flushing. +- Add Ruby 1.8 compatibility. +- Adds `syslog`, allowing you to configure mongodb to send all logging to the hosts syslog. +- Add mongodb::replset, a wrapper class for hiera users. +- Improved testing! + +####Bugfixes +- Fixes the package names to work since 10gen renamed them again. +- Fix provider name in the README. +- Disallow `nojournal` and `journal` to be set at the same time. +- Changed - to = for versioned install on Ubuntu. + +##2014-1-29 - Release 0.7.0 +###Summary + +Added Replica Set Type and Provider + +##2014-1-17 - Release 0.6.0 +###Summary + +Added support for installing MongoDB client on +RHEL family systems. + +##2014-01-10 Release 0.5.0 +###Summary + +Added types for providers for Mongo users and databases. + +##2013-12 Release 0.4.0 + +Major refactoring of the MongoDB module. Includes a new 'mongodb::globals' +that consolidates many shared parameters into one location. This is an +API-breaking release in anticipation of a 1.0 release. + +##2013-10-31 - Release 0.3.0 +###Summary + +Adds a number of parameters and fixes some platform +specific bugs in module deployment. + +##2013-09-25 - Release 0.2.0 +###Summary + +This release fixes a duplicate parameter. + +####Bugfixes +- Fix a duplicated parameter. + +##2012-07-13 - Release 0.1.0 +- Add support for RHEL/CentOS +- Change default mongodb install location to OS repo + +##2012-05-29 - Release 0.0.2 +- Fix Modulefile typo. +- Remove repo pin. +- Update spec tests and add travis support. + +##2012-05-03 - Release 0.0.1 +- Initial Release. diff --git a/mongodb/Gemfile b/mongodb/Gemfile index d0c14e046..39abe867d 100644 --- a/mongodb/Gemfile +++ b/mongodb/Gemfile @@ -10,7 +10,6 @@ group :test, :development do gem 'simplecov', :require => false gem 'beaker', :require => false gem 'beaker-rspec', :require => false - gem 'vagrant-wrapper', :require => false end if puppetversion = ENV['PUPPET_VERSION'] diff --git a/mongodb/Modulefile b/mongodb/Modulefile deleted file mode 100644 index e2eb82771..000000000 --- a/mongodb/Modulefile +++ /dev/null @@ -1,12 +0,0 @@ -name 'puppetlabs-mongodb' -version '0.8.0' -source 'git@github.com:puppetlabs/puppetlabs-mongodb.git' -author 'puppetlabs' -license 'Apache License Version 2.0' -summary 'mongodb puppet module' -description '10gen mongodb puppet module' -project_page 'https://github.com/puppetlabs/puppetlabs-mongodb' - -## Add dependencies, if any: -dependency 'puppetlabs/apt', '>= 1.0.0' -dependency 'puppetlabs/stdlib', '>= 2.2.0' diff --git a/mongodb/README.md b/mongodb/README.md index 9462cbd49..5483642a8 100644 --- a/mongodb/README.md +++ b/mongodb/README.md @@ -62,8 +62,8 @@ class {'::mongodb::server': For Red Hat family systems, the client can be installed in a similar fashion: -``` -puppet class {'::mongodb::client':} +```puppet +class {'::mongodb::client':} ``` Note that for Debian/Ubuntu family systems the client is installed with the @@ -335,6 +335,14 @@ set name as an argument to this set. All hosts must have the same set name. #####`rest` Set to true to enable a simple REST interface. Default: false +#####`quiet` +Runs the mongod or mongos instance in a quiet mode that attempts to limit the +amount of output. This option suppresses : "output from database commands, including drop, dropIndexes, diagLogging, validate, and clean", "replication activity", "connection accepted events" and "connection closed events". +Default: false + +> For production systems this option is **not** recommended as it may make tracking +problems during particular connections much more difficult. + #####`slowms` Sets the threshold for mongod to consider a query “slow” for the database profiler. Default: 100 ms @@ -411,6 +419,7 @@ The maximum amount of two second tries to wait MongoDB startup. Default: 10 ```puppet mongodb_user { testuser: + username => 'testuser', ensure => present, password_hash => mongodb_password('testuser', 'p@ssw0rd'), database => testdb, @@ -419,6 +428,9 @@ mongodb_user { testuser: require => Class['mongodb::server'], } ``` +#####`username` +Name of the mongodb user. + #####`password_hash` Hex encoded md5 hash of "$username:mongo:$password". diff --git a/mongodb/lib/puppet/provider/mongodb.rb b/mongodb/lib/puppet/provider/mongodb.rb new file mode 100644 index 000000000..9a579bd52 --- /dev/null +++ b/mongodb/lib/puppet/provider/mongodb.rb @@ -0,0 +1,54 @@ +class Puppet::Provider::Mongodb < Puppet::Provider + + # Without initvars commands won't work. + initvars + commands :mongo => 'mongo' + + # Optional defaults file + def self.mongorc_file + if File.file?("#{Facter.value(:root_home)}/.mongorc.js") + "load('#{Facter.value(:root_home)}/.mongorc.js'); " + else + nil + end + end + + def mongorc_file + self.class.mongorc_file + end + + # Mongo Command Wrapper + def self.mongo_eval(cmd, db = 'admin') + if mongorc_file + cmd = mongorc_file + cmd + end + + out = mongo([db, '--quiet', '--eval', cmd]) + + out.gsub!(/ObjectId\(([^)]*)\)/, '\1') + out + end + + def mongo_eval(cmd, db = 'admin') + self.class.mongo_eval(cmd, db) + end + + # Mongo Version checker + def self.mongo_version + @@mongo_version ||= self.mongo_eval('db.version()') + end + + def mongo_version + self.class.mongo_version + end + + def self.mongo_24? + v = self.mongo_version + ! v[/^2\.4\./].nil? + end + + def mongo_24? + self.class.mongo_24? + end + +end diff --git a/mongodb/lib/puppet/provider/mongodb_database/mongodb.rb b/mongodb/lib/puppet/provider/mongodb_database/mongodb.rb index 2de8420cc..0fb9d1856 100644 --- a/mongodb/lib/puppet/provider/mongodb_database/mongodb.rb +++ b/mongodb/lib/puppet/provider/mongodb_database/mongodb.rb @@ -1,36 +1,40 @@ -Puppet::Type.type(:mongodb_database).provide(:mongodb) do +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'mongodb')) +Puppet::Type.type(:mongodb_database).provide(:mongodb, :parent => Puppet::Provider::Mongodb) do desc "Manages MongoDB database." defaultfor :kernel => 'Linux' - commands :mongo => 'mongo' - - def block_until_mongodb(tries = 10) - begin - mongo('--quiet', '--eval', 'db.getMongo()') - rescue => e - debug('MongoDB server not ready, retrying') - sleep 2 - if (tries -= 1) > 0 - retry - else - raise e + def self.instances + require 'json' + dbs = JSON.parse mongo_eval('printjson(db.getMongo().getDBs())') + + dbs['databases'].collect do |db| + new(:name => db['name'], + :ensure => :present) + end + end + + # Assign prefetched dbs based on name. + def self.prefetch(resources) + dbs = instances + resources.keys.each do |name| + if provider = dbs.find { |db| db.name == name } + resources[name].provider = provider end end end def create - mongo(@resource[:name], '--quiet', '--eval', "db.dummyData.insert({\"created_by_puppet\": 1})") + mongo_eval('db.dummyData.insert({"created_by_puppet": 1})', @resource[:name]) end def destroy - mongo(@resource[:name], '--quiet', '--eval', 'db.dropDatabase()') + mongo_eval('db.dropDatabase()', @resource[:name]) end def exists? - block_until_mongodb(@resource[:tries]) - mongo("--quiet", "--eval", 'db.getMongo().getDBNames()').chomp.split(",").include?(@resource[:name]) + !(@property_hash[:ensure] == :absent or @property_hash[:ensure].nil?) end end diff --git a/mongodb/lib/puppet/provider/mongodb_user/mongodb.rb b/mongodb/lib/puppet/provider/mongodb_user/mongodb.rb index 10e0bf7f0..635d44a06 100644 --- a/mongodb/lib/puppet/provider/mongodb_user/mongodb.rb +++ b/mongodb/lib/puppet/provider/mongodb_user/mongodb.rb @@ -1,48 +1,137 @@ -Puppet::Type.type(:mongodb_user).provide(:mongodb) do +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'mongodb')) +Puppet::Type.type(:mongodb_user).provide(:mongodb, :parent => Puppet::Provider::Mongodb) do desc "Manage users for a MongoDB database." defaultfor :kernel => 'Linux' - commands :mongo => 'mongo' + def self.instances + require 'json' - def block_until_mongodb(tries = 10) - begin - mongo('--quiet', '--eval', 'db.getMongo()') - rescue - debug('MongoDB server not ready, retrying') - sleep 2 - retry unless (tries -= 1) <= 0 + if mongo_24? + dbs = JSON.parse mongo_eval('printjson(db.getMongo().getDBs()["databases"].map(function(db){return db["name"]}))') || 'admin' + + allusers = [] + + dbs.each do |db| + users = JSON.parse mongo_eval('printjson(db.system.users.find().toArray())', db) + + allusers += users.collect do |user| + new(:name => user['_id'], + :ensure => :present, + :username => user['user'], + :database => db, + :roles => user['roles'].sort, + :password_hash => user['pwd']) + end + end + return allusers + else + users = JSON.parse mongo_eval('printjson(db.system.users.find().toArray())') + + users.collect do |user| + new(:name => user['_id'], + :ensure => :present, + :username => user['user'], + :database => user['db'], + :roles => from_roles(user['roles'], user['db']), + :password_hash => user['credentials']['MONGODB-CR']) + end + end + end + + # Assign prefetched users based on username and database, not on id and name + def self.prefetch(resources) + users = instances + resources.each do |name, resource| + if provider = users.find { |user| user.username == resource[:username] and user.database == resource[:database] } + resources[name].provider = provider + end end end + mk_resource_methods + def create - mongo(@resource[:database], '--eval', "db.system.users.insert({user:\"#{@resource[:name]}\", pwd:\"#{@resource[:password_hash]}\", roles: #{@resource[:roles].inspect}})") + + + if mongo_24? + user = { + :user => @resource[:username], + :pwd => @resource[:password_hash], + :roles => @resource[:roles] + } + + mongo_eval("db.addUser(#{user.to_json})", @resource[:database]) + else + user = { + :user => @resource[:username], + :pwd => @resource[:password_hash], + :customData => { :createdBy => "Puppet Mongodb_user['#{@resource[:name]}']" }, + :roles => @resource[:roles] + } + + mongo_eval("db.createUser(#{user.to_json})", @resource[:database]) + end + + @property_hash[:ensure] = :present + @property_hash[:username] = @resource[:username] + @property_hash[:database] = @resource[:database] + @property_hash[:password_hash] = '' + @property_hash[:rolse] = @resource[:roles] + + exists? ? (return true) : (return false) end + def destroy - mongo(@resource[:database], '--quiet', '--eval', "db.removeUser(\"#{@resource[:name]}\")") + if mongo_24? + mongo_eval("db.removeUser('#{@resource[:username]}')") + else + mongo_eval("db.dropUser('#{@resource[:username]}')") + end end def exists? - block_until_mongodb(@resource[:tries]) - mongo(@resource[:database], '--quiet', '--eval', "db.system.users.find({user:\"#{@resource[:name]}\"}).count()").strip.eql?('1') - end - - def password_hash - mongo(@resource[:database], '--quiet', '--eval', "db.system.users.findOne({user:\"#{@resource[:name]}\"})[\"pwd\"]").strip + !(@property_hash[:ensure] == :absent or @property_hash[:ensure].nil?) end def password_hash=(value) - mongo(@resource[:database], '--quiet', '--eval', "db.system.users.update({user:\"#{@resource[:name]}\"}, { $set: {pwd:\"#{value}\"}})") + cmd = { + :updateUser => @resource[:username], + :pwd => @resource[:password_hash], + :digestPassword => false + } + + mongo_eval("db.runCommand(#{cmd.to_json})", @resource[:database]) end - def roles - mongo(@resource[:database], '--quiet', '--eval', "db.system.users.findOne({user:\"#{@resource[:name]}\"})[\"roles\"]").strip.split(",").sort + def roles=(roles) + if mongo_24? + mongo_eval("db.system.users.update({user:'#{@resource[:username]}'}, { $set: {roles: #{@resource[:roles].to_json}}})") + else + grant = roles-@resource[:roles] + if grant.length > 0 + mongo_eval("db.getSiblingDB('#{@resource[:database]}').grantRolesToUser('#{@resource[:username]}', #{grant. to_json})") + end + + revoke = @resource[:roles]-roles + if revoke.length > 0 + mongo_eval("db.getSiblingDB('#{@resource[:database]}').revokeRolesFromUser('#{@resource[:username]}', #{revoke.to_json})") + end + end end - def roles=(value) - mongo(@resource[:database], '--quiet', '--eval', "db.system.users.update({user:\"#{@resource[:name]}\"}, { $set: {roles: #{@resource[:roles].inspect}}})") + private + + def self.from_roles(roles, db) + roles.map do |entry| + if entry['db'] == db + entry['role'] + else + "#{entry['role']}@#{entry['db']}" + end + end.sort end end diff --git a/mongodb/lib/puppet/type/mongodb_user.rb b/mongodb/lib/puppet/type/mongodb_user.rb index 9cd7b1038..aee39efdf 100644 --- a/mongodb/lib/puppet/type/mongodb_user.rb +++ b/mongodb/lib/puppet/type/mongodb_user.rb @@ -10,13 +10,18 @@ def initialize(*args) end newparam(:name, :namevar=>true) do + desc "The name of the resource." + end + + newproperty(:username) do desc "The name of the user." + defaultto { @resource[:name] } end - newparam(:database) do + newproperty(:database) do desc "The user's target database." defaultto do - fail("Parameter 'database' must be set") + fail("Parameter 'database' must be set") if provider.database == :absent end newvalues(/^\w+$/) end @@ -48,7 +53,7 @@ def is_to_s(value) newproperty(:password_hash) do desc "The password hash of the user. Use mongodb_password() for creating hash." defaultto do - fail("Property 'password_hash' must be set. Use mongodb_password() for creating hash.") + fail("Property 'password_hash' must be set. Use mongodb_password() for creating hash.") if provider.database == :absent end newvalue(/^\w+$/) end diff --git a/mongodb/manifests/client.pp b/mongodb/manifests/client.pp index bf557d690..116fc4632 100644 --- a/mongodb/manifests/client.pp +++ b/mongodb/manifests/client.pp @@ -9,7 +9,7 @@ # is repository dependent. # class mongodb::client ( - $ensure = $mongodb::params::ensure_client, + $ensure = $mongodb::params::package_ensure_client, $package_name = $mongodb::params::client_package_name, ) inherits mongodb::params { class { 'mongodb::client::install': } diff --git a/mongodb/manifests/init.pp b/mongodb/manifests/init.pp index d489731b0..ca4500c69 100644 --- a/mongodb/manifests/init.pp +++ b/mongodb/manifests/init.pp @@ -74,6 +74,7 @@ $source = undef, $replset = undef, $rest = undef, + $quiet = undef, $slowms = undef, $keyfile = undef, $bind_ip = undef, @@ -127,6 +128,7 @@ source => $source, replset => $replset, rest => $rest, + quiet => $quiet, slowms => $slowms, keyfile => $keyfile, bind_ip => $bind_ip, diff --git a/mongodb/manifests/params.pp b/mongodb/manifests/params.pp index 50abeffbc..7789e27d3 100644 --- a/mongodb/manifests/params.pp +++ b/mongodb/manifests/params.pp @@ -1,82 +1,121 @@ # PRIVATE CLASS: do not use directly class mongodb::params inherits mongodb::globals { - $ensure = true - $service_enable = pick($service_enable, true) - $service_ensure = pick($service_ensure, 'running') - $service_status = $service_status - $ensure_client = true + $ensure = true + $service_enable = pick($mongodb::globals::service_enable, true) + $service_ensure = pick($mongodb::globals::service_ensure, 'running') + $service_status = $mongodb::globals::service_status # Amazon Linux's OS Family is 'Linux', operating system 'Amazon'. case $::osfamily { 'RedHat', 'Linux': { if $mongodb::globals::manage_package_repo { - $user = pick($user, 'mongod') - $group = pick($group, 'mongod') - if $::mongodb::globals::version { - $server_package_name = pick("$::mongodb::globals::server_package_name-${::mongodb::globals::version}", "mongodb-org-server-${::mongodb::globals::version}") - $client_package_name = pick("$::mongodb::globals::client_package_name-${::mongodb::globals::version}", "mongodb-org-shell-${::mongodb::globals::version}") - } else { + $user = pick($::mongodb::globals::user, 'mongod') + $group = pick($::mongodb::globals::group, 'mongod') + if ($::mongodb::globals::version == undef) { $server_package_name = pick($::mongodb::globals::server_package_name, 'mongodb-org-server') $client_package_name = pick($::mongodb::globals::client_package_name, 'mongodb-org-shell') + $package_ensure = true + $package_ensure_client = true + } else { + # check if the version is greater than 2.6 + if(versioncmp($::mongodb::globals::version, '2.6.0') >= 0) { + $server_package_name = pick($::mongodb::globals::server_package_name, 'mongodb-org-server') + $client_package_name = pick($::mongodb::globals::client_package_name, 'mongodb-org-shell') + $package_ensure = $::mongodb::globals::version + $package_ensure_client = $::mongodb::globals::version + } else { + $server_package_name = pick($::mongodb::globals::server_package_name, 'mongodb-10gen') + $client_package_name = pick($::mongodb::globals::client_package_name, 'mongodb-10gen') + $package_ensure = $::mongodb::globals::version + $package_ensure_client = $::mongodb::globals::version #this is still needed in case they are only installing the client + } } $service_name = pick($::mongodb::globals::service_name, 'mongod') - $config = '/etc/mongod.conf' - $dbpath = '/var/lib/mongodb' - $logpath = '/var/log/mongodb/mongod.log' - $pidfilepath = '/var/run/mongodb/mongod.pid' - $bind_ip = pick($bind_ip, ['127.0.0.1']) - $fork = true + $config = '/etc/mongod.conf' + $dbpath = '/var/lib/mongodb' + $logpath = '/var/log/mongodb/mongod.log' + $pidfilepath = '/var/run/mongodb/mongod.pid' + $bind_ip = pick($::mongodb::globals::bind_ip, ['127.0.0.1']) + $fork = true } else { # RedHat/CentOS doesn't come with a prepacked mongodb # so we assume that you are using EPEL repository. - $user = pick($user, 'mongodb') - $group = pick($group, 'mongodb') - $server_package_name = pick($server_package_name, 'mongodb-server') - $client_package_name = pick($client_package_name, 'mongodb') - - $service_name = pick($service_name, 'mongod') + if ($::mongodb::globals::version == undef) { + $package_ensure = true + $package_ensure_client = true + } else { + $package_ensure = $::mongodb::globals::version + $package_ensure_client = $::mongodb::globals::version + } + $user = pick($::mongodb::globals::user, 'mongodb') + $group = pick($::mongodb::globals::group, 'mongodb') + $server_package_name = pick($::mongodb::globals::server_package_name, 'mongodb-server') + $client_package_name = pick($::mongodb::globals::client_package_name, 'mongodb') + $service_name = pick($::mongodb::globals::service_name, 'mongod') $config = '/etc/mongodb.conf' $dbpath = '/var/lib/mongodb' $logpath = '/var/log/mongodb/mongodb.log' - $bind_ip = pick($bind_ip, ['127.0.0.1']) + $bind_ip = pick($::mongodb::globals::bind_ip, ['127.0.0.1']) $pidfilepath = '/var/run/mongodb/mongodb.pid' $fork = true $journal = true } } 'Debian': { - if $mongodb::globals::manage_package_repo { - $user = pick($user, 'mongodb') - $group = pick($group, 'mongodb') - if $::mongodb::globals::version { - $server_package_name = pick("${::mongodb::globals::server_package_name}=${::mongodb::globals::version}", "mongodb-org-server-${::mongodb::globals::version}") - $client_package_name = pick("${::mongodb::globals::client_package_name}=${::mongodb::globals::version}", "mongodb-org-shell-${::mongodb::globals::version}") - } - else { + if $::mongodb::globals::manage_package_repo { + $user = pick($::mongodb::globals::user, 'mongodb') + $group = pick($::mongodb::globals::group, 'mongodb') + if ($::mongodb::globals::version == undef) { $server_package_name = pick($::mongodb::globals::server_package_name, 'mongodb-org-server') $client_package_name = pick($::mongodb::globals::client_package_name, 'mongodb-org-shell') + $package_ensure = true + $package_ensure_client = true + $service_name = pick($::mongodb::globals::service_name, 'mongod') + $config = '/etc/mongod.conf' + } else { + # check if the version is greater than 2.6 + if(versioncmp($::mongodb::globals::version, '2.6.0') >= 0) { + $server_package_name = pick($::mongodb::globals::server_package_name, 'mongodb-org-server') + $client_package_name = pick($::mongodb::globals::client_package_name, 'mongodb-org-shell') + $package_ensure = $::mongodb::globals::version + $package_ensure_client = $::mongodb::globals::version + $service_name = pick($::mongodb::globals::service_name, 'mongod') + $config = '/etc/mongod.conf' + } else { + $server_package_name = pick($::mongodb::globals::server_package_name, 'mongodb-10gen') + $client_package_name = pick($::mongodb::globals::client_package_name, 'mongodb-10gen') + $package_ensure = $::mongodb::globals::version + $package_ensure_client = $::mongodb::globals::version #this is still needed in case they are only installing the client + $service_name = pick($::mongodb::globals::service_name, 'mongodb') + $config = '/etc/mongodb.conf' + } } - $service_name = pick($::mongodb::globals::service_name, 'mongod') - $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongodb' $logpath = '/var/log/mongodb/mongodb.log' - $bind_ip = ['127.0.0.1'] + $bind_ip = pick($::mongodb::globals::bind_ip, ['127.0.0.1']) } else { # although we are living in a free world, # I would not recommend to use the prepacked # mongodb server on Ubuntu 12.04 or Debian 6/7, # because its really outdated - $user = pick($user, 'mongodb') - $group = pick($group, 'mongodb') - $server_package_name = pick($server_package_name, 'mongodb-server') - $client_package_name = $client_package_name - $service_name = pick($service_name, 'mongodb') + if ($::mongodb::globals::version == undef) { + $package_ensure = true + $package_ensure_client = true + } else { + $package_ensure = $::mongodb::globals::version + $package_ensure_client = $::mongodb::globals::version + } + $user = pick($::mongodb::globals::user, 'mongodb') + $group = pick($::mongodb::globals::group, 'mongodb') + $server_package_name = pick($::mongodb::globals::server_package_name, 'mongodb-server') + $client_package_name = $::mongodb::globals::client_package_name + $service_name = pick($::mongodb::globals::service_name, 'mongodb') $config = '/etc/mongodb.conf' $dbpath = '/var/lib/mongodb' $logpath = '/var/log/mongodb/mongodb.log' - $bind_ip = pick($bind_ip, ['127.0.0.1']) - $pidfilepath = undef + $bind_ip = pick($::mongodb::globals::bind_ip, ['127.0.0.1']) + $pidfilepath = $::mongodb::globals::pidfilepath } # avoid using fork because of the init scripts design $fork = undef diff --git a/mongodb/manifests/server.pp b/mongodb/manifests/server.pp index 90e785e65..32984a58c 100644 --- a/mongodb/manifests/server.pp +++ b/mongodb/manifests/server.pp @@ -15,7 +15,7 @@ $service_ensure = $mongodb::params::service_ensure, $service_status = $mongodb::params::service_status, - $package_ensure = $ensure, + $package_ensure = $mongodb::params::package_ensure, $package_name = $mongodb::params::server_package_name, $logpath = $mongodb::params::logpath, @@ -50,10 +50,13 @@ $mms_interval = undef, $replset = undef, $rest = undef, + $quiet = undef, $slowms = undef, $keyfile = undef, $set_parameter = undef, $syslog = undef, + + $config_content = undef, # Deprecated parameters $master = undef, diff --git a/mongodb/manifests/server/config.pp b/mongodb/manifests/server/config.pp index 2056c14d5..587f76de5 100644 --- a/mongodb/manifests/server/config.pp +++ b/mongodb/manifests/server/config.pp @@ -4,6 +4,7 @@ $user = $mongodb::server::user $group = $mongodb::server::group $config = $mongodb::server::config + $config_content = $mongodb::server::config_content $dbpath = $mongodb::server::dbpath $pidfilepath = $mongodb::server::pidfilepath @@ -39,6 +40,7 @@ $source = $mongodb::server::source $replset = $mongodb::server::replset $rest = $mongodb::server::rest + $quiet = $mongodb::server::quiet $slowms = $mongodb::server::slowms $keyfile = $mongodb::server::keyfile $bind_ip = $mongodb::server::bind_ip @@ -64,8 +66,17 @@ $noauth = true } + #Pick which config content to use + if $config_content { + $cfg_content = $config_content + } elsif (versioncmp($mongodb::globals::version, '2.6.0') >= 0) { + $cfg_content = template('mongodb/mongodb.conf.2.6.erb') + } else { + $cfg_content = template('mongodb/mongodb.conf.erb') + } + file { $config: - content => template('mongodb/mongodb.conf.erb'), + content => $cfg_content, owner => 'root', group => 'root', mode => '0644', diff --git a/mongodb/manifests/server/service.pp b/mongodb/manifests/server/service.pp index 3a714705e..93a448743 100644 --- a/mongodb/manifests/server/service.pp +++ b/mongodb/manifests/server/service.pp @@ -9,10 +9,9 @@ $port = $mongodb::server::port $service_ensure = $ensure ? { - present => true, absent => false, purged => false, - default => $ensure + default => true } service { 'mongodb': diff --git a/mongodb/metadata.json b/mongodb/metadata.json new file mode 100644 index 000000000..ca4ddb6d2 --- /dev/null +++ b/mongodb/metadata.json @@ -0,0 +1,44 @@ +{ + "name": "puppetlabs-mongodb", + "version": "0.9.0", + "author": "puppetlabs", + "summary": "Installs MongoDB on RHEL/Ubuntu/Debian.", + "license": "Apache License Version 2.0", + "source": "https://github.com/puppetlabs/puppetlabs-mongodb", + "project_page": "https://github.com/puppetlabs/puppetlabs-mongodb", + "issues_url": "https://tickets.puppetlabs.com/browse/MODULES", + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "5", + "6" + ] + }, + { + "operatingsystem": "CentOS", + "operatingsystemrelease": [ + "5", + "6" + ] + }, + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "6", + "7" + ] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "10.04", + "12.04" + ] + } + ], + "dependencies": [ + {"name":"puppetlabs/apt","version_requirement":">= 1.0.0"}, + {"name":"puppetlabs/stdlib","version_requirement":">= 2.2.0"} + ] +} diff --git a/mongodb/spec/unit/puppet/provider/mongodb_database/mongodb_spec.rb b/mongodb/spec/unit/puppet/provider/mongodb_database/mongodb_spec.rb index 91cbe8c5f..ff06b7ff9 100644 --- a/mongodb/spec/unit/puppet/provider/mongodb_database/mongodb_spec.rb +++ b/mongodb/spec/unit/puppet/provider/mongodb_database/mongodb_spec.rb @@ -2,6 +2,26 @@ describe Puppet::Type.type(:mongodb_database).provider(:mongodb) do + let(:raw_dbs) { + { + "databases" => [ + { + "name" => "admin", + "sizeOnDisk" => 83886080, + "empty" => false + }, { + "name" => "local", + "sizeOnDisk" => 83886080, + "empty" => false + } + ], + "totalSize" => 251658240, + "ok" => 1 + }.to_json + } + + let(:parsed_dbs) { %w(admin local) } + let(:resource) { Puppet::Type.type(:mongodb_database).new( { :ensure => :present, :name => 'new_database', @@ -11,24 +31,36 @@ let(:provider) { resource.provider } + before :each do + provider.class.stubs(:mongo_eval).with('printjson(db.getMongo().getDBs())').returns(raw_dbs) + end + + let(:instance) { provider.class.instances.first } + + describe 'self.instances' do + it 'returns an array of dbs' do + dbs = provider.class.instances.collect {|x| x.name } + expect(parsed_dbs).to match_array(dbs) + end + end + describe 'create' do it 'makes a database' do - provider.expects(:mongo) + provider.expects(:mongo_eval) provider.create end end describe 'destroy' do it 'removes a database' do - provider.expects(:mongo) + provider.expects(:mongo_eval) provider.destroy end end describe 'exists?' do it 'checks if database exists' do - provider.expects(:mongo).at_least(2).returns("db1,new_database,db2") - provider.exists?.should eql true + instance.exists? end end diff --git a/mongodb/spec/unit/puppet/provider/mongodb_user/mongodb_spec.rb b/mongodb/spec/unit/puppet/provider/mongodb_user/mongodb_spec.rb index 10d15daa9..f2a90598b 100644 --- a/mongodb/spec/unit/puppet/provider/mongodb_user/mongodb_spec.rb +++ b/mongodb/spec/unit/puppet/provider/mongodb_user/mongodb_spec.rb @@ -1,7 +1,16 @@ require 'spec_helper' +require 'json' describe Puppet::Type.type(:mongodb_user).provider(:mongodb) do + let(:raw_users) do + [ + { '_id' => 'admin.root', 'user' => 'root', 'db' => 'admin', 'credentials' => { 'MONGODB-CR' => 'pass' }, 'roles' => [ { 'role' => 'role2', 'db' => 'admin' }, { 'role' => 'role1', 'db' => 'admin' } ] } + ].to_json + end + + let(:parsed_users) { %w(root) } + let(:resource) { Puppet::Type.type(:mongodb_user).new( { :ensure => :present, :name => 'new_user', @@ -14,52 +23,97 @@ let(:provider) { resource.provider } + before :each do + provider.class.stubs(:mongo_eval).with('printjson(db.system.users.find().toArray())').returns(raw_users) + provider.class.stubs(:mongo_version).returns('2.6.x') + end + + let(:instance) { provider.class.instances.first } + + describe 'self.instances' do + it 'returns an array of users' do + usernames = provider.class.instances.collect {|x| x.username } + expect(parsed_users).to match_array(usernames) + end + end + describe 'create' do it 'creates a user' do - provider.expects(:mongo) + user = { + :user => 'new_user', + :pwd => 'pass', + :customData => { :createdBy => "Puppet Mongodb_user['new_user']" }, + :roles => ['role1','role2'], + } + + + provider.expects(:mongo_eval).with("db.createUser(#{user.to_json})", 'new_database') provider.create end end describe 'destroy' do it 'removes a user' do - provider.expects(:mongo) + provider.expects(:mongo_eval).with("db.dropUser('new_user')") provider.destroy end end describe 'exists?' do it 'checks if user exists' do - provider.expects(:mongo).at_least(2).returns("1") - provider.exists?.should eql true + provider.exists?.should eql false end end describe 'password_hash' do it 'returns a password_hash' do - provider.expects(:mongo).returns("pass\n") - provider.password_hash.should == "pass" + instance.password_hash.should == "pass" end end describe 'password_hash=' do it 'changes a password_hash' do - provider.expects(:mongo) + cmd = { + :updateUser => 'new_user', + :pwd => 'pass', + :digestPassword => false + } + provider.expects(:mongo_eval). + with("db.runCommand(#{cmd.to_json})", 'new_database') provider.password_hash=("newpass") end end describe 'roles' do it 'returns a sorted roles' do - provider.expects(:mongo).returns("role2,role1\n") - provider.roles.should == ['role1','role2'] + instance.roles.should == ['role1', 'role2'] end end describe 'roles=' do - it 'changes a roles' do - provider.expects(:mongo) - provider.roles=(['role3','role4']) + it 'changes nothing' do + provider.expects(:mongo_eval).times(0) + provider.roles=(['role1', 'role2']) + end + + it 'grant a role' do + provider.expects(:mongo_eval).with("db.getSiblingDB('new_database').grantRolesToUser('new_user', [\"role3\"])") + provider.roles=(['role1', 'role2', 'role3']) + end + + it 'revokes a role' do + provider.expects(:mongo_eval). + with("db.getSiblingDB('new_database').revokeRolesFromUser('new_user', [\"role1\"])") + provider.roles=(['role2']) + end + + it 'exchanges a role' do + provider.expects(:mongo_eval). + with("db.getSiblingDB('new_database').revokeRolesFromUser('new_user', [\"role1\"])") + provider.expects(:mongo_eval). + with("db.getSiblingDB('new_database').grantRolesToUser('new_user', [\"role3\"])") + + provider.roles=(['role2', 'role3']) end end diff --git a/mongodb/templates/mongodb.conf.2.6.erb b/mongodb/templates/mongodb.conf.2.6.erb new file mode 100644 index 000000000..fe6182210 --- /dev/null +++ b/mongodb/templates/mongodb.conf.2.6.erb @@ -0,0 +1,121 @@ +# mongo.conf - generated from Puppet + +# System Log + +<% if @logpath -%> +systemLog.path: <%= @logpath %> +systemLog.destination: file +<% if @logappend -%> +systemLog.logAppend: <%= @logappend %> +<% end -%> +<% elsif @syslog -%> +systemLog.destination: syslog +<% end -%> +<% if @verbose -%> +systemLog.quiet: false +<% else -%> +systemLog.quiet: true +<% end -%> +<% if @verbositylevel == "v" -%> +systemLog.verbosity: 1 +<% elsif @verbositylevel == "vv" -%> +systemLog.verbosity: 2 +<% elsif @verbositylevel == "vvv" -%> +systemLog.verbosity: 3 +<% elsif @verbositylevel == "vvvv" -%> +systemLog.verbosity: 4 +<% elsif @verbositylevel == "vvvvv" -%> +systemLog.verbosity: 5 +<% end -%> + +#Process Management +<% if @fork -%> +processManagement.fork: <%= @fork %> +<% end -%> +<% if @pidfilepath -%> +processManagement.pidFilePath: <%= @pidfilepath %> +<% end -%> + +#Storage +storage.dbPath: <%= @dbpath %> +<% if @nojournal -%> +storage.journal.enabled: false +<% elsif @journal -%> +storage.journal.enabled: true +<% end -%> +<% if @noprealloc -%> +storage.preallocDataFiles: <%= @noprealloc %> +<% end -%> +<% if @nssize -%> +storage.nsSize: <%= @nssize %> +<% end -%> +<% if @directoryperdb -%> +storage.directoryPerDB: <%= @directoryperdb %> +<% end -%> +<% if @smallfiles -%> +storage.smallFiles: <%= @smallfiles %> +<% end -%> +<% if @quota -%> +storage.quota.enforced: <%= @quota %> +<% if @quotafiles -%> +storage.quota.maxFilesPerDB: <%= @quotafiles %> +<% end -%> +<% end -%> + + +#Security +<% if @auth -%> +security.authorization: enabled +<% else -%> +security.authorization: disabled +<% end -%> +<% if @keyfile -%> +security.keyFile: <%= @keyfile %> +<% end -%> +<% if @noscripting -%> +security.javascriptEnabled: <%= @noscripting %> +<% end -%> + + +# Net +<% if @bind_ip -%> +net.bindIp: <%= Array(@bind_ip).join(',') %> +<% end -%> +net.port: <%= @port %> +<% if @objcheck -%> +net.wireObjectCheck: <%= @objcheck %> +<% end -%> +<% if @rest -%> +net.http.RESTInterfaceEnabled: true +<% end -%> +<% if @maxconns -%> +net.maxIncomingConnections: <%= @maxconns %> +<% end -%> +<% if @nohttpinterface -%> +net.http.enabled: <%= @nohttpinterface %> +<% end -%> + +#Replication +<% if @replset -%> +replication.replSetName: <%= @replset %> +<% end -%> +<% if @oplog_size -%> +replication.oplogSizeMB: <%= @oplog_size %> +<% end -%> + +#Operation Profiling +<% if @profile == "0" -%> +operationProfiling.mode: off +<% elsif @profile == "1" -%> +operationProfiling.mode: slowOp +<% elsif @profile == "2" -%> +operationProfiling.mode: all +<% end -%> +<% if @slowms -%> +operationProfiling.slowOpThresholdMs: <%= @slowms %> +<% end -%> + + +<% if @set_parameter -%> +setParameter: <%= @set_parameter %> +<% end -%> diff --git a/mongodb/templates/mongodb.conf.erb b/mongodb/templates/mongodb.conf.erb index 8e6dea0c9..f6328b474 100644 --- a/mongodb/templates/mongodb.conf.erb +++ b/mongodb/templates/mongodb.conf.erb @@ -167,3 +167,6 @@ setParameter = <%= @set_parameter %> <% if @syslog -%> syslog = <%= @syslog %> <% end -%> +<% if @quiet -%> +quiet = <%= @quiet %> +<% end -%> diff --git a/mongodb/tests/client.pp b/mongodb/tests/client.pp new file mode 100644 index 000000000..ca1cc0d7b --- /dev/null +++ b/mongodb/tests/client.pp @@ -0,0 +1,2 @@ +class { 'mongodb::globals': manage_package_repo => true }-> +class { 'mongodb::client': }