mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-26 05:50:36 -07:00 
			
		
		
		
	- added terse syntax to modules.rst - added description of special variables to template module
		
			
				
	
	
		
			218 lines
		
	
	
	
		
			7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
	
		
			7 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 password used 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", "dump", "import" ]
 | |
|   collation:
 | |
|     description:
 | |
|       - Collation mode
 | |
|     required: false
 | |
|     default: null
 | |
|   encoding:
 | |
|     description:
 | |
|       - Encoding mode
 | |
|     required: false
 | |
|     default: null
 | |
|   target:
 | |
|     description:
 | |
|       - Where to dump/get the .sql file
 | |
|     required: true
 | |
| 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 C(login_password) and C(login_username) are required when you are
 | |
|      passing credentials. If none are present, the module will attempt to read
 | |
|      the credentials from C(~/.my.cnf), and finally fall back to using the MySQL
 | |
|      default login of 'root' with no password.
 | |
| requirements: [ ConfigParser ]
 | |
| author: Mark Theunissen
 | |
| '''
 | |
| 
 | |
| import ConfigParser
 | |
| import os
 | |
| 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_dump(user, password, db_name, target):
 | |
|     res = os.system("/usr/bin/mysqldump -q -u "+user+ " -p"+password+" "
 | |
|             +db_name+" > "
 | |
|             +target)
 | |
|     return (res == 0)
 | |
| 
 | |
| def db_import(user, password, db_name, target):
 | |
|     res = os.system("/usr/bin/mysql -u "+user+ " -p"+password+" "
 | |
|             +db_name+" < "
 | |
|             +target)
 | |
|     return (res == 0)
 | |
| 
 | |
| 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=""),
 | |
|             target=dict(default=None),
 | |
|             state=dict(default="present", choices=["absent", "present","dump", "import"]),
 | |
|         )
 | |
|     )
 | |
| 
 | |
|     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"]
 | |
|     target = module.params["target"]
 | |
| 
 | |
|     # 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")
 | |
| 
 | |
|     if state in ['dump','import']:
 | |
|         if target is None:
 | |
|             module.fail_json(msg="with state={0} target is required".format(state))
 | |
|         connect_to_db = db
 | |
|     else:
 | |
|         connect_to_db = 'mysql'
 | |
|     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=connect_to_db)
 | |
|         else:
 | |
|             db_connection = MySQLdb.connect(host=module.params["login_host"], user=login_user, passwd=login_password, db=connect_to_db)
 | |
|         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)
 | |
|         elif state == "dump":
 | |
|             changed = db_dump(login_user, login_password, db, target)
 | |
|             if not changed:
 | |
|                 module.fail_json(msg="dump failed!")
 | |
|         elif state == "import":
 | |
|             changed = db_import(login_user, login_password, db, target)
 | |
|             if not changed:
 | |
|                 module.fail_json(msg="import failed!")
 | |
|     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()
 |