diff --git a/changelogs/fragments/0_mysql_user_session_vars.yml b/changelogs/fragments/0_mysql_user_session_vars.yml new file mode 100644 index 0000000..55bcd6c --- /dev/null +++ b/changelogs/fragments/0_mysql_user_session_vars.yml @@ -0,0 +1,2 @@ +minor_changes: +- mysql_user - add the ``session_vars`` argument to set session variables at the beginning of module execution (https://github.com/ansible-collections/community.mysql/issues/478). diff --git a/plugins/module_utils/mysql.py b/plugins/module_utils/mysql.py index d256599..18e34e0 100644 --- a/plugins/module_utils/mysql.py +++ b/plugins/module_utils/mysql.py @@ -34,6 +34,8 @@ mysql_driver_fail_msg = ('A MySQL module is required: for Python 2.7 either PyMy 'Consider setting ansible_python_interpreter to use ' 'the intended Python version.') +from ansible_collections.community.mysql.plugins.module_utils.database import mysql_quote_identifier + def parse_from_mysql_config_file(cnf): # Default values of comment_prefix is '#' and ';'. @@ -149,3 +151,13 @@ def get_server_version(cursor): version_str = result[0] return version_str + + +def set_session_vars(module, cursor, session_vars): + """Set session vars.""" + for var, value in session_vars.items(): + query = "SET SESSION %s = " % mysql_quote_identifier(var, 'vars') + try: + cursor.execute(query + "%s", (value,)) + except Exception as e: + module.fail_json(msg='Failed to execute %s%s: %s' % (query, value, e)) diff --git a/plugins/modules/mysql_user.py b/plugins/modules/mysql_user.py index bd488b0..e1808c8 100644 --- a/plugins/modules/mysql_user.py +++ b/plugins/modules/mysql_user.py @@ -149,6 +149,12 @@ options: - Used when I(state=present), ignored otherwise. type: dict version_added: '0.1.0' + session_vars: + description: + - "Dictionary of session variables in form of C(variable: value) to set at the beginning of module execution." + - Cannot be used to set global variables, use the M(community.mysql.mysql_variables) module instead. + type: dict + version_added: '3.6.0' notes: - "MySQL server installs with default I(login_user) of C(root) and no password. @@ -208,12 +214,15 @@ EXAMPLES = r''' priv: '*.*:ALL' state: present +# Set session var wsrep_on=off before creating the user - name: Create database user with password and all database privileges and 'WITH GRANT OPTION' community.mysql.mysql_user: name: bob password: 12345 priv: '*.*:ALL,GRANT' state: present + session_vars: + wsrep_on: off - name: Create user with password, all database privileges and 'WITH GRANT OPTION' in db1 and db2 community.mysql.mysql_user: @@ -341,7 +350,11 @@ RETURN = '''#''' from ansible.module_utils.basic import AnsibleModule from ansible_collections.community.mysql.plugins.module_utils.database import SQLParseError from ansible_collections.community.mysql.plugins.module_utils.mysql import ( - mysql_connect, mysql_driver, mysql_driver_fail_msg, mysql_common_argument_spec + mysql_connect, + mysql_driver, + mysql_driver_fail_msg, + mysql_common_argument_spec, + set_session_vars, ) from ansible_collections.community.mysql.plugins.module_utils.user import ( convert_priv_dict_to_str, @@ -385,6 +398,7 @@ def main(): plugin_auth_string=dict(default=None, type='str'), resource_limits=dict(type='dict'), force_context=dict(type='bool', default=False), + session_vars=dict(type='dict'), ) module = AnsibleModule( argument_spec=argument_spec, @@ -419,6 +433,8 @@ def main(): plugin_hash_string = module.params["plugin_hash_string"] plugin_auth_string = module.params["plugin_auth_string"] resource_limits = module.params["resource_limits"] + session_vars = module.params["session_vars"] + if priv and not isinstance(priv, (str, dict)): module.fail_json(msg="priv parameter must be str or dict but %s was passed" % type(priv)) @@ -447,6 +463,9 @@ def main(): if not sql_log_bin: cursor.execute("SET SQL_LOG_BIN=0;") + if session_vars: + set_session_vars(module, cursor, session_vars) + get_impl(cursor) if priv is not None: diff --git a/tests/integration/targets/test_mysql_user/tasks/main.yml b/tests/integration/targets/test_mysql_user/tasks/main.yml index ef21c55..d829322 100644 --- a/tests/integration/targets/test_mysql_user/tasks/main.yml +++ b/tests/integration/targets/test_mysql_user/tasks/main.yml @@ -62,6 +62,8 @@ name: '{{user_name_1}}' password: '{{user_password_1}}' state: present + session_vars: + sort_buffer_size: 1024 register: result - name: assert output message mysql user was not created @@ -69,6 +71,24 @@ that: - result is not changed + # Try to set wrong session variable, must fail + - name: create mysql user trying to set global variable which is forbidden + mysql_user: + <<: *mysql_params + name: '{{user_name_1}}' + password: '{{user_password_1}}' + state: present + session_vars: + max_connections: 1000 + register: result + ignore_errors: true + + - name: we cannot set a global variable + assert: + that: + - result is failed + - result.msg is search('is a GLOBAL variable') + # ============================================================ # remove mysql user and verify user is removed from mysql database #