Merge pull request #46597 from terminalmage/fix-divergent-mongodb-states

Revert PR 41278
This commit is contained in:
Nicole Thomas 2018-03-19 22:02:37 -04:00 committed by GitHub
commit e1ade5dbb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 497 deletions

View File

@ -90,7 +90,7 @@ def _to_dict(objects):
def db_list(user=None, password=None, host=None, port=None, authdb=None):
'''
List all Mongodb databases
List all MongoDB databases
CLI Example:
@ -112,7 +112,7 @@ def db_list(user=None, password=None, host=None, port=None, authdb=None):
def db_exists(name, user=None, password=None, host=None, port=None, authdb=None):
'''
Checks if a database exists in Mongodb
Checks if a database exists in MongoDB
CLI Example:
@ -130,7 +130,7 @@ def db_exists(name, user=None, password=None, host=None, port=None, authdb=None)
def db_remove(name, user=None, password=None, host=None, port=None, authdb=None):
'''
Remove a Mongodb database
Remove a MongoDB database
CLI Example:
@ -207,7 +207,7 @@ def user_find(name, user=None, password=None, host=None, port=None,
def user_list(user=None, password=None, host=None, port=None, database='admin', authdb=None):
'''
List users of a Mongodb database
List users of a MongoDB database
CLI Example:
@ -248,7 +248,7 @@ def user_list(user=None, password=None, host=None, port=None, database='admin',
def user_exists(name, user=None, password=None, host=None, port=None,
database='admin', authdb=None):
'''
Checks if a user exists in Mongodb
Checks if a user exists in MongoDB
CLI Example:
@ -271,7 +271,7 @@ def user_exists(name, user=None, password=None, host=None, port=None,
def user_create(name, passwd, user=None, password=None, host=None, port=None,
database='admin', authdb=None, roles=None):
'''
Create a Mongodb user
Create a MongoDB user
CLI Example:
@ -299,7 +299,7 @@ def user_create(name, passwd, user=None, password=None, host=None, port=None,
def user_remove(name, user=None, password=None, host=None, port=None,
database='admin', authdb=None):
'''
Remove a Mongodb user
Remove a MongoDB user
CLI Example:
@ -325,7 +325,7 @@ def user_remove(name, user=None, password=None, host=None, port=None,
def user_roles_exists(name, roles, database, user=None, password=None, host=None,
port=None, authdb=None):
'''
Checks if a user of a Mongodb database has specified roles
Checks if a user of a MongoDB database has specified roles
CLI Examples:
@ -363,7 +363,7 @@ def user_roles_exists(name, roles, database, user=None, password=None, host=None
def user_grant_roles(name, roles, database, user=None, password=None, host=None,
port=None, authdb=None):
'''
Grant one or many roles to a Mongodb user
Grant one or many roles to a MongoDB user
CLI Examples:
@ -398,7 +398,7 @@ def user_grant_roles(name, roles, database, user=None, password=None, host=None,
def user_revoke_roles(name, roles, database, user=None, password=None, host=None,
port=None, authdb=None):
'''
Revoke one or many roles to a Mongodb user
Revoke one or many roles to a MongoDB user
CLI Examples:

View File

@ -1,435 +0,0 @@
# -*- coding: utf-8 -*-
'''
Management of Mongodb users and databases
=========================================
.. note::
This module requires PyMongo to be installed.
'''
# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals
# Define the module's virtual name
__virtualname__ = 'mongodb'
def __virtual__():
if 'mongodb.user_exists' not in __salt__:
return False
return __virtualname__
def database_absent(name,
user=None,
password=None,
host=None,
port=None,
authdb=None):
'''
Ensure that the named database is absent. Note that creation doesn't make sense in MongoDB.
name
The name of the database to remove
user
The user to connect as (must be able to create the user)
password
The password of the user
host
The host to connect to
port
The port to connect to
authdb
The database in which to authenticate
'''
ret = {'name': name,
'changes': {},
'result': True,
'comment': ''}
#check if database exists and remove it
if __salt__['mongodb.db_exists'](name, user, password, host, port, authdb=authdb):
if __opts__['test']:
ret['result'] = None
ret['comment'] = ('Database {0} is present and needs to be removed'
).format(name)
return ret
if __salt__['mongodb.db_remove'](name, user, password, host, port, authdb=authdb):
ret['comment'] = 'Database {0} has been removed'.format(name)
ret['changes'][name] = 'Absent'
return ret
# fallback
ret['comment'] = ('User {0} is not present, so it cannot be removed'
).format(name)
return ret
def user_present(name,
passwd,
database="admin",
user=None,
password=None,
host="localhost",
port=27017,
authdb=None):
'''
Ensure that the user is present with the specified properties
name
The name of the user to manage
passwd
The password of the user to manage
user
MongoDB user with sufficient privilege to create the user
password
Password for the admin user specified with the ``user`` parameter
host
The hostname/IP address of the MongoDB server
port
The port on which MongoDB is listening
database
The database in which to create the user
.. note::
If the database doesn't exist, it will be created.
authdb
The database in which to authenticate
Example:
.. code-block:: yaml
mongouser-myapp:
mongodb.user_present:
- name: myapp
- passwd: password-of-myapp
# Connect as admin:sekrit
- user: admin
- password: sekrit
'''
ret = {'name': name,
'changes': {},
'result': True,
'comment': 'User {0} is already present'.format(name)}
# Check for valid port
try:
port = int(port)
except TypeError:
ret['result'] = False
ret['comment'] = 'Port ({0}) is not an integer.'.format(port)
return ret
# check if user exists
user_exists = __salt__['mongodb.user_exists'](name, user, password, host, port, database, authdb)
if user_exists is True:
return ret
# if the check does not return a boolean, return an error
# this may be the case if there is a database connection error
if not isinstance(user_exists, bool):
ret['comment'] = user_exists
ret['result'] = False
return ret
if __opts__['test']:
ret['result'] = None
ret['comment'] = ('User {0} is not present and needs to be created'
).format(name)
return ret
# The user is not present, make it!
if __salt__['mongodb.user_create'](name, passwd, user, password, host, port, database=database, authdb=authdb):
ret['comment'] = 'User {0} has been created'.format(name)
ret['changes'][name] = 'Present'
else:
ret['comment'] = 'Failed to create database {0}'.format(name)
ret['result'] = False
return ret
def user_absent(name,
user=None,
password=None,
host=None,
port=None,
database="admin",
authdb=None):
'''
Ensure that the named user is absent
name
The name of the user to remove
user
MongoDB user with sufficient privilege to create the user
password
Password for the admin user specified by the ``user`` parameter
host
The hostname/IP address of the MongoDB server
port
The port on which MongoDB is listening
database
The database from which to remove the user specified by the ``name``
parameter
authdb
The database in which to authenticate
'''
ret = {'name': name,
'changes': {},
'result': True,
'comment': ''}
#check if user exists and remove it
user_exists = __salt__['mongodb.user_exists'](name, user, password, host, port, database=database, authdb=authdb)
if user_exists is True:
if __opts__['test']:
ret['result'] = None
ret['comment'] = ('User {0} is present and needs to be removed'
).format(name)
return ret
if __salt__['mongodb.user_remove'](name, user, password, host, port, database=database, authdb=authdb):
ret['comment'] = 'User {0} has been removed'.format(name)
ret['changes'][name] = 'Absent'
return ret
# if the check does not return a boolean, return an error
# this may be the case if there is a database connection error
if not isinstance(user_exists, bool):
ret['comment'] = user_exists
ret['result'] = False
return ret
# fallback
ret['comment'] = ('User {0} is not present, so it cannot be removed'
).format(name)
return ret
def _roles_to_set(roles, database):
ret = set()
for r in roles:
if isinstance(r, dict):
if r['db'] == database:
ret.add(r['role'])
else:
ret.add(r)
return ret
def _user_roles_to_set(user_list, name, database):
ret = set()
for item in user_list:
if item['user'] == name:
ret = ret.union(_roles_to_set(item['roles'], database))
return ret
def user_grant_roles(name, roles,
database="admin",
user=None,
password=None,
host="localhost",
port=27017,
authdb=None):
'''
Ensure that the named user is granted certain roles
name
The name of the user to remove
roles
The roles to grant to the user
user
MongoDB user with sufficient privilege to create the user
password
Password for the admin user specified by the ``user`` parameter
host
The hostname/IP address of the MongoDB server
port
The port on which MongoDB is listening
database
The database from which to remove the user specified by the ``name``
parameter
authdb
The database in which to authenticate
'''
ret = {'name': name,
'changes': {},
'result': False,
'comment': ''}
if not isinstance(roles, (list, tuple)):
roles = [roles]
if not roles:
ret['result'] = True
ret['comment'] = "nothing to do (no roles given)"
return ret
# Check for valid port
try:
port = int(port)
except TypeError:
ret['result'] = False
ret['comment'] = 'Port ({0}) is not an integer.'.format(port)
return ret
# check if grant exists
user_roles_exists = __salt__['mongodb.user_roles_exists'](name, roles, database,
user=user, password=password, host=host, port=port, authdb=authdb)
if user_roles_exists is True:
ret['result'] = True
ret['comment'] = "Roles already assigned"
return ret
user_list = __salt__['mongodb.user_list'](database=database,
user=user, password=password, host=host, port=port, authdb=authdb)
user_set = _user_roles_to_set(user_list, name, database)
roles_set = _roles_to_set(roles, database)
diff = roles_set - user_set
if __opts__['test']:
ret['result'] = None
ret['comment'] = "Would have modified roles (missing: {0})".format(diff)
return ret
# The user is not present, make it!
if __salt__['mongodb.user_grant_roles'](name, roles, database,
user=user, password=password, host=host, port=port, authdb=authdb):
ret['comment'] = 'Granted roles to {0} on {1}'.format(name, database)
ret['changes'][name] = ['{0} granted'.format(i) for i in diff]
ret['result'] = True
else:
ret['comment'] = 'Failed to grant roles ({2}) to {0} on {1}'.format(name, database, diff)
return ret
def user_set_roles(name, roles,
database="admin",
user=None,
password=None,
host="localhost",
port=27017,
authdb=None):
'''
Ensure that the named user has the given roles and no other roles
name
The name of the user to remove
roles
The roles the given user should have
user
MongoDB user with sufficient privilege to create the user
password
Password for the admin user specified by the ``user`` parameter
host
The hostname/IP address of the MongoDB server
port
The port on which MongoDB is listening
database
The database from which to remove the user specified by the ``name``
parameter
authdb
The database in which to authenticate
'''
ret = {'name': name,
'changes': {},
'result': False,
'comment': ''}
if not isinstance(roles, (list, tuple)):
roles = [roles]
if not roles:
ret['result'] = True
ret['comment'] = "nothing to do (no roles given)"
return ret
# Check for valid port
try:
port = int(port)
except TypeError:
ret['result'] = False
ret['comment'] = 'Port ({0}) is not an integer.'.format(port)
return ret
user_list = __salt__['mongodb.user_list'](database=database,
user=user, password=password, host=host, port=port, authdb=authdb)
user_set = _user_roles_to_set(user_list, name, database)
roles_set = _roles_to_set(roles, database)
to_grant = list(roles_set - user_set)
to_revoke = list(user_set - roles_set)
if not to_grant and not to_revoke:
ret['result'] = True
ret['comment'] = "User {0} has the appropriate roles on {1}".format(name, database)
return ret
if __opts__['test']:
lsg = ', '.join(to_grant)
lsr = ', '.join(to_revoke)
ret['result'] = None
ret['comment'] = "Would have modified roles (grant: {0}; revoke: {1})".format(lsg, lsr)
return ret
ret['changes'][name] = changes = {}
if to_grant:
if not __salt__['mongodb.user_grant_roles'](name, to_grant, database,
user=user, password=password, host=host, port=port, authdb=authdb):
ret['comment'] = "failed to grant some or all of {0} to {1} on {2}".format(to_grant, name, database)
return ret
else:
changes['granted'] = list(to_grant)
if to_revoke:
if not __salt__['mongodb.user_revoke_roles'](name, to_revoke, database,
user=user, password=password, host=host, port=port, authdb=authdb):
ret['comment'] = "failed to revoke some or all of {0} to {1} on {2}".format(to_revoke, name, database)
return ret
else:
changes['revoked'] = list(to_revoke)
ret['result'] = True
return ret

View File

@ -1,14 +1,23 @@
# -*- coding: utf-8 -*-
'''
Management of Mongodb databases
Management of MongoDB Databases
===============================
Only deletion is supported, creation doesn't make sense
and can be done using mongodb_user.present
:depends: - pymongo Python module
Only deletion is supported, creation doesn't make sense and can be done using
:py:func:`mongodb_user.present <salt.states.mongodb_user.present>`.
'''
from __future__ import absolute_import, print_function, unicode_literals
import salt.utils.versions
# Define the module's virtual name
__virtualname__ = 'mongodb_database'
def __virtual__():
if 'mongodb.db_exists' in __salt__:
return __virtualname__
return False
def absent(name,
@ -18,10 +27,8 @@ def absent(name,
port=None,
authdb=None):
'''
.. deprecated:: Fluorine
Use ``mongodb.database_absent`` instead
Ensure that the named database is absent
Ensure that the named database is absent. Note that creation doesn't make
sense in MongoDB.
name
The name of the database to remove
@ -41,19 +48,11 @@ def absent(name,
authdb
The database in which to authenticate
'''
ret = {'name': name,
'changes': {},
'result': True,
'comment': ''}
salt.utils.versions.warn_until(
'Fluorine',
'The \'mongodb_database.absent\' function has been deprecated and will be removed in Salt '
'{version}. Please use \'mongodb.database_absent\' instead.'
)
#check if database exists and remove it
if __salt__['mongodb.db_exists'](name, user, password, host, port, authdb=authdb):
if __opts__['test']:
ret['result'] = None
@ -65,7 +64,5 @@ def absent(name,
ret['changes'][name] = 'Absent'
return ret
# fallback
ret['comment'] = ('User {0} is not present, so it cannot be removed'
).format(name)
ret['comment'] = 'Database {0} is not present'.format(name)
return ret

View File

@ -1,16 +1,12 @@
# -*- coding: utf-8 -*-
'''
Management of Mongodb users
Management of MongoDB Users
===========================
.. note::
This module requires PyMongo to be installed.
:depends: - pymongo Python module
'''
from __future__ import absolute_import, print_function, unicode_literals
import salt.utils.versions
# Define the module's virtual name
__virtualname__ = 'mongodb_user'
@ -31,9 +27,6 @@ def present(name,
authdb=None,
roles=None):
'''
.. deprecated:: Fluorine
Use ``mongodb.user_present`` instead
Ensure that the user is present with the specified properties
name
@ -84,13 +77,6 @@ def present(name,
- dbOwner
'''
salt.utils.versions.warn_until(
'Fluorine',
'The \'mongodb_user.present\' function has been deprecated and will be removed in Salt '
'{version}. Please use \'mongodb.user_present\' instead.'
)
ret = {'name': name,
'changes': {},
'result': True,
@ -167,9 +153,6 @@ def absent(name,
database="admin",
authdb=None):
'''
.. deprecated:: Fluorine
Use ``mongodb.user_absent`` instead
Ensure that the named user is absent
name
@ -194,13 +177,6 @@ def absent(name,
authdb
The database in which to authenticate
'''
salt.utils.versions.warn_until(
'Fluorine',
'The \'mongodb_user.absent\' function has been deprecated and will be removed in Salt '
'{version}. Please use \'mongodb.user_absent\' instead.'
)
ret = {'name': name,
'changes': {},
'result': True,
@ -227,6 +203,5 @@ def absent(name,
return ret
# fallback
ret['comment'] = ('User {0} is not present, so it cannot be removed'
).format(name)
ret['comment'] = 'User {0} is not present'.format(name)
return ret

View File

@ -56,7 +56,6 @@ class MongodbDatabaseTestCase(TestCase, LoaderModuleMockMixin):
'changes': {'mydb': 'Absent'}})
self.assertDictEqual(mongodb_database.absent(name), ret)
comt = ('User {0} is not present, so it cannot be removed'
.format(name))
comt = 'Database {0} is not present'.format(name)
ret.update({'comment': comt, 'changes': {}})
self.assertDictEqual(mongodb_database.absent(name), ret)

View File

@ -98,7 +98,6 @@ class MongodbUserTestCase(TestCase, LoaderModuleMockMixin):
'changes': {name: 'Absent'}})
self.assertDictEqual(mongodb_user.absent(name), ret)
comt = ('User {0} is not present, so it cannot be removed'
.format(name))
comt = 'User {0} is not present'.format(name)
ret.update({'comment': comt, 'result': True, 'changes': {}})
self.assertDictEqual(mongodb_user.absent(name), ret)