Adapt synced puppetlabs-mongodb module for Fuel usage

Key moments:
    * Adds Support for Keyfile Key:
      upstream commit 7bbcff8024152b4ec9ce53dbba00024523707162
    * Remove useless openstack::mongo class
    * Add upstream changes for 217 pull request
      (https://github.com/puppetlabs/puppetlabs-mongodb/pull/217):
      - Implement retries for MongoDB shell commands
      - Initiate replica set creation from localhost if auth is enabled
    * Improve support for MongoDB authentication
      https://github.com/puppetlabs/puppetlabs-mongodb/pull/194
    * Fix lint errors (actually fixed in upstream)
    * Add noop tests for MongoDB parameters

  Implements: blueprint upgrade-openstack-puppet-modules

  Closes-bug: #1383639
  Related-bug: #1308990

Change-Id: I3b9cbd35bf46483782d7b7eb7ef030fd31fdd544
This commit is contained in:
iberezovskiy 2015-06-17 13:27:58 +03:00
parent 0ddb3a999a
commit ceeb76af18
25 changed files with 520 additions and 217 deletions

View File

@ -371,6 +371,10 @@ Default: 100 ms
Specify the path to a key file to store authentication information. This option
is only useful for the connection between replica set members. Default: None
#####`key`
Specify the key contained within the keyfile. This option
is only useful for the connection between replica set members. Default: None
#####`master`
Set to true to configure the current instance to act as master instance in a
replication configuration. Default: False *Note*: deprecated use replica sets

View File

@ -29,6 +29,8 @@ class Puppet::Provider::Mongodb < Puppet::Provider
# Mongo Command Wrapper
def self.mongo_eval(cmd, db = 'admin')
retry_count = 10
retry_sleep = 3
if mongorc_file
cmd = mongorc_file + cmd
end
@ -50,7 +52,23 @@ class Puppet::Provider::Mongodb < Puppet::Provider
port = config['port']
end
out = mongo([db, '--quiet', '--port', port, '--eval', cmd])
run_command = [db, '--quiet', '--port', port, '--eval', cmd]
out = nil
retry_count.times do |n|
begin
out = mongo(run_command)
rescue => e
debug "Request failed: '#{e.message}' Retry: '#{n}'"
sleep retry_sleep
next
end
break
end
if !out
fail "Could not evalute MongoDB shell command: #{cmd}"
end
out.gsub!(/ObjectId\(([^)]*)\)/, '\1')
out

View File

@ -85,6 +85,10 @@ Puppet::Type.type(:mongodb_replset).provide(:mongo) do
mongo_command("rs.remove(\"#{host}\")", master)
end
def auth_enabled
@resource[:auth_enabled]
end
def master_host(hosts)
hosts.each do |host|
status = db_ismaster(host)
@ -161,6 +165,7 @@ Puppet::Type.type(:mongodb_replset).provide(:mongo) do
end
def alive_members(hosts)
alive = []
hosts.select do |host|
begin
Puppet.debug "Checking replicaset member #{host} ..."
@ -168,6 +173,11 @@ Puppet::Type.type(:mongodb_replset).provide(:mongo) do
if status.has_key?('errmsg') and status['errmsg'] == 'not running with --replSet'
raise Puppet::Error, "Can't configure replicaset #{self.name}, host #{host} is not supposed to be part of a replicaset."
end
if auth_enabled and status.has_key?('errmsg') and (status['errmsg'].include? "unauthorized" or status['errmsg'].include? "not authorized")
Puppet.warning "Host #{host} is available, but you are unauthorized because of authentication is enabled: #{auth_enabled}"
alive.push(host)
end
if status.has_key?('set')
if status['set'] != self.name
raise Puppet::Error, "Can't configure replicaset #{self.name}, host #{host} is already part of another replicaset."
@ -175,17 +185,17 @@ Puppet::Type.type(:mongodb_replset).provide(:mongo) do
# This node is alive and supposed to be a member of our set
Puppet.debug "Host #{self.name} is available for replset #{status['set']}"
true
alive.push(host)
elsif status.has_key?('info')
Puppet.debug "Host #{self.name} is alive but unconfigured: #{status['info']}"
true
alive.push(host)
end
rescue Puppet::ExecutionFailure
Puppet.warning "Can't connect to replicaset member #{host}."
false
end
end
alive
end
def set_members
@ -241,10 +251,17 @@ Puppet::Type.type(:mongodb_replset).provide(:mongo) do
end
def mongo_command(command, host, retries=4)
self.class.mongo_command(command,host,retries)
self.class.mongo_command(command,host,retries, auth_enabled)
end
def self.mongo_command(command, host=nil, retries=4)
def self.mongo_command(command, host=nil, retries=4, auth_enabled=false)
if auth_enabled and command.include? "rs.initiate"
# We can't setup replica from any hosts except localhost
# if authentication is enabled
# User can't be created before replica set initialization
# So we can't use user credentials for auth
host = '127.0.0.1'
end
# Allow waiting for mongod to become ready
# Wait for 2 seconds initially and double the delay at each retry
wait = 2

