2014-09-26 01:01:01 +00:00
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Ansible module to manage mysql variables
( c ) 2013 , Balazs Pocze < banyek @gawker.com >
Certain parts are taken from Mark Theunissen ' s mysqldb module
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_variables
short_description : Manage MySQL global variables
description :
- Query / Set MySQL variables
version_added : 1.3
2015-06-15 19:53:30 +00:00
author : " Balazs Pocze (@banyek) "
2014-09-26 01:01:01 +00:00
options :
variable :
description :
- Variable name to operate
required : True
value :
description :
- If set , then sets variable value to this
required : False
2015-11-11 04:13:48 +00:00
extends_documentation_fragment : mysql
2014-09-26 01:01:01 +00:00
'''
EXAMPLES = '''
# Check for sync_binlog setting
2016-10-12 19:20:41 +00:00
- mysql_variables :
variable : sync_binlog
2014-09-26 01:01:01 +00:00
# Set read_only variable to 1
2016-10-12 19:20:41 +00:00
- mysql_variables :
variable : read_only
value : 1
2014-09-26 01:01:01 +00:00
'''
import warnings
2015-03-26 14:12:18 +00:00
from re import match
2014-09-26 01:01:01 +00:00
try :
import MySQLdb
except ImportError :
mysqldb_found = False
else :
mysqldb_found = True
def typedvalue ( value ) :
"""
Convert value to number whenever possible , return same value
otherwise .
>> > typedvalue ( ' 3 ' )
3
>> > typedvalue ( ' 3.0 ' )
3.0
>> > typedvalue ( ' foobar ' )
' foobar '
"""
try :
return int ( value )
except ValueError :
pass
try :
return float ( value )
except ValueError :
pass
return value
def getvariable ( cursor , mysqlvar ) :
2015-03-26 14:12:18 +00:00
cursor . execute ( " SHOW VARIABLES WHERE Variable_name = %s " , ( mysqlvar , ) )
2014-09-26 01:01:01 +00:00
mysqlvar_val = cursor . fetchall ( )
2015-03-26 14:12:18 +00:00
if len ( mysqlvar_val ) is 1 :
return mysqlvar_val [ 0 ] [ 1 ]
else :
return None
2014-09-26 01:01:01 +00:00
def setvariable ( cursor , mysqlvar , value ) :
""" Set a global mysql variable to a given value
The DB driver will handle quoting of the given value based on its
type , thus numeric strings like ' 3.0 ' or ' 8 ' are illegal , they
should be passed as numeric literals .
"""
2015-03-26 14:12:18 +00:00
query = " SET GLOBAL %s = " % mysql_quote_identifier ( mysqlvar , ' vars ' )
2014-09-26 01:01:01 +00:00
try :
2015-03-26 14:12:18 +00:00
cursor . execute ( query + " %s " , ( value , ) )
2014-09-26 01:01:01 +00:00
cursor . fetchall ( )
result = True
2016-05-18 14:07:21 +00:00
except Exception :
e = get_exception ( )
2014-09-26 01:01:01 +00:00
result = str ( e )
return result
def main ( ) :
module = AnsibleModule (
argument_spec = dict (
login_user = dict ( default = None ) ,
2016-05-02 16:38:07 +00:00
login_password = dict ( default = None , no_log = True ) ,
login_host = dict ( default = " localhost " ) ,
login_port = dict ( default = 3306 , type = ' int ' ) ,
2014-09-26 01:01:01 +00:00
login_unix_socket = dict ( default = None ) ,
variable = dict ( default = None ) ,
2015-11-11 04:13:48 +00:00
value = dict ( default = None ) ,
ssl_cert = dict ( default = None ) ,
ssl_key = dict ( default = None ) ,
ssl_ca = dict ( default = None ) ,
2016-03-10 21:06:39 +00:00
connect_timeout = dict ( default = 30 , type = ' int ' ) ,
2016-05-02 16:38:07 +00:00
config_file = dict ( default = " ~/.my.cnf " , type = " path " )
2014-09-26 01:01:01 +00:00
)
)
user = module . params [ " login_user " ]
password = module . params [ " login_password " ]
2015-11-11 04:13:48 +00:00
ssl_cert = module . params [ " ssl_cert " ]
ssl_key = module . params [ " ssl_key " ]
ssl_ca = module . params [ " ssl_ca " ]
2016-03-10 21:06:39 +00:00
connect_timeout = module . params [ ' connect_timeout ' ]
2015-11-11 04:13:48 +00:00
config_file = module . params [ ' config_file ' ]
db = ' mysql '
2014-09-26 01:01:01 +00:00
mysqlvar = module . params [ " variable " ]
value = module . params [ " value " ]
2015-03-26 14:12:18 +00:00
if mysqlvar is None :
module . fail_json ( msg = " Cannot run without variable to operate with " )
if match ( ' ^[0-9a-z_]+$ ' , mysqlvar ) is None :
2016-02-16 21:58:44 +00:00
module . fail_json ( msg = " invalid variable name \" %s \" " % mysqlvar )
2014-09-26 01:01:01 +00:00
if not mysqldb_found :
module . fail_json ( msg = " the python mysqldb module is required " )
else :
warnings . filterwarnings ( ' error ' , category = MySQLdb . Warning )
try :
2016-03-10 21:06:39 +00:00
cursor = mysql_connect ( module , user , password , config_file , ssl_cert , ssl_key , ssl_ca , db ,
connect_timeout = connect_timeout )
2016-05-18 14:07:21 +00:00
except Exception :
e = get_exception ( )
2015-11-11 04:13:48 +00:00
if os . path . exists ( config_file ) :
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 :
module . fail_json ( msg = " unable to find %s . Exception message: %s " % ( config_file , e ) )
2014-09-26 01:01:01 +00:00
mysqlvar_val = getvariable ( cursor , mysqlvar )
2015-03-26 14:12:18 +00:00
if mysqlvar_val is None :
module . fail_json ( msg = " Variable not available \" %s \" " % mysqlvar , changed = False )
2014-09-26 01:01:01 +00:00
if value is None :
module . exit_json ( msg = mysqlvar_val )
else :
# Type values before using them
value_wanted = typedvalue ( value )
2015-03-26 14:12:18 +00:00
value_actual = typedvalue ( mysqlvar_val )
2014-09-26 01:01:01 +00:00
if value_wanted == value_actual :
module . exit_json ( msg = " Variable already set to requested value " , changed = False )
2014-11-25 09:46:09 +00:00
try :
result = setvariable ( cursor , mysqlvar , value_wanted )
2016-05-18 14:07:21 +00:00
except SQLParseError :
e = get_exception ( )
2014-11-25 09:46:09 +00:00
result = str ( e )
2014-09-26 01:01:01 +00:00
if result is True :
module . exit_json ( msg = " Variable change succeeded prev_value= %s " % value_actual , changed = True )
else :
module . fail_json ( msg = result , changed = False )
# import module snippets
from ansible . module_utils . basic import *
2014-11-25 09:46:09 +00:00
from ansible . module_utils . database import *
2015-11-11 04:13:48 +00:00
from ansible . module_utils . mysql import *
2016-05-02 16:38:07 +00:00
if __name__ == ' __main__ ' :
2016-05-18 14:07:21 +00:00
main ( )