ansible/library/mysql_db
2012-09-29 16:15:52 +02:00

181 lines
5.8 KiB
Python
Executable file

#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2012, Mark Theunissen <mark.theunissen@gmail.com>
# 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 <http://www.gnu.org/licenses/>.
DOCUMENTATION = '''
---
module: mysql_db
short_description: Add or remove MySQL databases from a remote host.
description:
- Add or remove MySQL databases from a remote host.
version_added: "0.6"
options:
name:
description:
- name of the database to add or remove
required: true
default: null
login_user:
description:
- The username used to authenticate with
required: false
default: null
login_password:
description:
- The passwordused to authenticate with
required: false
default: null
login_host:
description:
- Host running the database
required: false
default: localhost
state:
description:
- The database state
required: false
default: present
choices: [ "present", "absent" ]
collation:
description:
- Collation mode
required: false
default: null
encoding:
description:
- Encoding mode
required: false
default: null
examples:
- code: mysql_db db=bobdata state=present
description: create a new database with name 'bobdata'
notes:
- Requires the MySQLdb Python package on the remote host. For Ubuntu, this is as easy as apt-get install python-mysqldb.
- Both 'login_password' and 'login_username' are required when you are passing credentials. If none are present, the module will attempt to read the credentials from ~/.my.cnf, and finally fall back to using the MySQL default login of 'root' with no password.
requirements: [ ConfigParser ]
author: Mark Theunissen
'''
import ConfigParser
try:
import MySQLdb
except ImportError:
mysqldb_found = False
else:
mysqldb_found = True
# ===========================================
# MySQL module specific support methods.
#
def db_exists(cursor, db):
res = cursor.execute("SHOW DATABASES LIKE %s", (db,))
return bool(res)
def db_delete(cursor, db):
query = "DROP DATABASE %s" % db
cursor.execute(query)
return True
def db_create(cursor, db, encoding, collation):
if encoding:
encoding = " CHARACTER SET %s" % encoding
if collation:
collation = " COLLATE %s" % collation
query = "CREATE DATABASE %s%s%s" % (db, encoding, collation)
res = cursor.execute(query)
return True
def load_mycnf():
config = ConfigParser.RawConfigParser()
mycnf = os.path.expanduser('~/.my.cnf')
if not os.path.exists(mycnf):
return False
try:
config.readfp(open(mycnf))
creds = dict(user=config.get('client', 'user'),passwd=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_unix_socket=dict(default=None),
db=dict(required=True, aliases=['name']),
encoding=dict(default=""),
collation=dict(default=""),
state=dict(default="present", choices=["absent", "present"]),
)
)
if not mysqldb_found:
module.fail_json(msg="the python mysqldb module is required")
db = module.params["db"]
encoding = module.params["encoding"]
collation = module.params["collation"]
state = module.params["state"]
# Either the caller passes both a username and password with which to connect to
# mysql, or they pass neither and allow this module to read the credentials from
# ~/.my.cnf.
login_password = module.params["login_password"]
login_user = module.params["login_user"]
if login_user is None and login_password is None:
mycnf_creds = load_mycnf()
if mycnf_creds is False:
login_user = "root"
login_password = ""
else:
login_user = mycnf_creds["user"]
login_password = mycnf_creds["passwd"]
elif login_password is None or login_user is None:
module.fail_json(msg="when supplying login arguments, both login_user and login_password must be provided")
try:
if module.params["login_unix_socket"] != None:
db_connection = MySQLdb.connect(host=module.params["login_host"], unix_socket=module.params["login_unix_socket"], user=login_user, passwd=login_password, db="mysql")
else:
db_connection = MySQLdb.connect(host=module.params["login_host"], user=login_user, passwd=login_password, db="mysql")
cursor = db_connection.cursor()
except Exception as e:
module.fail_json(msg="unable to connect, check login_user and login_password are correct, or alternatively check ~/.my.cnf contains credentials")
changed = False
if db_exists(cursor, db):
if state == "absent":
changed = db_delete(cursor, db)
else:
if state == "present":
changed = db_create(cursor, db, encoding, collation)
module.exit_json(changed=changed, db=db)
# this is magic, see lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
main()