From 4912f1a41b9b7a79fa526119879ff8159bb7c2da Mon Sep 17 00:00:00 2001 From: Andrew Klychkov Date: Fri, 28 Jun 2024 11:34:59 +0200 Subject: [PATCH] mysql_variables: fix boolean value handling (#653) * mysql_variables: fix boolean value handling * fix * Fix tests * Fix tests * Fix * Fix * Fix * Fix comment --- changelogs/fragments/2-mysql_variables.yml | 2 + plugins/modules/mysql_variables.py | 21 +++++ .../tasks/mysql_variables.yml | 93 +++++++++++++++++++ .../plugins/modules/test_mysql_variables.py | 26 ++++++ 4 files changed, 142 insertions(+) create mode 100644 changelogs/fragments/2-mysql_variables.yml create mode 100644 tests/unit/plugins/modules/test_mysql_variables.py diff --git a/changelogs/fragments/2-mysql_variables.yml b/changelogs/fragments/2-mysql_variables.yml new file mode 100644 index 0000000..9ef8d80 --- /dev/null +++ b/changelogs/fragments/2-mysql_variables.yml @@ -0,0 +1,2 @@ +bugfixes: +- mysql_variables - fix the module always changes on boolean values (https://github.com/ansible-collections/community.mysql/issues/652). diff --git a/plugins/modules/mysql_variables.py b/plugins/modules/mysql_variables.py index f912a27..8632a52 100644 --- a/plugins/modules/mysql_variables.py +++ b/plugins/modules/mysql_variables.py @@ -26,6 +26,7 @@ options: value: description: - If set, then sets variable value to this. + - With boolean values, use C(0)|C(1) or quoted C("ON")|C("OFF"). type: str mode: description: @@ -74,6 +75,11 @@ EXAMPLES = r''' variable: read_only value: 1 mode: persist + +- name: Set a boolean using ON/OFF notation + mysql_variables: + variable: log_slow_replica_statements + value: "ON" # Make sure it's quoted ''' RETURN = r''' @@ -176,6 +182,18 @@ def setvariable(cursor, mysqlvar, value, mode='global'): return result +def convert_bool_setting_value_wanted(val): + """Converts passed value from 0,1,on,off to ON/OFF + as it's represented in the server. + """ + if val in ('on', 1): + val = 'ON' + elif val in ('off', 0): + val = 'OFF' + + return val + + def main(): argument_spec = mysql_common_argument_spec() argument_spec.update( @@ -243,6 +261,9 @@ def main(): # Type values before using them value_wanted = typedvalue(value) value_actual = typedvalue(mysqlvar_val) + if value_actual in ('ON', 'OFF') and value_wanted not in ('ON', 'OFF'): + value_wanted = convert_bool_setting_value_wanted(value_wanted) + value_in_auto_cnf = None if var_in_mysqld_auto_cnf is not None: value_in_auto_cnf = typedvalue(var_in_mysqld_auto_cnf) diff --git a/tests/integration/targets/test_mysql_variables/tasks/mysql_variables.yml b/tests/integration/targets/test_mysql_variables/tasks/mysql_variables.yml index 4a7fd00..8194172 100644 --- a/tests/integration/targets/test_mysql_variables/tasks/mysql_variables.yml +++ b/tests/integration/targets/test_mysql_variables/tasks/mysql_variables.yml @@ -287,6 +287,99 @@ var_name: "{{set_name}}" var_value: '{{set_value}}' + #========================================================================= + # Bugfix https://github.com/ansible-collections/community.mysql/issues/652 + + - name: Get server version + register: result + mysql_info: + <<: *mysql_params + + - name: Set variable name when running on MySQL + set_fact: + log_slow_statements: log_slow_replica_statements + when: result.server_engine == 'MySQL' + + - name: Set variable name when running on MariaDB + set_fact: + log_slow_statements: log_slow_slave_statements + when: result.server_engine == 'MariaDB' + + - name: Set a boolean value using ON + mysql_variables: + <<: *mysql_params + variable: "{{ log_slow_statements }}" + value: "ON" + register: result + + - name: Check that it changed + assert: + that: + - result is changed or result.msg == "Variable is already set to requested value." + - result.msg == "Variable is already set to requested value." or result.queries == ["SET GLOBAL `{{ log_slow_statements }}` = ON"] + + - name: Set a boolean value again using ON + mysql_variables: + <<: *mysql_params + variable: "{{ log_slow_statements }}" + value: "ON" + register: result + + - name: Check that it didn't change + assert: + that: + - result is not changed + + - name: Set a boolean value again using 1 + mysql_variables: + <<: *mysql_params + variable: "{{ log_slow_statements }}" + value: 1 + register: result + + - name: Check that it didn't change + assert: + that: + - result is not changed + + - name: Set a boolean value using OFF + mysql_variables: + <<: *mysql_params + variable: "{{ log_slow_statements }}" + value: "OFF" + register: result + + - name: Check that it changed + assert: + that: + - result is changed + - result.queries == ["SET GLOBAL `{{ log_slow_statements }}` = OFF"] + + - name: Set a boolean value again using 0 + mysql_variables: + <<: *mysql_params + variable: "{{ log_slow_statements }}" + value: 0 + register: result + + - name: Check that it didn't change + assert: + that: + - result is not changed + + - name: Set a boolean value using on + mysql_variables: + <<: *mysql_params + variable: "{{ log_slow_statements }}" + value: "on" + register: result + + - name: Check that it changed + assert: + that: + - result is changed + - result.queries == ["SET GLOBAL `{{ log_slow_statements }}` = ON"] + #============================================================ # Verify mysql_variable fails with an incorrect login_password parameter # diff --git a/tests/unit/plugins/modules/test_mysql_variables.py b/tests/unit/plugins/modules/test_mysql_variables.py new file mode 100644 index 0000000..8960173 --- /dev/null +++ b/tests/unit/plugins/modules/test_mysql_variables.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import pytest + +from ansible_collections.community.mysql.plugins.modules.mysql_variables import ( + convert_bool_setting_value_wanted, +) + + +@pytest.mark.parametrize( + 'value,output', + [ + (1, 'ON'), + (0, 'OFF'), + (2, 2), + ('on', 'ON'), + ('off', 'OFF'), + ('ON', 'ON'), + ('OFF', 'OFF'), + ] +) +def test_convert_bool_value(value, output): + assert convert_bool_setting_value_wanted(value) == output