Unify mysql modules.
Added config_file, ssl_ca, ssl_cert, ssl_key, changed connect method, added error checking where a backtrace previoussly was possible
This commit is contained in:
parent
7d072140b3
commit
a50b661e54
1 changed files with 26 additions and 109 deletions
|
@ -45,27 +45,6 @@ options:
|
||||||
- resetslave
|
- resetslave
|
||||||
- resetslaveall
|
- resetslaveall
|
||||||
default: getslave
|
default: getslave
|
||||||
login_user:
|
|
||||||
description:
|
|
||||||
- username to connect mysql host, if defined login_password also needed.
|
|
||||||
required: False
|
|
||||||
login_password:
|
|
||||||
description:
|
|
||||||
- password to connect mysql host, if defined login_user also needed.
|
|
||||||
required: False
|
|
||||||
login_host:
|
|
||||||
description:
|
|
||||||
- mysql host to connect
|
|
||||||
required: False
|
|
||||||
login_port:
|
|
||||||
description:
|
|
||||||
- Port of the MySQL server. Requires login_host be defined as other then localhost if login_port is used
|
|
||||||
required: False
|
|
||||||
default: 3306
|
|
||||||
version_added: "1.9"
|
|
||||||
login_unix_socket:
|
|
||||||
description:
|
|
||||||
- unix socket to connect mysql server
|
|
||||||
master_host:
|
master_host:
|
||||||
description:
|
description:
|
||||||
- same as mysql variable
|
- same as mysql variable
|
||||||
|
@ -115,6 +94,11 @@ options:
|
||||||
master_auto_position:
|
master_auto_position:
|
||||||
descrtiption:
|
descrtiption:
|
||||||
- does the host uses GTID based replication or not
|
- does the host uses GTID based replication or not
|
||||||
|
required: false
|
||||||
|
default: null
|
||||||
|
version_added: "2.0"
|
||||||
|
|
||||||
|
extends_documentation_fragment: mysql
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -131,7 +115,6 @@ EXAMPLES = '''
|
||||||
- mysql_replication: mode=getslave login_host=ansible.example.com login_port=3308
|
- mysql_replication: mode=getslave login_host=ansible.example.com login_port=3308
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import ConfigParser
|
|
||||||
import os
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
@ -197,65 +180,6 @@ def changemaster(cursor, chm, chm_params):
|
||||||
cursor.execute(query, chm_params)
|
cursor.execute(query, chm_params)
|
||||||
|
|
||||||
|
|
||||||
def strip_quotes(s):
|
|
||||||
""" Remove surrounding single or double quotes
|
|
||||||
|
|
||||||
>>> print strip_quotes('hello')
|
|
||||||
hello
|
|
||||||
>>> print strip_quotes('"hello"')
|
|
||||||
hello
|
|
||||||
>>> print strip_quotes("'hello'")
|
|
||||||
hello
|
|
||||||
>>> print strip_quotes("'hello")
|
|
||||||
'hello
|
|
||||||
|
|
||||||
"""
|
|
||||||
single_quote = "'"
|
|
||||||
double_quote = '"'
|
|
||||||
|
|
||||||
if s.startswith(single_quote) and s.endswith(single_quote):
|
|
||||||
s = s.strip(single_quote)
|
|
||||||
elif s.startswith(double_quote) and s.endswith(double_quote):
|
|
||||||
s = s.strip(double_quote)
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def config_get(config, section, option):
|
|
||||||
""" Calls ConfigParser.get and strips quotes
|
|
||||||
|
|
||||||
See: http://dev.mysql.com/doc/refman/5.0/en/option-files.html
|
|
||||||
"""
|
|
||||||
return strip_quotes(config.get(section, option))
|
|
||||||
|
|
||||||
|
|
||||||
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))
|
|
||||||
except (IOError):
|
|
||||||
return False
|
|
||||||
# We support two forms of passwords in .my.cnf, both pass= and password=,
|
|
||||||
# as these are both supported by MySQL.
|
|
||||||
try:
|
|
||||||
passwd = config_get(config, 'client', 'password')
|
|
||||||
except (ConfigParser.NoOptionError):
|
|
||||||
try:
|
|
||||||
passwd = config_get(config, 'client', 'pass')
|
|
||||||
except (ConfigParser.NoOptionError):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# If .my.cnf doesn't specify a user, default to user login name
|
|
||||||
try:
|
|
||||||
user = config_get(config, 'client', 'user')
|
|
||||||
except (ConfigParser.NoOptionError):
|
|
||||||
user = getpass.getuser()
|
|
||||||
creds = dict(user=user, passwd=passwd)
|
|
||||||
return creds
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec = dict(
|
argument_spec = dict(
|
||||||
|
@ -281,6 +205,10 @@ def main():
|
||||||
master_ssl_cert=dict(default=None),
|
master_ssl_cert=dict(default=None),
|
||||||
master_ssl_key=dict(default=None),
|
master_ssl_key=dict(default=None),
|
||||||
master_ssl_cipher=dict(default=None),
|
master_ssl_cipher=dict(default=None),
|
||||||
|
config_file=dict(default="~/.my.cnf"),
|
||||||
|
ssl_cert=dict(default=None),
|
||||||
|
ssl_key=dict(default=None),
|
||||||
|
ssl_ca=dict(default=None),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
user = module.params["login_user"]
|
user = module.params["login_user"]
|
||||||
|
@ -304,42 +232,27 @@ def main():
|
||||||
master_ssl_key = module.params["master_ssl_key"]
|
master_ssl_key = module.params["master_ssl_key"]
|
||||||
master_ssl_cipher = module.params["master_ssl_cipher"]
|
master_ssl_cipher = module.params["master_ssl_cipher"]
|
||||||
master_auto_position = module.params["master_auto_position"]
|
master_auto_position = module.params["master_auto_position"]
|
||||||
|
ssl_cert = module.params["ssl_cert"]
|
||||||
|
ssl_key = module.params["ssl_key"]
|
||||||
|
ssl_ca = module.params["ssl_ca"]
|
||||||
|
config_file = module.params['config_file']
|
||||||
|
config_file = os.path.expanduser(os.path.expandvars(config_file))
|
||||||
|
|
||||||
if not mysqldb_found:
|
if not mysqldb_found:
|
||||||
module.fail_json(msg="the python mysqldb module is required")
|
module.fail_json(msg="the python mysqldb module is required")
|
||||||
else:
|
else:
|
||||||
warnings.filterwarnings('error', category=MySQLdb.Warning)
|
warnings.filterwarnings('error', category=MySQLdb.Warning)
|
||||||
|
|
||||||
# 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_password = module.params["login_password"]
|
||||||
login_user = module.params["login_user"]
|
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:
|
try:
|
||||||
if module.params["login_unix_socket"]:
|
cursor = mysql_connect(module, login_user, login_password, config_file, ssl_cert, ssl_key, ssl_ca, None, 'MySQLdb.cursors.DictCursor')
|
||||||
db_connection = MySQLdb.connect(host=module.params["login_host"], unix_socket=module.params["login_unix_socket"], user=login_user, passwd=login_password)
|
except Exception, e:
|
||||||
elif module.params["login_port"] != 3306 and module.params["login_host"] == "localhost":
|
if os.path.exists(config_file):
|
||||||
module.fail_json(msg="login_host is required when login_port is defined, login_host cannot be localhost when login_port is defined")
|
module.fail_json(msg="unable to connect to database, check login_user and login_password are correct or %s has the credentials. Exception message: %s" % (config_file, e))
|
||||||
else:
|
else:
|
||||||
db_connection = MySQLdb.connect(host=module.params["login_host"], port=module.params["login_port"], user=login_user, passwd=login_password)
|
module.fail_json(msg="unable to find %s. Exception message: %s" % (config_file, e))
|
||||||
except Exception, e:
|
|
||||||
errno, errstr = e.args
|
|
||||||
module.fail_json(msg="unable to connect to database, check login_user and login_password are correct or ~/.my.cnf has the credentials (%s: %s)" % (errno, errstr) )
|
|
||||||
try:
|
|
||||||
cursor = db_connection.cursor(cursorclass=MySQLdb.cursors.DictCursor)
|
|
||||||
except Exception, e:
|
|
||||||
module.fail_json(msg="Trouble getting DictCursor from db_connection: %s" % e)
|
|
||||||
|
|
||||||
if mode in "getmaster":
|
if mode in "getmaster":
|
||||||
masterstatus = get_master_status(cursor)
|
masterstatus = get_master_status(cursor)
|
||||||
|
@ -352,8 +265,8 @@ def main():
|
||||||
slavestatus = get_slave_status(cursor)
|
slavestatus = get_slave_status(cursor)
|
||||||
try:
|
try:
|
||||||
module.exit_json( **slavestatus )
|
module.exit_json( **slavestatus )
|
||||||
except TypeError:
|
except TypeError, e:
|
||||||
module.fail_json(msg="Server is not configured as mysql slave")
|
module.fail_json(msg="Server is not configured as mysql slave. ERROR: %s" % e)
|
||||||
|
|
||||||
elif mode in "changemaster":
|
elif mode in "changemaster":
|
||||||
chm=[]
|
chm=[]
|
||||||
|
@ -404,7 +317,10 @@ def main():
|
||||||
chm_params['master_ssl_cipher'] = master_ssl_cipher
|
chm_params['master_ssl_cipher'] = master_ssl_cipher
|
||||||
if master_auto_position:
|
if master_auto_position:
|
||||||
chm.append("MASTER_AUTO_POSITION = 1")
|
chm.append("MASTER_AUTO_POSITION = 1")
|
||||||
|
try:
|
||||||
changemaster(cursor, chm, chm_params)
|
changemaster(cursor, chm, chm_params)
|
||||||
|
except Exception, e:
|
||||||
|
module.fail_json(msg='%s. Query == CHANGE MASTER TO %s' % (e, chm))
|
||||||
module.exit_json(changed=True)
|
module.exit_json(changed=True)
|
||||||
elif mode in "startslave":
|
elif mode in "startslave":
|
||||||
started = start_slave(cursor)
|
started = start_slave(cursor)
|
||||||
|
@ -433,5 +349,6 @@ def main():
|
||||||
|
|
||||||
# import module snippets
|
# import module snippets
|
||||||
from ansible.module_utils.basic import *
|
from ansible.module_utils.basic import *
|
||||||
|
from ansible.module_utils.mysql import *
|
||||||
main()
|
main()
|
||||||
warnings.simplefilter("ignore")
|
warnings.simplefilter("ignore")
|
||||||
|
|
Loading…
Reference in a new issue