diff --git a/.github/workflows/ansible-test-plugins.yml b/.github/workflows/ansible-test-plugins.yml index 0b6c184..ad8c4b5 100644 --- a/.github/workflows/ansible-test-plugins.yml +++ b/.github/workflows/ansible-test-plugins.yml @@ -13,7 +13,7 @@ on: # yamllint disable-line rule:truthy - '.github/workflows/ansible-test-plugins.yml' schedule: - cron: '0 6 * * *' - workflow_dispatch: + jobs: sanity: @@ -54,8 +54,8 @@ jobs: db_engine_version: - '8.0.38' - '8.4.1' + - '10.5.25' - '10.11.8' - - '11.4.5' connector_name: - pymysql - mysqlclient @@ -87,10 +87,10 @@ jobs: exclude: - db_engine_name: mysql - db_engine_version: '10.11.8' + db_engine_version: '10.5.25' - db_engine_name: mysql - db_engine_version: '11.4.5' + db_engine_version: '10.11.8' - db_engine_name: mariadb db_engine_version: '8.0.38' @@ -119,13 +119,13 @@ jobs: - db_engine_version: '8.0.38' ansible: stable-2.17 - - db_engine_version: '10.11.8' + - db_engine_version: '10.5.25' ansible: stable-2.17 - db_engine_version: '8.0.38' ansible: devel - - db_engine_version: '10.11.8' + - db_engine_version: '10.5.25' ansible: devel - db_engine_version: '8.4.1' @@ -162,7 +162,7 @@ jobs: db_engine_version: '8.0.38' - connector_version: '1.1.1' - db_engine_version: '10.11.8' + db_engine_version: '10.5.25' services: db_primary: @@ -175,7 +175,7 @@ jobs: # We write our own health-cmd because the mariadb container does not # provide a healthcheck options: >- - --health-cmd "${{ matrix.db_engine_name == 'mysql' && 'mysqladmin' || 'mariadb-admin' }} ping -P 3306 -pmsandbox |grep alive || exit 1" + --health-cmd "mysqladmin ping -P 3306 -pmsandbox |grep alive || exit 1" --health-start-period 10s --health-interval 10s --health-timeout 5s @@ -189,7 +189,7 @@ jobs: ports: - 3308:3306 options: >- - --health-cmd "${{ matrix.db_engine_name == 'mysql' && 'mysqladmin' || 'mariadb-admin' }} ping -P 3306 -pmsandbox |grep alive || exit 1" + --health-cmd "mysqladmin ping -P 3306 -pmsandbox |grep alive || exit 1" --health-start-period 10s --health-interval 10s --health-timeout 5s @@ -203,7 +203,7 @@ jobs: ports: - 3309:3306 options: >- - --health-cmd "${{ matrix.db_engine_name == 'mysql' && 'mysqladmin' || 'mariadb-admin' }} ping -P 3306 -pmsandbox |grep alive || exit 1" + --health-cmd "mysqladmin ping -P 3306 -pmsandbox |grep alive || exit 1" --health-start-period 10s --health-interval 10s --health-timeout 5s diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b318076..a6ada35 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,43 +6,6 @@ Community MySQL and MariaDB Collection Release Notes This changelog describes changes after version 2.0.0. -v3.13.0 -======= - -Release Summary ---------------- - -This is a minor release of the ``community.mysql`` collection. -This changelog contains all changes to the modules and plugins in this -collection that have been made after the previous release. - -Minor Changes -------------- - -- Integration tests for MariaDB 11.4 have replaced those for 10.5. The previous version is now 10.11. -- mysql_user - add ``locked`` option to lock/unlock users, this is mainly used to have users that will act as definers on stored procedures. - -Bugfixes --------- - -- mysql_db - fix dump and import to find MariaDB binaries (mariadb and mariadb-dump) when MariaDB 11+ is used and symbolic links to MySQL binaries are absent. - -v3.12.0 -======= - -Release Summary ---------------- - -This is a minor release of the ``community.mysql`` collection. -This changelog contains all changes to the modules and plugins in this -collection that have been made after the previous release. - -Minor Changes -------------- - -- mysql_db - added ``zstd`` (de)compression support for ``import``/``dump`` states (https://github.com/ansible-collections/community.mysql/issues/696). -- mysql_query - returns the ``execution_time_ms`` list containing execution time per query in milliseconds. - v3.11.0 ======= @@ -50,7 +13,6 @@ Release Summary --------------- This is a minor release of the ``community.mysql`` collection. - This changelog contains all changes to the modules and plugins in this collection that have been made after the previous release. diff --git a/Makefile b/Makefile index b503e2f..5a11d1b 100644 --- a/Makefile +++ b/Makefile @@ -11,17 +11,6 @@ ifdef continue_on_errors _continue_on_errors = --continue-on-error endif -# Set command variables based on database engine -# Required for MariaDB 11+ which no longer includes mysql named compatible -# executable symlinks -ifeq ($(db_engine_name),mysql) - _command = mysqld - _health_cmd = mysqladmin -else - _command = mariadbd - _health_cmd = mariadb-admin -endif - .PHONY: test-integration test-integration: @echo -n $(db_engine_name) > tests/integration/db_engine_name @@ -40,9 +29,9 @@ test-integration: --env MYSQL_ROOT_PASSWORD=msandbox \ --network podman \ --publish 3307:3306 \ - --health-cmd '$(_health_cmd) ping -P 3306 -pmsandbox | grep alive || exit 1' \ + --health-cmd 'mysqladmin ping -P 3306 -pmsandbox | grep alive || exit 1' \ docker.io/library/$(db_engine_name):$(db_engine_version) \ - $(_command) + mysqld podman run \ --detach \ --replace \ @@ -51,9 +40,9 @@ test-integration: --env MYSQL_ROOT_PASSWORD=msandbox \ --network podman \ --publish 3308:3306 \ - --health-cmd '$(_health_cmd) ping -P 3306 -pmsandbox | grep alive || exit 1' \ + --health-cmd 'mysqladmin ping -P 3306 -pmsandbox | grep alive || exit 1' \ docker.io/library/$(db_engine_name):$(db_engine_version) \ - $(_command) + mysqld podman run \ --detach \ --replace \ @@ -62,9 +51,9 @@ test-integration: --env MYSQL_ROOT_PASSWORD=msandbox \ --network podman \ --publish 3309:3306 \ - --health-cmd '$(_health_cmd) ping -P 3306 -pmsandbox | grep alive || exit 1' \ + --health-cmd 'mysqladmin ping -P 3306 -pmsandbox | grep alive || exit 1' \ docker.io/library/$(db_engine_name):$(db_engine_version) \ - $(_command) + mysqld # Setup replication and restart containers using the same subshell to keep variables alive db_ver=$(db_engine_version); \ maj="$${db_ver%.*.*}"; \ diff --git a/README.md b/README.md index df2404f..5db2f05 100644 --- a/README.md +++ b/README.md @@ -112,10 +112,10 @@ For MariaDB, only Long Term releases are tested. When multiple LTS are available - mariadb:10.3.34 (collection version < 3.5.1) - mariadb:10.4.24 (collection version >= 3.5.2, < 3.10.0) - mariadb:10.5.18 (collection version >= 3.5.2, < 3.10.0) -- mariadb:10.5.25 (collection version >= 3.10.0, <3.13.0) +- mariadb:10.5.25 (collection version >= 3.10.0) - mariadb:10.6.11 (collection version >= 3.5.2, < 3.10.0) - mariadb:10.11.8 (collection version >= 3.10.0) -- mariadb:11.4.5 (collection version >= 3.13.0) + ### Database connectors diff --git a/TESTING.md b/TESTING.md index 45e6bba..1a22832 100644 --- a/TESTING.md +++ b/TESTING.md @@ -65,8 +65,8 @@ The Makefile accept the following options - Choices: - "8.0.38" <- mysql - "8.4.1" <- mysql (NOT WORKING YET, ansible-test uses Ubuntu 20.04 which is too old to install mysql-community-client 8.4) + - "10.5.25" <- mariadb - "10.11.8" <- mariadb - - "11.4.5" <- mariadb - Description: The tag of the container to use for the service containers that will host a primary database and two replicas. Do not use short version, like `mysql:8` (don't do that) because our tests expect a full version to filter tests precisely. For instance: `when: db_version is version ('8.0.22', '>')`. You can use any tag available on [hub.docker.com/_/mysql](https://hub.docker.com/_/mysql) and [hub.docker.com/_/mariadb](https://hub.docker.com/_/mariadb) but GitHub Action will only use the versions listed above. - `connector_name` @@ -121,7 +121,7 @@ make ansible="stable-2.16" db_engine_name="mysql" db_engine_version="8.0.31" con make ansible="stable-2.17" db_engine_name="mysql" db_engine_version="8.0.31" connector_name="mysqlclient" connector_version="2.0.3" target="test_mysql_query" keep_containers_alive=1 continue_on_errors=1 # If your system has an usupported version of Python: -make local_python_version="3.10" ansible="stable-2.17" db_engine_name="mariadb" db_engine_version="11.4.5" connector_name="pymysql" connector_version="1.0.2" +make local_python_version="3.10" ansible="stable-2.17" db_engine_name="mariadb" db_engine_version="10.6.11" connector_name="pymysql" connector_version="1.0.2" ``` diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 5ec7dc9..8e5aeaf 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -230,43 +230,6 @@ releases: - 591-mysql_info-db_tables_count.yml - 671-modules_util_user.yml release_date: '2024-11-19' - 3.12.0: - changes: - minor_changes: - - mysql_db - added ``zstd`` (de)compression support for ``import``/``dump`` - states (https://github.com/ansible-collections/community.mysql/issues/696). - - mysql_query - returns the ``execution_time_ms`` list containing execution - time per query in milliseconds. - release_summary: 'This is a minor release of the ``community.mysql`` collection. - - This changelog contains all changes to the modules and plugins in this - - collection that have been made after the previous release.' - fragments: - - 0-mysql_query-returns-exec-time-ms.yml - - 3.12.0.yml - - 696-mysql-db-add-zstd-support.yml - release_date: '2025-01-17' - 3.13.0: - changes: - bugfixes: - - mysql_db - fix dump and import to find MariaDB binaries (mariadb and mariadb-dump) - when MariaDB 11+ is used and symbolic links to MySQL binaries are absent. - minor_changes: - - Integration tests for MariaDB 11.4 have replaced those for 10.5. The previous - version is now 10.11. - - mysql_user - add ``locked`` option to lock/unlock users, this is mainly used - to have users that will act as definers on stored procedures. - release_summary: 'This is a minor release of the ``community.mysql`` collection. - - This changelog contains all changes to the modules and plugins in this - - collection that have been made after the previous release.' - fragments: - - 3.13.0.yml - - 702-user_locking.yaml - - tests_mariadb_11_4.yml - release_date: '2025-03-21' 3.2.0: changes: bugfixes: diff --git a/galaxy.yml b/galaxy.yml index 624c7d6..1ecd6f2 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: community name: mysql -version: 3.13.0 +version: 3.11.0 readme: README.md authors: - Ansible community diff --git a/plugins/module_utils/user.py b/plugins/module_utils/user.py index 9de1c6d..307ef6e 100644 --- a/plugins/module_utils/user.py +++ b/plugins/module_utils/user.py @@ -52,25 +52,6 @@ def user_exists(cursor, user, host, host_all): return count[0] > 0 -def user_is_locked(cursor, user, host): - cursor.execute("SHOW CREATE USER %s@%s", (user, host)) - - # Per discussions on irc:libera.chat:#maria the query may return up to 2 rows but "ACCOUNT LOCK" should always be in the first row. - result = cursor.fetchone() - - # ACCOUNT LOCK does not have to be the last option in the CREATE USER query. - # Need to handle both DictCursor and non-DictCursor - if isinstance(result, tuple): - if result[0].find('ACCOUNT LOCK') > 0: - return True - elif isinstance(result, dict): - for res in result.values(): - if res.find('ACCOUNT LOCK') > 0: - return True - - return False - - def sanitize_requires(tls_requires): sanitized_requires = {} if tls_requires: @@ -179,7 +160,7 @@ def get_existing_authentication(cursor, user, host=None): def user_add(cursor, user, host, host_all, password, encrypted, plugin, plugin_hash_string, plugin_auth_string, salt, new_priv, attributes, tls_requires, reuse_existing_password, module, - password_expire, password_expire_interval, locked=False): + password_expire, password_expire_interval): # If attributes are set, perform a sanity check to ensure server supports user attributes before creating user if attributes and not get_attribute_support(cursor): module.fail_json(msg="user attributes were specified but the server does not support user attributes") @@ -269,9 +250,6 @@ def user_add(cursor, user, host, host_all, password, encrypted, cursor.execute("ALTER USER %s@%s ATTRIBUTE %s", (user, host, json.dumps(attributes))) final_attributes = attributes_get(cursor, user, host) - if locked: - cursor.execute("ALTER USER %s@%s ACCOUNT LOCK", (user, host)) - return {'changed': True, 'password_changed': not used_existing_password, 'attributes': final_attributes} @@ -286,7 +264,7 @@ def is_hash(password): def user_mod(cursor, user, host, host_all, password, encrypted, plugin, plugin_hash_string, plugin_auth_string, salt, new_priv, append_privs, subtract_privs, attributes, tls_requires, module, - password_expire, password_expire_interval, locked=None, role=False, maria_role=False): + password_expire, password_expire_interval, role=False, maria_role=False): changed = False msg = "User unchanged" grant_option = False @@ -558,22 +536,6 @@ def user_mod(cursor, user, host, host_all, password, encrypted, if attribute_support: final_attributes = attributes_get(cursor, user, host) - if not role and locked is not None and user_is_locked(cursor, user, host) != locked: - if not module.check_mode: - if locked: - cursor.execute("ALTER USER %s@%s ACCOUNT LOCK", (user, host)) - msg = 'User locked' - else: - cursor.execute("ALTER USER %s@%s ACCOUNT UNLOCK", (user, host)) - msg = 'User unlocked' - else: - if locked: - msg = 'User will be locked' - else: - msg = 'User will be unlocked' - - changed = True - if role: continue diff --git a/plugins/modules/mysql_db.py b/plugins/modules/mysql_db.py index 6ef578c..e1d1a7a 100644 --- a/plugins/modules/mysql_db.py +++ b/plugins/modules/mysql_db.py @@ -46,8 +46,8 @@ options: target: description: - Location, on the remote host, of the dump file to read from or write to. - - Uncompressed SQL files (C(.sql)) as well as bzip2 (C(.bz2)), gzip (C(.gz)), - xz (Added in 2.0) and zstd (C(.zst)) (Added in 3.12.0) compressed files are supported. + - Uncompressed SQL files (C(.sql)) as well as bzip2 (C(.bz2)), gzip (C(.gz)) and + xz (Added in 2.0) compressed files are supported. type: path single_transaction: description: @@ -386,75 +386,67 @@ def db_dump(module, host, user, password, db_name, target, all_databases, port, encoding=None, force=False, master_data=0, skip_lock_tables=False, dump_extra_args=None, unsafe_password=False, restrict_config_file=False, check_implicit_admin=False, pipefail=False): - - cmd_str = 'mysqldump' - if server_implementation == 'mariadb' and LooseVersion(server_version) >= LooseVersion("10.4.6"): - cmd_str = 'mariadb-dump' - try: - cmd = [module.get_bin_path(cmd_str, True)] - except Exception as e: - return 1, "", "Error determining dump command: %s" % str(e) - + cmd = module.get_bin_path('mysqldump', True) # If defined, mysqldump demands --defaults-extra-file be the first option if config_file: if restrict_config_file: - cmd.append("--defaults-file=%s" % shlex_quote(config_file)) + cmd += " --defaults-file=%s" % shlex_quote(config_file) else: - cmd.append("--defaults-extra-file=%s" % shlex_quote(config_file)) + cmd += " --defaults-extra-file=%s" % shlex_quote(config_file) if check_implicit_admin: - cmd.append("--user=root --password=''") + cmd += " --user=root --password=''" else: if user is not None: - cmd.append("--user=%s" % shlex_quote(user)) + cmd += " --user=%s" % shlex_quote(user) if password is not None: if not unsafe_password: - cmd.append("--password=%s" % shlex_quote(password)) + cmd += " --password=%s" % shlex_quote(password) else: - cmd.append("--password=%s" % password) + cmd += " --password=%s" % password if ssl_cert is not None: - cmd.append("--ssl-cert=%s" % shlex_quote(ssl_cert)) + cmd += " --ssl-cert=%s" % shlex_quote(ssl_cert) if ssl_key is not None: - cmd.append("--ssl-key=%s" % shlex_quote(ssl_key)) + cmd += " --ssl-key=%s" % shlex_quote(ssl_key) if ssl_ca is not None: - cmd.append("--ssl-ca=%s" % shlex_quote(ssl_ca)) + cmd += " --ssl-ca=%s" % shlex_quote(ssl_ca) if force: - cmd.append("--force") + cmd += " --force" if socket is not None: - cmd.append("--socket=%s" % shlex_quote(socket)) + cmd += " --socket=%s" % shlex_quote(socket) else: - cmd.append("--host=%s --port=%i" % (shlex_quote(host), port)) + cmd += " --host=%s --port=%i" % (shlex_quote(host), port) if all_databases: - cmd.append("--all-databases") + cmd += " --all-databases" elif len(db_name) > 1: - cmd.append("--databases {0}".format(' '.join(db_name))) + cmd += " --databases {0}".format(' '.join(db_name)) else: - cmd.append("%s" % shlex_quote(' '.join(db_name))) + cmd += " %s" % shlex_quote(' '.join(db_name)) if skip_lock_tables: - cmd.append("--skip-lock-tables") + cmd += " --skip-lock-tables" if (encoding is not None) and (encoding != ""): - cmd.append("--default-character-set=%s" % shlex_quote(encoding)) + cmd += " --default-character-set=%s" % shlex_quote(encoding) if single_transaction: - cmd.append("--single-transaction=true") + cmd += " --single-transaction=true" if quick: - cmd.append("--quick") + cmd += " --quick" if ignore_tables: for an_ignored_table in ignore_tables: - cmd.append("--ignore-table={0}".format(an_ignored_table)) + cmd += " --ignore-table={0}".format(an_ignored_table) if hex_blob: - cmd.append("--hex-blob") + cmd += " --hex-blob" if master_data: if (server_implementation == 'mysql' and LooseVersion(server_version) >= LooseVersion("8.2.0")): - cmd.append("--source-data=%s" % master_data) + cmd += " --source-data=%s" % master_data else: - cmd.append("--master-data=%s" % master_data) + cmd += " --master-data=%s" % master_data if dump_extra_args is not None: - cmd.append(dump_extra_args) + cmd += " " + dump_extra_args path = None if os.path.splitext(target)[-1] == '.gz': @@ -463,10 +455,6 @@ def db_dump(module, host, user, password, db_name, target, all_databases, port, path = module.get_bin_path('bzip2', True) elif os.path.splitext(target)[-1] == '.xz': path = module.get_bin_path('xz', True) - elif os.path.splitext(target)[-1] == '.zst': - path = module.get_bin_path('zstd', True) - - cmd = ' '.join(cmd) if path: cmd = '%s | %s > %s' % (cmd, path, shlex_quote(target)) @@ -486,21 +474,13 @@ def db_dump(module, host, user, password, db_name, target, all_databases, port, def db_import(module, host, user, password, db_name, target, all_databases, port, config_file, - server_implementation, server_version, socket=None, ssl_cert=None, ssl_key=None, ssl_ca=None, - encoding=None, force=False, + socket=None, ssl_cert=None, ssl_key=None, ssl_ca=None, encoding=None, force=False, use_shell=False, unsafe_password=False, restrict_config_file=False, check_implicit_admin=False): if not os.path.exists(target): return module.fail_json(msg="target %s does not exist on the host" % target) - cmd_str = 'mysql' - if server_implementation == 'mariadb' and LooseVersion(server_version) >= LooseVersion("10.4.6"): - cmd_str = 'mariadb' - try: - cmd = [module.get_bin_path(cmd_str, True)] - except Exception as e: - return 1, "", "Error determining mysql/mariadb command: %s" % str(e) - + cmd = [module.get_bin_path('mysql', True)] # --defaults-file must go first, or errors out if config_file: if restrict_config_file: @@ -546,8 +526,6 @@ def db_import(module, host, user, password, db_name, target, all_databases, port comp_prog_path = module.get_bin_path('bzip2', required=True) elif os.path.splitext(target)[-1] == '.xz': comp_prog_path = module.get_bin_path('xz', required=True) - elif os.path.splitext(target)[-1] == '.zst': - comp_prog_path = module.get_bin_path('zstd', required=True) if comp_prog_path: # The line below is for returned data only: executed_commands.append('%s -dc %s | %s' % (comp_prog_path, target, cmd)) @@ -790,8 +768,8 @@ def main(): rc, stdout, stderr = db_import(module, login_host, login_user, login_password, db, target, all_databases, - login_port, config_file, server_implementation, - server_version, socket, ssl_cert, ssl_key, ssl_ca, + login_port, config_file, + socket, ssl_cert, ssl_key, ssl_ca, encoding, force, use_shell, unsafe_login_password, restrict_config_file, check_implicit_admin) if rc != 0: diff --git a/plugins/modules/mysql_info.py b/plugins/modules/mysql_info.py index 2360d01..8c3845d 100644 --- a/plugins/modules/mysql_info.py +++ b/plugins/modules/mysql_info.py @@ -4,7 +4,6 @@ # Copyright: (c) 2019, Andrew Klychkov (@Andersson007) # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - from __future__ import absolute_import, division, print_function __metaclass__ = type @@ -319,7 +318,6 @@ from ansible_collections.community.mysql.plugins.module_utils.user import ( get_resource_limits, get_existing_authentication, get_user_implementation, - user_is_locked, ) from ansible.module_utils.six import iteritems from ansible.module_utils._text import to_native @@ -654,10 +652,8 @@ class MySQL_Info(object): if authentications: output_dict.update(authentications[0]) - if line.get('is_role') and line['is_role'] == 'N': - output_dict['locked'] = user_is_locked(self.cursor, user, host) - # TODO password_option + # TODO lock_option # but both are not supported by mysql_user atm. So no point yet. output.append(output_dict) diff --git a/plugins/modules/mysql_query.py b/plugins/modules/mysql_query.py index 35beeb3..2cdf096 100644 --- a/plugins/modules/mysql_query.py +++ b/plugins/modules/mysql_query.py @@ -62,6 +62,7 @@ author: - Andrew Klychkov (@Andersson007) extends_documentation_fragment: - community.mysql.mysql + ''' EXAMPLES = r''' @@ -116,18 +117,8 @@ rowcount: returned: changed type: list sample: [5, 1] -execution_time_ms: - description: - - A list containing execution time per query in milliseconds. - - The measurements are done right before and after passing - the query to the driver for execution. - returned: success - type: list - sample: [7104, 85] - version_added: '3.12.0' ''' -import time import warnings from ansible.module_utils.basic import AnsibleModule @@ -148,18 +139,6 @@ DDL_QUERY_KEYWORDS = ('CREATE', 'DROP', 'ALTER', 'RENAME', 'TRUNCATE') # Module execution. # - -def execute_and_return_time(cursor, query, args): - # Measure query execution time in milliseconds - start_time = time.perf_counter() - - cursor.execute(query, args) - - # Calculate the execution time rounding it to 4 decimal places - exec_time_ms = round((time.perf_counter() - start_time) * 1000, 4) - return cursor, exec_time_ms - - def main(): argument_spec = mysql_common_argument_spec() argument_spec.update( @@ -234,7 +213,6 @@ def main(): query_result = [] executed_queries = [] rowcount = [] - execution_time_ms = [] already_exists = False for q in query: @@ -245,8 +223,7 @@ def main(): category=mysql_driver.Warning) try: - cursor, exec_time_ms = execute_and_return_time(cursor, q, arguments) - execution_time_ms.append(exec_time_ms) + cursor.execute(q, arguments) except mysql_driver.Warning: # When something is run with IF NOT EXISTS # and there's "already exists" MySQL warning, @@ -303,7 +280,6 @@ def main(): 'executed_queries': executed_queries, 'query_result': query_result, 'rowcount': rowcount, - 'execution_time_ms': execution_time_ms, } # Exit: diff --git a/plugins/modules/mysql_replication.py b/plugins/modules/mysql_replication.py index b902da0..35659d3 100644 --- a/plugins/modules/mysql_replication.py +++ b/plugins/modules/mysql_replication.py @@ -284,6 +284,7 @@ EXAMPLES = r''' community.mysql.mysql_replication: mode: changeprimary fail_on_error: true + ''' RETURN = r''' diff --git a/plugins/modules/mysql_role.py b/plugins/modules/mysql_role.py index 382445c..c88392b 100644 --- a/plugins/modules/mysql_role.py +++ b/plugins/modules/mysql_role.py @@ -930,12 +930,11 @@ class Role(): set_default_role_all=set_default_role_all) if privs: - result = user_mod(cursor=self.cursor, user=self.name, host=self.host, - host_all=None, password=None, encrypted=None, plugin=None, - plugin_auth_string=None, plugin_hash_string=None, salt=None, - new_priv=privs, append_privs=append_privs, subtract_privs=subtract_privs, - attributes=None, tls_requires=None, module=self.module, password_expire=None, - password_expire_interval=None, role=True, maria_role=self.is_mariadb) + result = user_mod(self.cursor, self.name, self.host, + None, None, None, None, None, None, None, + privs, append_privs, subtract_privs, None, None, + self.module, None, None, role=True, + maria_role=self.is_mariadb) changed = result['changed'] if admin: diff --git a/plugins/modules/mysql_user.py b/plugins/modules/mysql_user.py index 2a5855c..cf210a3 100644 --- a/plugins/modules/mysql_user.py +++ b/plugins/modules/mysql_user.py @@ -189,15 +189,6 @@ options: fields names in privileges. type: bool version_added: '3.8.0' - - locked: - description: - - Lock account to prevent connections using it. - - This is primarily used for creating a user that will act as a DEFINER on stored procedures. - - If not specified leaves the lock state as is (for a new user creates unlocked). - type: bool - version_added: '3.13.0' - attributes: description: - "Create, update, or delete user attributes (arbitrary 'key: value' comments) for the user." @@ -234,7 +225,6 @@ author: - Lukasz Tomaszkiewicz (@tomaszkiewicz) - kmarse (@kmarse) - Laurent Indermühle (@laurent-indermuehle) -- E.S. Rosenberg (@Keeper-of-the-Keys) extends_documentation_fragment: - community.mysql.mysql @@ -279,7 +269,7 @@ EXAMPLES = r''' priv: '*.*:ALL,GRANT' state: present session_vars: - wsrep_on: 'off' + wsrep_on: off - name: Create user with password, all database privileges and 'WITH GRANT OPTION' in db1 and db2 community.mysql.mysql_user: @@ -410,13 +400,6 @@ EXAMPLES = r''' priv: 'db1.*': DELETE -- name: Create locked user to act as a definer on procedures - community.mysql.mysql_user: - name: readonly_procedures_locked - locked: true - priv: - db1.*: SELECT - # Example .my.cnf file for setting the root password # [client] # user=root @@ -487,7 +470,6 @@ def main(): column_case_sensitive=dict(type='bool', default=None), # TODO 4.0.0 add default=True password_expire=dict(type='str', choices=['now', 'never', 'default', 'interval'], no_log=True), password_expire_interval=dict(type='int', required_if=[('password_expire', 'interval', True)], no_log=True), - locked=dict(type='bool'), ) module = AnsibleModule( argument_spec=argument_spec, @@ -528,7 +510,6 @@ def main(): column_case_sensitive = module.params["column_case_sensitive"] password_expire = module.params["password_expire"] password_expire_interval = module.params["password_expire_interval"] - locked = module.boolean(module.params['locked']) 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)) @@ -596,15 +577,13 @@ def main(): result = user_mod(cursor, user, host, host_all, password, encrypted, plugin, plugin_hash_string, plugin_auth_string, salt, priv, append_privs, subtract_privs, attributes, tls_requires, module, - password_expire, password_expire_interval, locked=locked) + password_expire, password_expire_interval) else: - result = user_mod(cursor=cursor, user=user, host=host, host_all=host_all, password=None, - encrypted=encrypted, plugin=None, plugin_hash_string=None, plugin_auth_string=None, - salt=None, new_priv=priv, append_privs=append_privs, subtract_privs=subtract_privs, - attributes=attributes, tls_requires=tls_requires, module=module, - password_expire=password_expire, password_expire_interval=password_expire_interval, - locked=locked) + result = user_mod(cursor, user, host, host_all, None, encrypted, + None, None, None, None, + priv, append_privs, subtract_privs, attributes, tls_requires, module, + password_expire, password_expire_interval) changed = result['changed'] msg = result['msg'] password_changed = result['password_changed'] @@ -622,7 +601,7 @@ def main(): result = user_add(cursor, user, host, host_all, password, encrypted, plugin, plugin_hash_string, plugin_auth_string, salt, priv, attributes, tls_requires, reuse_existing_password, module, - password_expire, password_expire_interval, locked=locked) + password_expire, password_expire_interval) changed = result['changed'] password_changed = result['password_changed'] final_attributes = result['attributes'] diff --git a/tests/integration/targets/test_mysql_info/tasks/filter_users_info.yml b/tests/integration/targets/test_mysql_info/tasks/filter_users_info.yml index 558d309..36508f3 100644 --- a/tests/integration/targets/test_mysql_info/tasks/filter_users_info.yml +++ b/tests/integration/targets/test_mysql_info/tasks/filter_users_info.yml @@ -261,7 +261,6 @@ resource_limits: "{{ item.resource_limits | default(omit) }}" column_case_sensitive: true state: present - locked: "{{ item.locked | default(omit) }}" loop: "{{ result.users_info }}" loop_control: label: "{{ item.name }}@{{ item.host }}" @@ -276,7 +275,6 @@ - item.name != 'mariadb.sys' - item.name != 'mysql.sys' - item.name != 'mysql.infoschema' - - item.name != 'mysql.session' # ================================== Cleanup ============================ diff --git a/tests/integration/targets/test_mysql_query/tasks/mysql_query_initial.yml b/tests/integration/targets/test_mysql_query/tasks/mysql_query_initial.yml index 310f925..fbf5ca8 100644 --- a/tests/integration/targets/test_mysql_query/tasks/mysql_query_initial.yml +++ b/tests/integration/targets/test_mysql_query/tasks/mysql_query_initial.yml @@ -35,7 +35,6 @@ that: - result is changed - result.executed_queries == ['CREATE TABLE {{ test_table1 }} (id int)'] - - result.execution_time_ms[0] > 0 - name: Insert test data mysql_query: @@ -53,8 +52,6 @@ - result is changed - result.rowcount == [2, 1] - result.executed_queries == ['INSERT INTO {{ test_table1 }} VALUES (1), (2)', 'INSERT INTO {{ test_table1 }} VALUES (3)'] - - result.execution_time_ms[0] > 0 - - result.execution_time_ms[1] > 0 - name: Check data in {{ test_table1 }} mysql_query: diff --git a/tests/integration/targets/test_mysql_user/tasks/main.yml b/tests/integration/targets/test_mysql_user/tasks/main.yml index 7212886..9244570 100644 --- a/tests/integration/targets/test_mysql_user/tasks/main.yml +++ b/tests/integration/targets/test_mysql_user/tasks/main.yml @@ -305,7 +305,3 @@ - name: Mysql_user - test update_password ansible.builtin.import_tasks: file: test_update_password.yml - - - name: Mysql_user - test user_locking - ansible.builtin.import_tasks: - file: test_user_locking.yml diff --git a/tests/integration/targets/test_mysql_user/tasks/test_user_locking.yml b/tests/integration/targets/test_mysql_user/tasks/test_user_locking.yml deleted file mode 100644 index 3990610..0000000 --- a/tests/integration/targets/test_mysql_user/tasks/test_user_locking.yml +++ /dev/null @@ -1,200 +0,0 @@ ---- - -- vars: - mysql_parameters: &mysql_params - login_user: '{{ mysql_user }}' - login_password: '{{ mysql_password }}' - login_host: '{{ mysql_host }}' - login_port: '{{ mysql_primary_port }}' - - block: - - # ========================= Prepare ======================================= - - name: Mysql_user Lock user | Create a test database - community.mysql.mysql_db: - <<: *mysql_params - name: mysql_lock_user_test - state: present - - # ========================== Tests ======================================== - - - name: Mysql_user Lock user | create locked | Create test user - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - password: 'msandbox' - locked: true - priv: - 'mysql_lock_user_test.*': 'SELECT' - - - name: Mysql_user Lock user | create locked | Assert that test user is locked - community.mysql.mysql_query: - <<: *mysql_params - query: - - SHOW CREATE USER 'mysql_locked_user'@'localhost' - register: locked_user_creation - failed_when: - - locked_user_creation.query_result[0][0] is not search('ACCOUNT LOCK') - - - name: 'Mysql_user Lock user | create locked | Idempotence check' - check_mode: true - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - locked: true - priv: - 'mysql_lock_user_test.*': 'SELECT' - register: idempotence_check - failed_when: idempotence_check is changed - - - name: 'Mysql_user Lock user | create locked | Check that absense of locked does not unlock the user' - check_mode: true - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - priv: - 'mysql_lock_user_test.*': 'SELECT' - register: idempotence_check - failed_when: idempotence_check is changed - - - name: 'Mysql_user Lock user | create locked | Unlock test user check_mode: true' - check_mode: true - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - locked: false - priv: - 'mysql_lock_user_test.*': 'SELECT' - - - name: Mysql_user Lock user | create locked | Assert that test user is locked - community.mysql.mysql_query: - <<: *mysql_params - query: - - SHOW CREATE USER 'mysql_locked_user'@'localhost' - register: locked_user_creation - failed_when: - - locked_user_creation.query_result[0][0] is not search('ACCOUNT LOCK') - - - name: Mysql_user Lock user | create locked | Unlock test user - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - locked: false - priv: - 'mysql_lock_user_test.*': 'SELECT' - - - name: Mysql_user Lock user | create locked | Assert that test user is not locked - community.mysql.mysql_query: - <<: *mysql_params - query: - - SHOW CREATE USER 'mysql_locked_user'@'localhost' - register: locked_user_creation - failed_when: - - locked_user_creation.query_result[0][0] is search('ACCOUNT LOCK') - - - name: Mysql_user Lock user | create locked | Remove test user - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - state: absent - - - name: Mysql_user Lock user | create unlocked | Create test user - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - password: 'msandbox' - locked: false - priv: - 'mysql_lock_user_test.*': 'SELECT' - - - name: Mysql_user Lock user | create unlocked | Assert that test user is not locked - community.mysql.mysql_query: - <<: *mysql_params - query: - - SHOW CREATE USER 'mysql_locked_user'@'localhost' - register: locked_user_creation - failed_when: - - locked_user_creation.query_result[0][0] is search('ACCOUNT LOCK') - - - name: 'Mysql_user Lock user | create unlocked | Idempotence check' - check_mode: true - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - locked: false - priv: - 'mysql_lock_user_test.*': 'SELECT' - register: idempotence_check - failed_when: idempotence_check is changed - - - name: 'Mysql_user Lock user | create unlocked | Lock test user check_mode: true' - check_mode: true - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - locked: true - priv: - 'mysql_lock_user_test.*': 'SELECT' - - - name: Mysql_user Lock user | create unlocked | Assert that test user is not locked - community.mysql.mysql_query: - <<: *mysql_params - query: - - SHOW CREATE USER 'mysql_locked_user'@'localhost' - register: locked_user_creation - failed_when: - - locked_user_creation.query_result[0][0] is search('ACCOUNT LOCK') - - - name: Mysql_user Lock user | create unlocked | Lock test user - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - locked: true - priv: - 'mysql_lock_user_test.*': 'SELECT' - - - name: Mysql_user Lock user | create unlocked | Assert that test user is locked - community.mysql.mysql_query: - <<: *mysql_params - query: - - SHOW CREATE USER 'mysql_locked_user'@'localhost' - register: locked_user_creation - failed_when: - - locked_user_creation.query_result[0][0] is not search('ACCOUNT LOCK') - - - name: Mysql_user Lock user | create unlocked | Remove test user - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - state: absent - - - name: Mysql_user Lock user | create default | Create test user - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - password: 'msandbox' - priv: - 'mysql_lock_user_test.*': 'SELECT' - - - name: Mysql_user Lock user | create default | Assert that test user is not locked - community.mysql.mysql_query: - <<: *mysql_params - query: - - SHOW CREATE USER 'mysql_locked_user'@'localhost' - register: locked_user_creation - failed_when: - - locked_user_creation.query_result[0][0] is search('ACCOUNT LOCK') - - - name: Mysql_user Lock user | create default | Remove test user - community.mysql.mysql_user: - <<: *mysql_params - name: mysql_locked_user - state: absent - - # ========================= Teardown ====================================== - - - name: Mysql_user Lock user | Delete test database - community.mysql.mysql_db: - <<: *mysql_params - name: mysql_lock_user_test - state: absent