Add auth and remote connections support to MongoDB
Add options to provide admin user login and password to be used while managing databases and users. Admin user should have at least permissions 'root' and 'restore'. If there is no admin user mongo will work in 'localhost exception' mode allowing administration from the local interface. Closes-Bug: 1354494 Change-Id: I253ee50523fba66586e7a42a7f0772adebe96e83
This commit is contained in:
parent
bce9efc948
commit
21e1efbe9c
61
deployment/puppet/mongodb/lib/puppet/provider/common.rb
Normal file
61
deployment/puppet/mongodb/lib/puppet/provider/common.rb
Normal file
@ -0,0 +1,61 @@
|
||||
module MongoCommon
|
||||
|
||||
def mongo_local(cmd, database = @resource[:admin_database], username = @resource[:admin_username], password = @resource[:admin_password])
|
||||
mongo_cmd = [
|
||||
@resource[:mongo_path],
|
||||
'--quiet',
|
||||
'--eval',
|
||||
cmd,
|
||||
database,
|
||||
]
|
||||
output = Puppet::Util::Execution.execute(mongo_cmd, :failonfail => false, :combine => false)
|
||||
rc = $?.exitstatus
|
||||
Puppet.debug "Local Mongo: #{cmd} -> #{rc}: #{output}"
|
||||
[output, rc]
|
||||
end
|
||||
|
||||
def mongo_remote(cmd, database = @resource[:admin_database], username = @resource[:admin_username], password = @resource[:admin_password])
|
||||
mongo_cmd = [
|
||||
@resource[:mongo_path],
|
||||
'--username',
|
||||
username,
|
||||
'--password',
|
||||
password,
|
||||
'--host',
|
||||
@resource[:admin_host],
|
||||
'--port',
|
||||
@resource[:admin_port],
|
||||
'--quiet',
|
||||
'--eval',
|
||||
cmd,
|
||||
database,
|
||||
]
|
||||
output = Puppet::Util::Execution.execute(mongo_cmd, :failonfail => false, :combine => false)
|
||||
rc = $?.exitstatus
|
||||
Puppet.debug "Remote Mongo: #{cmd} -> #{rc}: #{output}"
|
||||
[output, rc]
|
||||
end
|
||||
|
||||
def mongo(cmd, database = @resource[:admin_database], username = @resource[:admin_username], password = @resource[:admin_password])
|
||||
output, rc = mongo_remote(cmd, database,username,password)
|
||||
return output if rc == 0
|
||||
output, rc = mongo_local(cmd, database,username,password)
|
||||
return output if rc == 0
|
||||
raise Puppet::ExecutionFailure, output
|
||||
end
|
||||
|
||||
def block_until_mongodb(tries = 10)
|
||||
begin
|
||||
mongo('db.getMongo()')
|
||||
rescue => e
|
||||
debug('MongoDB server not ready, retrying')
|
||||
sleep 2
|
||||
if (tries -= 1) > 0
|
||||
retry
|
||||
else
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -1,32 +1,26 @@
|
||||
Puppet::Type.type(:mongodb_database).provide(:mongodb) do
|
||||
|
||||
require File.join(File.dirname(__FILE__), '..', 'common.rb')
|
||||
desc "Manages MongoDB database."
|
||||
|
||||
defaultfor :kernel => 'Linux'
|
||||
|
||||
commands :mongo => 'mongo'
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
include MongoCommon
|
||||
|
||||
def create
|
||||
mongo(@resource[:name], '--quiet', '--eval', "db.dummyData.insert({\"created_by_puppet\": 1})")
|
||||
Puppet.debug "mongo_database: #{@resource[:name]} create"
|
||||
mongo('db.dummyData.insert({"created_by_puppet": 1})', @resource[:name])
|
||||
end
|
||||
|
||||
def destroy
|
||||
mongo(@resource[:name], '--quiet', '--eval', 'db.dropDatabase()')
|
||||
Puppet.debug "mongo_database: #{@resource[:name]} destroy"
|
||||
mongo('db.dropDatabase()', @resource[:name])
|
||||
end
|
||||
|
||||
def exists?
|
||||
Puppet.debug "mongo_database: '#{@resource[:name]}' exists?"
|
||||
block_until_mongodb(@resource[:tries])
|
||||
mongo("--quiet", "--eval", 'db.getMongo().getDBNames()').split(",").include?(@resource[:name])
|
||||
current_databases = mongo('db.getMongo().getDBNames()').strip.split(',')
|
||||
exists = current_databases.include?(@resource[:name])
|
||||
Puppet.debug "mongo_database: '#{@resource[:name]}' all: #{current_databases.inspect} '#{@resource[:name]}' exists? #{exists}"
|
||||
exists
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,48 +1,49 @@
|
||||
Puppet::Type.type(:mongodb_user).provide(:mongodb) do
|
||||
|
||||
require File.join(File.dirname(__FILE__), '..', 'common.rb')
|
||||
desc "Manage users for a MongoDB database."
|
||||
|
||||
defaultfor :kernel => 'Linux'
|
||||
|
||||
commands :mongo => 'mongo'
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
include MongoCommon
|
||||
|
||||
def create
|
||||
mongo(@resource[:database], '--eval', "db.system.users.insert({user:\"#{@resource[:name]}\", pwd:\"#{@resource[:password_hash]}\", roles: #{@resource[:roles].inspect}})")
|
||||
Puppet.debug "mongodb_user: #{@resource[:name]} database '#{@resource[:database]}' create"
|
||||
mongo("db.getMongo().getDB('#{@resource[:database]}').system.users.insert({user:'#{@resource[:name]}', pwd:'#{@resource[:password_hash]}', roles: #{@resource[:roles].inspect}})")
|
||||
end
|
||||
|
||||
def destroy
|
||||
mongo(@resource[:database], '--quiet', '--eval', "db.removeUser(\"#{@resource[:name]}\")")
|
||||
Puppet.debug "mongodb_user: #{@resource[:name]} database '#{@resource[:database]}' destroy"
|
||||
mongo("db.getMongo().getDB('#{@resource[:database]}').removeUser('#{@resource[:name]}')")
|
||||
end
|
||||
|
||||
def exists?
|
||||
Puppet.debug "mongodb_user: '#{@resource[:name]}' database '#{@resource[:database]}' exists?"
|
||||
block_until_mongodb(@resource[:tries])
|
||||
mongo(@resource[:database], '--quiet', '--eval', "db.system.users.find({user:\"#{@resource[:name]}\"}).count()").strip.eql?('1')
|
||||
exists = mongo("db.getMongo().getDB('#{@resource[:database]}').system.users.find({user:'#{@resource[:name]}'}).count()").strip.to_i > 0
|
||||
Puppet.debug "mongodb_user: '#{@resource[:name]}' database '#{@resource[:database]}' exists? #{exists}"
|
||||
exists
|
||||
end
|
||||
|
||||
def password_hash
|
||||
mongo(@resource[:database], '--quiet', '--eval', "db.system.users.findOne({user:\"#{@resource[:name]}\"})[\"pwd\"]").strip
|
||||
Puppet.debug "mongodb_user: '#{@resource[:name]}' database '#{@resource[:database]}' password_hash get"
|
||||
hash = mongo("db.getMongo().getDB('#{@resource[:database]}').system.users.findOne({user:'#{@resource[:name]}'})['pwd']").strip
|
||||
Puppet.debug "mongodb_user: '#{@resource[:name]}' database '#{@resource[:database]}' password_hash: #{hash}"
|
||||
hash
|
||||
end
|
||||
|
||||
def password_hash=(value)
|
||||
mongo(@resource[:database], '--quiet', '--eval', "db.system.users.update({user:\"#{@resource[:name]}\"}, { $set: {pwd:\"#{value}\"}})")
|
||||
Puppet.debug "mongodb_user: '#{@resource[:name]}' database '#{@resource[:database]}' password_hash set #{value.inspect}"
|
||||
mongo("db.getMongo().getDB('#{@resource[:database]}').system.users.update({user:'#{@resource[:name]}'}, { $set: {pwd:'#{value}'}})")
|
||||
end
|
||||
|
||||
def roles
|
||||
mongo(@resource[:database], '--quiet', '--eval', "db.system.users.findOne({user:\"#{@resource[:name]}\"})[\"roles\"]").strip.split(",").sort
|
||||
Puppet.debug "mongodb_user: '#{@resource[:name]}' database '#{@resource[:database]}' roles get"
|
||||
roles = mongo("db.getMongo().getDB('#{@resource[:database]}').system.users.findOne({user:'#{@resource[:name]}'})['roles']").strip.split(',').sort
|
||||
Puppet.debug "mongodb_user: '#{@resource[:name]}' roles: #{roles.inspect}"
|
||||
roles
|
||||
end
|
||||
|
||||
def roles=(value)
|
||||
mongo(@resource[:database], '--quiet', '--eval', "db.system.users.update({user:\"#{@resource[:name]}\"}, { $set: {roles: #{@resource[:roles].inspect}}})")
|
||||
Puppet.debug "mongodb_user: '#{@resource[:name]}' database '#{@resource[:database]}' roles set #{value.inspect}"
|
||||
mongo("db.getMongo().getDB('#{@resource[:database]}').system.users.update({user:'#{@resource[:name]}'}, { $set: {roles: #{@resource[:roles].inspect}}})")
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -8,6 +8,35 @@ Puppet::Type.newtype(:mongodb_database) do
|
||||
newvalues(/^\w+$/)
|
||||
end
|
||||
|
||||
newparam(:admin_username) do
|
||||
desc "Administrator user login"
|
||||
defaultto 'admin'
|
||||
end
|
||||
|
||||
newparam(:admin_password) do
|
||||
desc "Administrator user password"
|
||||
end
|
||||
|
||||
newparam(:admin_host) do
|
||||
desc "Connect to this host as an admin user"
|
||||
defaultto 'localhost'
|
||||
end
|
||||
|
||||
newparam(:admin_port) do
|
||||
desc "Connect to this port as an admin user"
|
||||
defaultto '27017'
|
||||
end
|
||||
|
||||
newparam(:admin_database) do
|
||||
desc "Connect to this database as an admin user"
|
||||
defaultto 'admin'
|
||||
end
|
||||
|
||||
newparam(:mongo_path) do
|
||||
desc "Path to mongo binary"
|
||||
defaultto '/usr/bin/mongo'
|
||||
end
|
||||
|
||||
newparam(:tries) do
|
||||
desc "The maximum amount of two second tries to wait MongoDB startup."
|
||||
defaultto 10
|
||||
@ -17,4 +46,11 @@ Puppet::Type.newtype(:mongodb_database) do
|
||||
end
|
||||
end
|
||||
|
||||
autorequire(:package) do
|
||||
'mongodb'
|
||||
end
|
||||
|
||||
autorequire(:service) do
|
||||
'mongodb'
|
||||
end
|
||||
end
|
||||
|
@ -13,6 +13,35 @@ Puppet::Type.newtype(:mongodb_user) do
|
||||
desc "The name of the user."
|
||||
end
|
||||
|
||||
newparam(:admin_username) do
|
||||
desc "Administrator user login"
|
||||
defaultto 'admin'
|
||||
end
|
||||
|
||||
newparam(:admin_password) do
|
||||
desc "Administrator user password"
|
||||
end
|
||||
|
||||
newparam(:admin_host) do
|
||||
desc "Connect to this host as an admin user"
|
||||
defaultto 'localhost'
|
||||
end
|
||||
|
||||
newparam(:admin_port) do
|
||||
desc "Connect to this port as an admin user"
|
||||
defaultto '27017'
|
||||
end
|
||||
|
||||
newparam(:mongo_path) do
|
||||
desc "Path to mongo binary"
|
||||
defaultto '/usr/bin/mongo'
|
||||
end
|
||||
|
||||
newparam(:admin_database) do
|
||||
desc "Connect to this database as an admin user"
|
||||
defaultto 'admin'
|
||||
end
|
||||
|
||||
newparam(:database) do
|
||||
desc "The user's target database."
|
||||
defaultto do
|
||||
@ -53,4 +82,11 @@ Puppet::Type.newtype(:mongodb_user) do
|
||||
newvalue(/^\w+$/)
|
||||
end
|
||||
|
||||
autorequire(:package) do
|
||||
'mongodb'
|
||||
end
|
||||
|
||||
autorequire(:service) do
|
||||
'mongodb'
|
||||
end
|
||||
end
|
||||
|
@ -16,12 +16,20 @@ define mongodb::db (
|
||||
$password = false,
|
||||
$roles = ['dbAdmin'],
|
||||
$tries = 10,
|
||||
$admin_username = undef,
|
||||
$admin_password = undef,
|
||||
$admin_host = undef,
|
||||
$admin_database = undef,
|
||||
) {
|
||||
|
||||
mongodb_database { $name:
|
||||
ensure => present,
|
||||
tries => $tries,
|
||||
require => Class['mongodb::server'],
|
||||
admin_username => $admin_username,
|
||||
admin_password => $admin_password,
|
||||
admin_host => $admin_host,
|
||||
admin_database => $admin_database,
|
||||
require => Class['mongodb::server'],
|
||||
}
|
||||
|
||||
if $password_hash {
|
||||
@ -29,7 +37,7 @@ define mongodb::db (
|
||||
} elsif $password {
|
||||
$hash = mongodb_password($user, $password)
|
||||
} else {
|
||||
fail("Parameter 'password_hash' or 'password' should be provided.")
|
||||
fail("Parameter 'password_hash' or 'password' should be provided to mongodb::db.")
|
||||
}
|
||||
|
||||
mongodb_user { $user:
|
||||
@ -37,6 +45,10 @@ define mongodb::db (
|
||||
password_hash => $hash,
|
||||
database => $name,
|
||||
roles => $roles,
|
||||
admin_username => $admin_username,
|
||||
admin_password => $admin_password,
|
||||
admin_host => $admin_host,
|
||||
admin_database => $admin_database,
|
||||
require => Mongodb_database[$name],
|
||||
}
|
||||
|
||||
|
@ -12,9 +12,6 @@ class openstack::mongo (
|
||||
$use_syslog = true,
|
||||
) {
|
||||
|
||||
# notify {"MongoDB params: $ceilometer_user $ceilometer_database $ceilometer_db_password": }
|
||||
|
||||
|
||||
class {'::mongodb::client':
|
||||
} ->
|
||||
|
||||
@ -30,14 +27,32 @@ class openstack::mongo (
|
||||
user => $ceilometer_user,
|
||||
password => $ceilometer_db_password,
|
||||
roles => ['readWrite', 'dbAdmin', 'dbOwner'],
|
||||
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' ],
|
||||
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',
|
||||
}
|
||||
|
||||
#notify {"mongo: $ceilometer_db_password": }
|
||||
|
||||
}
|
||||
|
@ -48,11 +48,10 @@ class openstack::mongo_primary (
|
||||
mongodb::db { $ceilometer_database:
|
||||
user => $ceilometer_user,
|
||||
password => $ceilometer_db_password,
|
||||
roles => [
|
||||
'readWrite',
|
||||
'dbAdmin',
|
||||
'dbOwner'
|
||||
],
|
||||
roles => [ 'readWrite', 'dbAdmin', 'dbOwner' ],
|
||||
admin_username => 'admin',
|
||||
admin_password => $ceilometer_db_password,
|
||||
admin_database => 'admin',
|
||||
} ->
|
||||
|
||||
mongodb::db { 'admin':
|
||||
@ -70,8 +69,12 @@ class openstack::mongo_primary (
|
||||
'clusterManager',
|
||||
'clusterMonitor',
|
||||
'hostManager',
|
||||
'root'
|
||||
'root',
|
||||
'restore',
|
||||
],
|
||||
admin_username => 'admin',
|
||||
admin_password => $ceilometer_db_password,
|
||||
admin_database => 'admin',
|
||||
} ->
|
||||
|
||||
notify {"mongodb primary finished": }
|
||||
|
Loading…
Reference in New Issue
Block a user