View File

@ -17,6 +17,11 @@ Puppet::Type.newtype(:mongodb_replset) do
desc "The name of the replicaSet"
end
newparam(:auth_enabled) do
desc "Check authentication enabled"
defaultto false
end
newproperty(:members, :array_matching => :all) do
desc "The replicaSet members"

View File

@ -20,9 +20,9 @@ class mongodb::client::install {
if $package_name {
package { 'mongodb_client':
ensure => $my_package_ensure,
name => $package_name,
tag => 'mongodb',
ensure => $my_package_ensure,
name => $package_name,
tag => 'mongodb',
}
}
}

View File

@ -19,9 +19,9 @@ define mongodb::db (
) {
mongodb_database { $name:
ensure => present,
tries => $tries,
require => Class['mongodb::server'],
ensure => 'present',
tries => $tries,
require => Class['mongodb::server'],
}
if $password_hash {

View File

@ -79,6 +79,7 @@ class mongodb (
$quiet = undef,
$slowms = undef,
$keyfile = undef,
$key = undef,
$bind_ip = undef,
$pidfilepath = undef
) inherits mongodb::params {
@ -135,6 +136,7 @@ class mongodb (
quiet => $quiet,
slowms => $slowms,
keyfile => $keyfile,
key => $key,
bind_ip => $bind_ip,
pidfilepath => $pidfilepath,
}

View File

@ -24,8 +24,8 @@ class mongodb::mongos::install (
if !defined(Package[$package_name]) {
package { 'mongodb_mongos':
ensure => $my_package_ensure,
name => $package_name,
ensure => $my_package_ensure,
name => $package_name,
}
}

View File

@ -5,6 +5,8 @@ class mongodb::params inherits mongodb::globals {
$service_enable = pick($mongodb::globals::service_enable, true)
$service_ensure = pick($mongodb::globals::service_ensure, 'running')
$service_status = $mongodb::globals::service_status
$store_creds = true
$rcfile = "${::root_home}/.mongorc.js"
$mongos_service_enable = pick($mongodb::globals::mongos_service_enable, true)
$mongos_service_ensure = pick($mongodb::globals::mongos_service_ensure, 'running')

View File

@ -8,6 +8,7 @@ class mongodb::server (
$config = $mongodb::params::config,
$dbpath = $mongodb::params::dbpath,
$pidfilepath = $mongodb::params::pidfilepath,
$rcfile = $mongodb::params::rcfile,
$service_provider = $mongodb::params::service_provider,
$service_name = $mongodb::params::service_name,
@ -29,6 +30,11 @@ class mongodb::server (
$cpu = undef,
$auth = false,
$noauth = undef,
$create_admin = false,
$admin_username = undef,
$admin_password = undef,
$admin_roles = ['dbAdmin', 'dbOwner', 'userAdmin', 'userAdminAnyDatabase'],
$store_creds = $mongodb::params::store_creds,
$verbose = undef,
$verbositylevel = undef,
$objcheck = undef,
@ -55,6 +61,7 @@ class mongodb::server (
$quiet = undef,
$slowms = undef,
$keyfile = undef,
$key = undef,
$set_parameter = undef,
$syslog = undef,
$config_content = undef,
@ -87,4 +94,24 @@ class mongodb::server (
class { 'mongodb::server::install': }->
anchor { 'mongodb::server::end': }
}
if $create_admin {
mongodb_user { $admin_username:
ensure => present,
username => $admin_username,
password_hash => mongodb_password($admin_username, $admin_password),
database => 'admin',
roles => $admin_roles,
tries => 10,
tag => 'admin'
}
if $replset {
# You can't create users before replica set initialization
Class['mongodb::replset'] -> Mongodb_user <| tag == 'admin' |>
}
# Make sure admin user created first
Mongodb_user <| tag == 'admin' |> -> Mongodb_user <| tag != 'admin' |>
}
}

View File

@ -18,6 +18,11 @@ class mongodb::server::config {
$cpu = $mongodb::server::cpu
$auth = $mongodb::server::auth
$noath = $mongodb::server::noauth
$create_admin = $mongodb::server::create_admin
$admin_username = $mongodb::server::admin_username
$admin_password = $mongodb::server::admin_password
$store_creds = $mongodb::server::store_creds
$rcfile = $mongodb::server::rcfile
$verbose = $mongodb::server::verbose
$verbositylevel = $mongodb::server::verbositylevel
$objcheck = $mongodb::server::objcheck
@ -45,6 +50,7 @@ class mongodb::server::config {
$quiet = $mongodb::server::quiet
$slowms = $mongodb::server::slowms
$keyfile = $mongodb::server::keyfile
$key = $mongodb::server::key
$bind_ip = $mongodb::server::bind_ip
$directoryperdb = $mongodb::server::directoryperdb
$profile = $mongodb::server::profile
@ -66,6 +72,14 @@ class mongodb::server::config {
# Exists for future compatibility and clarity.
if $auth {
$noauth = false
if $keyfile {
file { $keyfile:
content => inline_template($key),
owner => $user,
group => $group,
mode => '0400',
}
}
}
else {
$noauth = true
@ -105,4 +119,18 @@ class mongodb::server::config {
ensure => absent
}
}
if $store_creds {
file { $rcfile:
ensure => present,
content => template('mongodb/mongorc.js.erb'),
owner => 'root',
group => 'root',
mode => '0644'
}
} else {
file { $rcfile:
ensure => absent
}
}
}

View File

@ -27,8 +27,8 @@ class mongodb::server::install {
}
package { 'mongodb_server':
ensure => $my_package_ensure,
name => $package_name,
tag => 'mongodb',
ensure => $my_package_ensure,
name => $package_name,
tag => 'mongodb',
}
}

View File

@ -39,7 +39,7 @@ class mongodb::server::service {
}
if $service_ensure {
mongodb_conn_validator { "mongodb":
mongodb_conn_validator { 'mongodb':
server => $bind_ip,
port => $port_real,
timeout => '240',

View File

@ -3,7 +3,7 @@ require 'spec_helper'
describe 'mongodb::server::config', :type => :class do
describe 'with preseted variables' do
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' }", "include mongodb::server"]}
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $rcfile = '/root/.mongorc.js' }", "include mongodb::server"]}
it {
should contain_file('/etc/mongod.conf')
@ -12,7 +12,7 @@ describe 'mongodb::server::config', :type => :class do
end
describe 'with default values' do
let(:pre_condition) {[ "class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $ensure = present $user = 'mongod' $group = 'mongod' $port = 29017 $bind_ip = ['0.0.0.0'] $fork = true $logpath ='/var/log/mongo/mongod.log' $logappend = true }", "include mongodb::server" ]}
let(:pre_condition) {[ "class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $rcfile = '/root/.mongorc.js' $store_creds = true $ensure = present $user = 'mongod' $group = 'mongod' $port = 29017 $bind_ip = ['0.0.0.0'] $fork = true $logpath ='/var/log/mongo/mongod.log' $logappend = true }", "include mongodb::server" ]}
it {
should contain_file('/etc/mongod.conf').with({
@ -27,11 +27,18 @@ describe 'mongodb::server::config', :type => :class do
should contain_file('/etc/mongod.conf').with_content(/^logappend=true/)
should contain_file('/etc/mongod.conf').with_content(/^logpath=\/var\/log\/mongo\/mongod\.log/)
should contain_file('/etc/mongod.conf').with_content(/^fork=true/)
is_expected.to contain_file('/root/.mongorc.js').with({
'ensure' => 'present',
'owner' => 'root',
'group' => 'root',
'mode' => '0644'
})
}
end
describe 'with absent ensure' do
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $ensure = absent }", "include mongodb::server"]}
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $rcfile = '/root/.mongorc.js' $ensure = absent }", "include mongodb::server"]}
it {
should contain_file('/etc/mongod.conf').with({ :ensure => 'absent' })
@ -40,7 +47,7 @@ describe 'mongodb::server::config', :type => :class do
end
describe 'with specific bind_ip values' do
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $ensure = present $bind_ip = ['127.0.0.1', '10.1.1.13']}", "include mongodb::server"]}
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $rcfile = '/root/.mongorc.js' $ensure = present $bind_ip = ['127.0.0.1', '10.1.1.13'] }", "include mongodb::server"]}
it {
should contain_file('/etc/mongod.conf').with_content(/bind_ip\s=\s127\.0\.0\.1\,10\.1\.1\.13/)
@ -48,15 +55,15 @@ describe 'mongodb::server::config', :type => :class do
end
describe 'when specifying auth to true' do
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $auth = true $dbpath = '/var/lib/mongo' $ensure = present }", "include mongodb::server"]}
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $auth = true $dbpath = '/var/lib/mongo' $rcfile = '/root/.mongorc.js' $ensure = present }", "include mongodb::server"]}
it {
should contain_file('/etc/mongod.conf').with_content(/^auth=true/)
}
end
describe 'when specifying set_parameter value' do
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $set_parameter = 'textSearchEnable=true' $dbpath = '/var/lib/mongo' $ensure = present }", "include mongodb::server"]}
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $set_parameter = 'textSearchEnable=true' $dbpath = '/var/lib/mongo' $rcfile = '/root/.mongorc.js' $ensure = present }", "include mongodb::server"]}
it {
should contain_file('/etc/mongod.conf').with_content(/^setParameter = textSearchEnable=true/)
@ -65,7 +72,7 @@ describe 'mongodb::server::config', :type => :class do
describe 'with journal:' do
context 'on true with i686 architecture' do
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $ensure = present $journal = true }", "include mongodb::server"]}
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $rcfile = '/root/.mongorc.js' $ensure = present $journal = true }", "include mongodb::server"]}
let (:facts) { { :architecture => 'i686' } }
it {
@ -85,7 +92,7 @@ describe 'mongodb::server::config', :type => :class do
end
context 'true and with quotafiles' do
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $ensure = present $quota = true $quotafiles = 1 }", "include mongodb::server"]}
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $rcfile = '/root/.mongorc.js' $ensure = present $quota = true $quotafiles = 1 }", "include mongodb::server"]}
it {
should contain_file('/etc/mongod.conf').with_content(/quota = true/)
@ -96,7 +103,7 @@ describe 'mongodb::server::config', :type => :class do
describe 'when specifying syslog value' do
context 'it should be set to true' do
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $ensure = present $syslog = true }", "include mongodb::server"]}
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $rcfile = '/root/.mongorc.js' $ensure = present $syslog = true }", "include mongodb::server"]}
it {
should contain_file('/etc/mongod.conf').with_content(/^syslog = true/)
@ -104,7 +111,7 @@ describe 'mongodb::server::config', :type => :class do
end
context 'if logpath is also set an error should be raised' do
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $ensure = present $syslog = true $logpath ='/var/log/mongo/mongod.log' }", "include mongodb::server"]}
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $rcfile = '/root/.mongorc.js' $ensure = present $syslog = true $logpath ='/var/log/mongo/mongod.log' }", "include mongodb::server"]}
it {
expect { should contain_file('/etc/mongod.conf') }.to raise_error(Puppet::Error, /You cannot use syslog with logpath/)
@ -113,4 +120,14 @@ describe 'mongodb::server::config', :type => :class do
end
describe 'with store_creds' do
context 'false' do
let(:pre_condition) { ["class mongodb::server { $config = '/etc/mongod.conf' $dbpath = '/var/lib/mongo' $rcfile = '/root/.mongorc.js' $ensure = present $store_creds = false }", "include mongodb::server"]}
it {
is_expected.to contain_file('/root/.mongorc.js').with_ensure('absent')
}
end
end
end

View File

@ -9,8 +9,39 @@ describe 'mongodb::server' do
end
context 'with defaults' do
it { should contain_class('mongodb::server::install') }
it { should contain_class('mongodb::server::config') }
it { is_expected.to compile.with_all_deps }
it { is_expected.to contain_class('mongodb::server::install').
that_comes_before('Class[mongodb::server::config]') }
it { is_expected.to contain_class('mongodb::server::config').
that_comes_before('Class[mongodb::server::service]') }
it { is_expected.to contain_class('mongodb::server::service') }
end
context 'with create_admin => true' do
let(:params) do
{
:create_admin => true,
:admin_username => 'admin',
:admin_password => 'password'
}
end
it { is_expected.to compile.with_all_deps }
it { is_expected.to contain_class('mongodb::server::install').
that_comes_before('Class[mongodb::server::config]') }
it { is_expected.to contain_class('mongodb::server::config').
that_comes_before('Class[mongodb::server::service]') }
it { is_expected.to contain_class('mongodb::server::service') }
it {
is_expected.to contain_mongodb_user('admin').with({
'username' => 'admin',
'ensure' => 'present',
'database' => 'admin',
'roles' => ['dbAdmin', 'dbOwner', 'userAdmin', 'userAdminAnyDatabase'],
'tries' => 10,
'tag' => 'admin'
})
}
end
context 'when deploying on Solaris' do
@ -20,4 +51,4 @@ describe 'mongodb::server' do
it { expect { should raise_error(Puppet::Error) } }
end
end
end

View File

@ -0,0 +1,24 @@
function authRequired() {
try {
if (db.serverCmdLineOpts().code == 13) {
return true;
}
return false;
}
catch (err) {
return false;
}
}
if (authRequired()) {
try {
var prev_db = db
db = db.getSiblingDB('admin')
db.auth('<%= @admin_username %>', '<%= @admin_password %>')
db = db.getSiblingDB(prev_db)
}
catch (err) {
// This isn't catching authentication errors as I'd expect...
return;
}
}

View File

@ -1,69 +0,0 @@
# == Class: openstack::mongo
class openstack::mongo (
$ceilometer_database = "ceilometer",
$ceilometer_user = "ceilometer",
$ceilometer_metering_secret = undef,
$ceilometer_db_password = "ceilometer",
$ceilometer_metering_secret = "ceilometer",
$mongodb_port = 27017,
$mongodb_bind_address = ['0.0.0.0'],
$use_syslog = true,
$verbose = false,
$debug = false,
) {
if $debug {
$set_parameter = 'logLevel=2'
$quiet = false
} else {
$set_parameter = 'logLevel=0'
$quiet = true
}
class {'::mongodb::client':
} ->
class {'::mongodb::server':
port => $mongodb_port,
verbose => $verbose,
use_syslog => $use_syslog,
bind_ip => $mongodb_bind_address,
auth => true,
set_parameter => $set_parameter,
quiet => $quiet,
} ->
mongodb::db { $ceilometer_database:
user => $ceilometer_user,
password => $ceilometer_db_password,
roles => ['readWrite', 'dbAdmin'],
admin_username => 'admin',
admin_password => $ceilometer_db_password,
admin_database => 'admin',
} ->
mongodb::db { 'admin':
user => 'admin',
password => $ceilometer_db_password,
roles => [
'userAdmin',
'readWrite',
'dbAdmin',
'dbAdminAnyDatabase',
'readAnyDatabase',
'readWriteAnyDatabase',
'userAdminAnyDatabase',
'clusterAdmin',
'clusterManager',
'clusterMonitor',
'hostManager',
'root',
'restore',
],
admin_username => 'admin',
admin_password => $ceilometer_db_password,
admin_database => 'admin',
}
}

View File

@ -1,92 +1,113 @@
# == Class: openstack::mongo_primary
class openstack::mongo_primary (
$ceilometer_database = "ceilometer",
$ceilometer_user = "ceilometer",
$ceilometer_metering_secret = undef,
$ceilometer_db_password = "ceilometer",
$ceilometer_metering_secret = "ceilometer",
$ceilometer_replset_members = ['mongo2', 'mongo3'],
$mongodb_bind_address = ['0.0.0.0'],
$mongodb_port = 27017,
$use_syslog = true,
$verbose = false,
$debug = false,
$replset = undef,
$auth = true,
$ceilometer_database = "ceilometer",
$ceilometer_user = "ceilometer",
$ceilometer_metering_secret = undef,
$ceilometer_db_password = "ceilometer",
$ceilometer_metering_secret = "ceilometer",
$ceilometer_replset_members = ['127.0.0.1'],
$mongodb_bind_address = ['127.0.0.1'],
$mongodb_port = 27017,
$use_syslog = true,
$verbose = false,
$debug = false,
$logappend = true,
$journal = true,
$replset_name = 'ceilometer',
$keyfile = '/etc/mongodb.key',
$key = undef,
$oplog_size = '10240',
$fork = false,
$directoryperdb = true,
$profile = "1",
$dbpath = '/var/lib/mongo/mongodb',
$mongo_version = undef,
) {
if $debug {
$set_parameter = 'logLevel=2'
$quiet = false
$verbositylevel = "vv"
} else {
$set_parameter = 'logLevel=0'
$quiet = true
$verbositylevel = "v"
}
if size($ceilometer_replset_members) > 0 {
$replset_setup = true
$keyfile = '/etc/mongodb.key'
if $use_syslog {
$logpath = false
} else {
$replset_setup = false
$keyfile = undef
# undef to use defaults
$logpath = undef
}
if $key {
$key_content = $key
} else {
$key_content = file('/var/lib/astute/mongodb/mongodb.key')
}
class {'::mongodb::globals':
version => $mongo_version,
} ->
notify {"MongoDB params: $mongodb_bind_address" :} ->
class {'::mongodb::client':
} ->
class {'::mongodb::server':
port => $mongodb_port,
verbose => $verbose,
use_syslog => $use_syslog,
bind_ip => $mongodb_bind_address,
auth => true,
replset => $replset,
keyfile => $keyfile,
set_parameter => $set_parameter,
quiet => $quiet,
package_ensure => true,
port => $mongodb_port,
verbose => $verbose,
verbositylevel => $verbositylevel,
syslog => $use_syslog,
logpath => $logpath,
logappend => $logappend,
journal => $journal,
bind_ip => $mongodb_bind_address,
auth => $auth,
replset => $replset_name,
keyfile => $keyfile,
key => $key_content,
directoryperdb => $directoryperdb,
fork => $fork,
profile => $profile,
oplog_size => $oplog_size,
dbpath => $dbpath,
config_content => $config_content,
create_admin => true,
admin_username => 'admin',
admin_password => $ceilometer_db_password,
admin_roles => ['userAdmin', 'readWrite', 'dbAdmin',
'dbAdminAnyDatabase', 'readAnyDatabase',
'readWriteAnyDatabase', 'userAdminAnyDatabase',
'clusterAdmin', 'clusterManager', 'clusterMonitor',
'hostManager', 'root', 'restore'],
} ->
class {'::mongodb::replset':
replset_setup => $replset_setup,
replset_members => $ceilometer_replset_members,
} ->
notify {"mongodb configuring databases" :} ->
notify {"mongodb configuring ceilometer database" :} ->
mongodb::db { $ceilometer_database:
user => $ceilometer_user,
password => $ceilometer_db_password,
roles => [ 'readWrite', 'dbAdmin' ],
admin_username => 'admin',
admin_password => $ceilometer_db_password,
admin_database => 'admin',
} ->
mongodb::db { 'admin':
user => 'admin',
password => $ceilometer_db_password,
roles => [
'userAdmin',
'readWrite',
'dbAdmin',
'dbAdminAnyDatabase',
'readAnyDatabase',
'readWriteAnyDatabase',
'userAdminAnyDatabase',
'clusterAdmin',
'clusterManager',
'clusterMonitor',
'hostManager',
'root',
'restore',
],
admin_username => 'admin',
admin_password => $ceilometer_db_password,
admin_database => 'admin',
user => $ceilometer_user,
password => $ceilometer_db_password,
roles => [ 'readWrite', 'dbAdmin' ],
} ->
notify {"mongodb primary finished": }
if $replset_name and is_string($replset_name) {
mongodb_conn_validator { 'check_alive':
server => $ceilometer_replset_members,
port => $mongodb_port,
}
$members = suffix($ceilometer_replset_members, inline_template(":<%= @mongodb_port %>"))
$sets = { "${replset_name}" => { auth_enabled => $auth, members => $members } }
class {'::mongodb::replset':
sets => $sets,
}
Class['::mongodb::server'] -> Mongodb_conn_validator['check_alive'] -> Mongodb::Db["$ceilometer_database"]
}
}

View File

@ -1,40 +1,78 @@
# == Class: openstack::mongo_secondary
class openstack::mongo_secondary (
$ceilometer_database = "ceilometer",
$ceilometer_user = "ceilometer",
$ceilometer_metering_secret = undef,
$ceilometer_db_password = "ceilometer",
$ceilometer_metering_secret = "ceilometer",
$mongodb_port = 27017,
$mongodb_bind_address = ['0.0.0.0'],
$replset = undef,
$use_syslog = true,
$verbose = false,
$debug = false,
$auth = true,
$ceilometer_database = "ceilometer",
$ceilometer_user = "ceilometer",
$ceilometer_metering_secret = undef,
$ceilometer_db_password = "ceilometer",
$ceilometer_metering_secret = "ceilometer",
$mongodb_bind_address = ['127.0.0.1'],
$mongodb_port = 27017,
$use_syslog = true,
$verbose = false,
$debug = false,
$logappend = true,
$journal = true,
$replset_name = undef,
$keyfile = '/etc/mongodb.key',
$key = undef,
$oplog_size = '10240',
$fork = false,
$directoryperdb = true,
$profile = "1",
$dbpath = '/var/lib/mongo/mongodb',
$mongo_version = undef,
) {
if $debug {
$set_parameter = 'logLevel=2'
$quiet = false
$verbositylevel = "vv"
} else {
$set_parameter = 'logLevel=0'
$quiet = true
$verbositylevel = "v"
}
if $use_syslog {
$logpath = false
} else {
# undef to use defaults
$logpath = undef
}
if $key {
$key_content = $key
} else {
$key_content = file('/var/lib/astute/mongodb/mongodb.key')
}
class {'::mongodb::globals':
version => $mongo_version,
} ->
notify {"MongoDB params: $mongodb_bind_address": } ->
class {'::mongodb::client':
} ->
class {'::mongodb::server':
port => $mongodb_port,
verbose => $verbose,
use_syslog => $use_syslog,
bind_ip => $mongodb_bind_address,
replset => $replset,
auth => true,
keyfile => '/etc/mongodb.key',
set_parameter => $set_parameter,
quiet => $quiet,
package_ensure => true,
port => $mongodb_port,
verbose => $verbose,
verbositylevel => $verbositylevel,
syslog => $use_syslog,
logpath => $logpath,
logappend => $logappend,
journal => $journal,
bind_ip => $mongodb_bind_address,
auth => $auth,
replset => $replset_name,
keyfile => $keyfile,
key => $key_content,
directoryperdb => $directoryperdb,
fork => $fork,
profile => $profile,
oplog_size => $oplog_size,
dbpath => $dbpath,
config_content => $config_content,
create_admin => false,
}
}

View File

@ -0,0 +1,43 @@
module Puppet::Parser::Functions
newfunction(:mongo_hosts, :type => :rvalue, :doc => <<-EOS
Return a comma-separated list of hosts with roles 'primary-mongo' and 'mongo'
Argument1: $nodes_hash, mandatory argument
Argument2: 'array' or 'string' Return values as an array or a string? Default: string
Argument3: roles to select, primary-mongo and mongo by default
Returns: a string of ips, separated by a comma
EOS
) do |args|
nodes = args[0]
type = args[1] || 'string'
roles = args[2] || %w(primary-mongo mongo)
roles = Array(roles) unless roles.is_a?(Array)
unless nodes.is_a?(Array) && nodes.any? && nodes.first.is_a?(Hash) && nodes.first['uid']
raise Puppet::ParseError, 'You should provide $nodes_hash as the first argument of this fuction! It should be an array of hashes with node information.'
end
unless %w(array string).include? type
raise Puppet::ParseError, 'Type should be either array or string!'
end
unless roles.any?
raise Puppet::ParseError, 'You should give at list one role to filter!'
end
hosts = []
roles.each do |r|
nodes.inject(hosts) do |h,n|
h.push(n['internal_address']) if (n['role'] == r) && n['internal_address']
h
end
end
if type == 'string'
hosts.join(',')
else
hosts
end
end
end

View File

@ -71,12 +71,10 @@ if $ceilometer_hash['enabled'] {
$mongo_replicaset = undef
}
} else {
$mongo_hosts = mongo_hosts($nodes_hash, 'string', $mongo_roles )
if size(mongo_hosts($nodes_hash, 'array', $mongo_roles)) > 1 {
$mongo_replicaset = 'ceilometer'
} else {
$mongo_replicaset = undef
}
$mongo_nodes = mongo_hosts($nodes_hash, 'array')
$mongo_hosts = join($mongo_nodes, ',')
# MongoDB is alsways configured with replica set
$mongo_replicaset = 'ceilometer'
}
}

View File

@ -5,14 +5,21 @@ $debug = hiera('debug', false)
$internal_address = hiera('internal_address')
$nodes_hash = hiera('nodes', {})
$roles = node_roles($nodes_hash, hiera('uid'))
$replset_name = 'ceilometer'
####################################################################
firewall {'120 mongodb':
port => $mongodb_port,
proto => 'tcp',
action => 'accept',
} ->
class { 'openstack::mongo_secondary':
mongodb_bind_address => [ '127.0.0.1', $internal_address ],
use_syslog => $use_syslog,
debug => $debug,
replset => 'ceilometer',
mongodb_bind_address => [ '127.0.0.1', $internal_address ],
use_syslog => $use_syslog,
mongo_version => '2.6.10',
debug => $debug,
replset_name => $replset_name,
}
if !(member($roles, 'controller') or member($roles, 'primary-controller')) {

View File

@ -6,23 +6,24 @@ $internal_address = hiera('internal_address')
$ceilometer_hash = hiera('ceilometer')
$nodes_hash = hiera('nodes')
$roles = node_roles($nodes_hash, hiera('uid'))
$replset_name = 'ceilometer'
####################################################################
if size(mongo_hosts($nodes_hash, 'array', 'mongo')) > 1 {
$replset = 'ceilometer'
}
else {
$replset = undef
}
firewall {'120 mongodb':
port => $mongodb_port,
proto => 'tcp',
action => 'accept',
} ->
class { 'openstack::mongo_primary':
mongodb_bind_address => [ '127.0.0.1', $internal_address ],
ceilometer_metering_secret => $ceilometer_hash['metering_secret'],
ceilometer_db_password => $ceilometer_hash['db_password'],
ceilometer_replset_members => mongo_hosts($nodes_hash, 'array', 'mongo'),
replset => $replset,
use_syslog => $use_syslog,
debug => $debug,
mongodb_bind_address => [ '127.0.0.1', $internal_address ],
ceilometer_metering_secret => $ceilometer_hash['metering_secret'],
ceilometer_db_password => $ceilometer_hash['db_password'],
ceilometer_replset_members => mongo_hosts($nodes_hash, 'array'),
replset_name => $replset_name,
mongo_version => '2.6.10',
use_syslog => $use_syslog,
debug => $debug,
}
if !(member($roles, 'controller') or member($roles, 'primary-controller')) {

View File

@ -1,5 +1,6 @@
require 'spec_helper'
require 'shared-examples'
manifest = 'roles/mongo_primary.pp'
describe manifest do
@ -10,6 +11,52 @@ describe manifest do
end
end
shared_examples 'catalog' do
debug = Noop.hiera 'debug'
use_syslog = Noop.hiera 'use_syslog'
ceilometer_hash = Noop.hiera_structure 'ceilometer'
nodes_hash = Noop.hiera_structure 'nodes'
it 'should configure MongoDB only with replica set' do
should contain_class('mongodb::server').with('replset' => 'ceilometer')
end
it 'should configure MongoDB with authentication enabled' do
should contain_class('mongodb::server').with('auth' => 'true')
end
it 'should configure verbosity level for MongoDB' do
if debug
should contain_class('mongodb::server').with('verbositylevel' => 'vv')
else
should contain_class('mongodb::server').with('verbositylevel' => 'v')
end
end
it 'should create keyfile for replica setup' do
should contain_class('mongodb::server').with('keyfile' => '/etc/mongodb.key')
end
it 'should not write logs to file if syslog is enabled' do
if use_syslog
should contain_class('mongodb::server').with('logpath' => 'false')
end
end
it 'should configure oplog size for local database' do
should contain_class('mongodb::server').with('oplog_size' => '10240')
end
it 'should capture data regarding performance' do
should contain_class('mongodb::server').with('profile' => '1')
end
it 'should store each database in separate directory' do
should contain_class('mongodb::server').with('directoryperdb' => 'true')
end
end
test_ubuntu_and_centos manifest
end

View File

@ -11,10 +11,52 @@ describe manifest do
end
shared_examples 'catalog' do
it do
should contain_file('/etc/mongodb.key').with_content('key')
debug = Noop.hiera 'debug'
use_syslog = Noop.hiera 'use_syslog'
ceilometer_hash = Noop.hiera_structure 'ceilometer'
nodes_hash = Noop.hiera_structure 'nodes'
it 'should configure MongoDB only with replica set' do
should contain_class('mongodb::server').with('replset' => 'ceilometer')
end
it 'should configure MongoDB with authentication enabled' do
should contain_class('mongodb::server').with('auth' => 'true')
end
it 'should configure verbosity level for MongoDB' do
if debug
should contain_class('mongodb::server').with('verbositylevel' => 'vv')
else
should contain_class('mongodb::server').with('verbositylevel' => 'v')
end
end
it 'should create keyfile for replica setup' do
should contain_class('mongodb::server').with('keyfile' => '/etc/mongodb.key')
end
it 'should not write logs to file if syslog is enabled' do
if use_syslog
should contain_class('mongodb::server').with('logpath' => 'false')
end
end
it 'should configure oplog size for local database' do
should contain_class('mongodb::server').with('oplog_size' => '10240')
end
it 'should capture data regarding performance' do
should contain_class('mongodb::server').with('profile' => '1')
end
it 'should store each database in separate directory' do
should contain_class('mongodb::server').with('directoryperdb' => 'true')
end
end
test_ubuntu_and_centos manifest
end