From d98864cc564187af3a98069c398bd85633978c86 Mon Sep 17 00:00:00 2001 From: Elliott Foster Date: Thu, 31 Jan 2013 08:48:58 -0600 Subject: [PATCH] Adding mongodb_user module. --- mongodb_user | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 mongodb_user diff --git a/mongodb_user b/mongodb_user new file mode 100644 index 00000000000..62115552412 --- /dev/null +++ b/mongodb_user @@ -0,0 +1,191 @@ +#!/usr/bin/python + +# (c) 2012, Elliott Foster +# Sponsored by Four Kitchens http://fourkitchens.com. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +DOCUMENTATION = ''' +--- +module: mongodb_user +short_description: Adds or removes a user from a MongoDB database. +description: + - Adds or removes a user from a MongoDB database. +version_added: "0.X" +options: + login_user: + description: + - The username used to authenticate with + required: false + default: null + login_password: + description: + - The password used to authenticate with + required: false + default: null + login_host: + description: + - The host running the database + required: false + default: localhost + login_port + description: + - The port to connect to + required: false + default: 27017 + database: + description: + - The name of the database to add/remove the user from + required: true + user: + description: + - The name of the user to add or remove + required: true + default: null + password: + description: + - The password to use for the user + required: false + default: null + state: + state: + description: + - The database user state + required: false + default: present + choices: [ "present", "absent" ] +examples: + - code: "mongodb_user: database=burgers name=bob password=12345 state=present" + description: Create 'burgers' database user with name 'bob' and password '12345'. + - code: "mongodb_user: database=burgers name=bob state=absent" + description: Delete 'burgers' database user with name 'bob'. + notes: + - Requires the pymongo Python package on teh remote host, version 2.4.2+. This + can be installed using pip. @see http://api.mongodb.org/python/current/installation.html +requirements: [ "pymongo" ] +author: Elliott Foster +''' + +import ConfigParser +try: + from pymongo import MongoClient + from pymongo.errors import ConnectionFailure + from pymongo.errors import OperationFailure +except ImportError: + pymongo_found = False +else: + pymongo_found = True + +# ========================================= +# MongoDB module specific support methods. +# + +def user_add(client, db_name, user, password): + try: + db = client[db_name] + db.add_user(user, password) + except OperationFailure: + return False + + + return True + +def user_remove(client, db_name, user): + try: + db = client[db_name] + db.remove_user(user) + except OperationFailure: + return False + + return True + +def load_mongocnf(): + config = ConfigParser.RawConfigParser() + mongocnf = os.path.expanduser('~/.mongodb.cnf') + if not os.path.exists(mongocnf): + return False + + try: + config.readfp(open(mongocnf)) + creds = dict( + user=config.get('client', 'user'), + password=config.get('client', 'pass') + ) + except (ConfigParser.NoOptionError, IOError): + return False + + return creds + +# ========================================= +# Module execution. +# + +def main(): + module = AnsibleModule( + argument_spec = dict( + login_user=dict(default=None), + login_password=dict(default=None), + login_host=dict(default='localhost'), + login_port=dict(default='27017'), + database=dict(required=True, aliases=['db']), + user=dict(required=True, aliases=['name']), + password=dict(aliases=['pass']), + state=dict(default='present', choices=['absent', 'present']), + ) + ) + + if not pymongo_found: + module.fail_json(msg='the python pymongo module is required') + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + db_name = module.params['database'] + user = module.params['user'] + password = module.params['password'] + state = module.params['state'] + + try: + client = MongoClient(login_host, int(login_port)) + if login_user is None and login_password is None: + mongocnf_creds = load_mongocnf() + if mongocnf_creds is not False: + login_user = mongocnf_creds['user'] + login_password = mongocnf_creds['password'] + elif login_password is None and login_user is not None: + module.fail_json(msg='when supplying login arguments, both login_user and login_password must be provided') + + if login_user is not None and login_password is not None: + client.admin.authenticate(login_user, login_password) + + except ConnectionFailure as e: + module.fail_json(msg='unable to connect to database, check login_user and login_password are correct') + + if state == 'present': + if password is None: + module.fail_json(msg='password parameter required when adding a user') + if user_add(client, db_name, user, password) is not True: + module.fail_json(msg='Unable to add or update user, check login_user and login_password are correct and that this user has access to the admin collection') + elif state == 'absent': + if user_remove(client, db_name, user) is not True: + module.fail_json(msg='Unable to remove user, check login_user and login_password are correct and that this user has access to the admin collection') + + module.exit_json(changed=True, user=user) + +# this is magic, see lib/ansible/module_common.py +#<> +main()