diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 4ec1cdc8e1..671278c4d6 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -64,10 +64,6 @@ files: $doc_fragments/hwc.py: maintainers: $team_huawei labels: hwc - $doc_fragments/mysql.py: - maintainers: $team_mysql - labels: database mysql - keywords: mariadb $doc_fragments/postgres.py: maintainers: $team_postgresql labels: postgres postgresql @@ -155,10 +151,6 @@ files: $module_utils/memset.py: maintainers: glitchcrab labels: cloud memset - $module_utils/mysql.py: - maintainers: $team_mysql - labels: database mysql - keywords: mariadb $module_utils/net_tools/nios/api.py: maintainers: $team_networking sganesh-infoblox labels: infoblox networking @@ -498,22 +490,6 @@ files: authors: vedit maintainers: Jmainguy kenichi-ogawa-1988 labels: mssql_db - $modules/database/mysql/mysql_db.py: - authors: ansible - maintainers: $team_mysql - $modules/database/mysql/: - authors: Andersson007 - maintainers: Alexander198961 Xyon bmalynovytch bmildren kurtdavis michaelcoburn oneiroi tolland - keywords: mariadb - $modules/database/mysql/mysql_replication.py: - authors: Andersson007 banyek - $modules/database/mysql/mysql_user.py: - authors: Jmainguy bmalynovytch - maintainers: Alexander198961 Andersson007 Xyon bmildren kurtdavis michaelcoburn oneiroi tolland - ignore: tomaszkiewicz - $modules/database/mysql/mysql_variables.py: - authors: banyek - maintainers: $team_mysql $modules/database/postgresql/postgresql_db.py: authors: ansible maintainers: $team_postgresql @@ -1341,7 +1317,6 @@ macros: team_linode: InTheCloudDan decentral1se displague rmcintosh team_macos: akasurde kyleabenson martinm82 team_manageiq: abellotti cben gtanzillo yaacov zgalor - team_mysql: Alexander198961 Andersson007 Xyon bmalynovytch bmildren kurtdavis michaelcoburn oneiroi tolland team_netapp: amit0701 carchi8py hulquest lmprice lonico ndswartz schmots1 team_netscaler: chiradeep giorgos-nikolopoulos team_netvisor: Qalthos amitsi csharpe-pn pdam preetiparasar diff --git a/changelogs/fragments/609-mysql_user_fix_overriding_password_to_the_same.yml b/changelogs/fragments/609-mysql_user_fix_overriding_password_to_the_same.yml deleted file mode 100644 index 9ad0c083e5..0000000000 --- a/changelogs/fragments/609-mysql_user_fix_overriding_password_to_the_same.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- mysql_user - fix overriding password to the same (https://github.com/ansible-collections/community.general/issues/543). diff --git a/changelogs/fragments/618-mysql_user_add_missed_privileges.yml b/changelogs/fragments/618-mysql_user_add_missed_privileges.yml deleted file mode 100644 index cf7a583c0e..0000000000 --- a/changelogs/fragments/618-mysql_user_add_missed_privileges.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- mysql_user - add missed privileges to support (https://github.com/ansible-collections/community.general/issues/617). diff --git a/changelogs/fragments/mysql.yml b/changelogs/fragments/mysql.yml new file mode 100644 index 0000000000..acfc578125 --- /dev/null +++ b/changelogs/fragments/mysql.yml @@ -0,0 +1,2 @@ +removed_features: +- "mysql_* - all MySQL modules have been moved to the ``community.mysql`` collection. A redirection is active, which will be removed in version 2.0.0 (https://github.com/ansible-collections/community.general/pull/633)." diff --git a/meta/runtime.yml b/meta/runtime.yml index 1ff5ba7fc6..a6e9b572a9 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -286,6 +286,36 @@ plugin_routing: deprecation: removal_version: 3.0.0 warning_text: see plugin documentation for details + mysql_db: + deprecation: + removal_version: 2.0.0 + warning_text: The mysql_db module has been moved to the community.mysql collection. + redirect: community.mysql.mysql_db + mysql_info: + deprecation: + removal_version: 2.0.0 + warning_text: The mysql_info module has been moved to the community.mysql collection. + redirect: community.mysql.mysql_info + mysql_query: + deprecation: + removal_version: 2.0.0 + warning_text: The mysql_query module has been moved to the community.mysql collection. + redirect: community.mysql.mysql_query + mysql_replication: + deprecation: + removal_version: 2.0.0 + warning_text: The mysql_replication module has been moved to the community.mysql collection. + redirect: community.mysql.mysql_replication + mysql_user: + deprecation: + removal_version: 2.0.0 + warning_text: The mysql_user module has been moved to the community.mysql collection. + redirect: community.mysql.mysql_user + mysql_variables: + deprecation: + removal_version: 2.0.0 + warning_text: The mysql_variables module has been moved to the community.mysql collection. + redirect: community.mysql.mysql_variables ovirt: deprecation: removal_version: 3.0.0 @@ -627,6 +657,11 @@ plugin_routing: removal_version: 2.0.0 warning_text: The digital_ocean docs_fragment has been moved to the community.digitalocean collection. redirect: community.digitalocean.digital_ocean + mysql: + deprecation: + removal_version: 2.0.0 + warning_text: The mysql docs_fragment has been moved to the community.mysql collection. + redirect: community.mysql.mysql proxysql: deprecation: removal_version: 2.0.0 @@ -638,3 +673,8 @@ plugin_routing: removal_version: 2.0.0 warning_text: The digital_ocean module_utils has been moved to the community.digitalocean collection. redirect: community.digitalocean.digital_ocean + mysql: + deprecation: + removal_version: 2.0.0 + warning_text: The mysql module_utils has been moved to the community.mysql collection. + redirect: community.mysql.mysql diff --git a/plugins/doc_fragments/mysql.py b/plugins/doc_fragments/mysql.py deleted file mode 100644 index f5254064a9..0000000000 --- a/plugins/doc_fragments/mysql.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Jonathan Mainguy -# 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 - - -class ModuleDocFragment(object): - - # Standard mysql documentation fragment - DOCUMENTATION = r''' -options: - login_user: - description: - - The username used to authenticate with. - type: str - login_password: - description: - - The password used to authenticate with. - type: str - login_host: - description: - - Host running the database. - - In some cases for local connections the I(login_unix_socket=/path/to/mysqld/socket), - that is usually C(/var/run/mysqld/mysqld.sock), needs to be used instead of I(login_host=localhost). - type: str - default: localhost - login_port: - description: - - Port of the MySQL server. Requires I(login_host) be defined as other than localhost if login_port is used. - type: int - default: 3306 - login_unix_socket: - description: - - The path to a Unix domain socket for local connections. - type: str - connect_timeout: - description: - - The connection timeout when connecting to the MySQL server. - type: int - default: 30 - config_file: - description: - - Specify a config file from which user and password are to be read. - type: path - default: '~/.my.cnf' - ca_cert: - description: - - The path to a Certificate Authority (CA) certificate. This option, if used, must specify the same certificate - as used by the server. - type: path - aliases: [ ssl_ca ] - client_cert: - description: - - The path to a client public key certificate. - type: path - aliases: [ ssl_cert ] - client_key: - description: - - The path to the client private key. - type: path - aliases: [ ssl_key ] -requirements: - - PyMySQL (Python 2.7 and Python 3.X), or - - MySQLdb (Python 2.x) -notes: - - Requires the PyMySQL (Python 2.7 and Python 3.X) or MySQL-python (Python 2.X) package on the remote host. - The Python package may be installed with apt-get install python-pymysql (Ubuntu; see M(ansible.builtin.apt)) or - yum install python2-PyMySQL (RHEL/CentOS/Fedora; see M(ansible.builtin.yum)). You can also use dnf install python2-PyMySQL - for newer versions of Fedora; see M(ansible.builtin.dnf). - - Both C(login_password) and C(login_user) are required when you are - passing credentials. If none are present, the module will attempt to read - the credentials from C(~/.my.cnf), and finally fall back to using the MySQL - default login of 'root' with no password. - - If there are problems with local connections, using I(login_unix_socket=/path/to/mysqld/socket) - instead of I(login_host=localhost) might help. As an example, the default MariaDB installation of version 10.4 - and later uses the unix_socket authentication plugin by default that - without using I(login_unix_socket=/var/run/mysqld/mysqld.sock) (the default path) - causes the error ``Host '127.0.0.1' is not allowed to connect to this MariaDB server``. -''' diff --git a/plugins/module_utils/mysql.py b/plugins/module_utils/mysql.py deleted file mode 100644 index b5beb02751..0000000000 --- a/plugins/module_utils/mysql.py +++ /dev/null @@ -1,110 +0,0 @@ -# This code is part of Ansible, but is an independent component. -# This particular file snippet, and this file snippet only, is BSD licensed. -# Modules you write using this snippet, which is embedded dynamically by Ansible -# still belong to the author of the module, and may assign their own license -# to the complete work. -# -# Copyright (c), Jonathan Mainguy , 2015 -# Most of this was originally added by Sven Schliesing @muffl0n in the mysql_user.py module -# -# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import os - -from ansible.module_utils.six.moves import configparser - -try: - import pymysql as mysql_driver - _mysql_cursor_param = 'cursor' -except ImportError: - try: - import MySQLdb as mysql_driver - import MySQLdb.cursors - _mysql_cursor_param = 'cursorclass' - except ImportError: - mysql_driver = None - -mysql_driver_fail_msg = 'The PyMySQL (Python 2.7 and Python 3.X) or MySQL-python (Python 2.X) module is required.' - - -def parse_from_mysql_config_file(cnf): - cp = configparser.ConfigParser() - cp.read(cnf) - return cp - - -def mysql_connect(module, login_user=None, login_password=None, config_file='', ssl_cert=None, - ssl_key=None, ssl_ca=None, db=None, cursor_class=None, - connect_timeout=30, autocommit=False, config_overrides_defaults=False): - config = {} - - if config_file and os.path.exists(config_file): - config['read_default_file'] = config_file - cp = parse_from_mysql_config_file(config_file) - # Override some commond defaults with values from config file if needed - if cp and cp.has_section('client') and config_overrides_defaults: - try: - module.params['login_host'] = cp.get('client', 'host', fallback=module.params['login_host']) - module.params['login_port'] = cp.getint('client', 'port', fallback=module.params['login_port']) - except Exception as e: - if "got an unexpected keyword argument 'fallback'" in e.message: - module.fail_json('To use config_overrides_defaults, ' - 'it needs Python 3.5+ as the default interpreter on a target host') - - if ssl_ca is not None or ssl_key is not None or ssl_cert is not None: - config['ssl'] = {} - - if module.params['login_unix_socket']: - config['unix_socket'] = module.params['login_unix_socket'] - else: - config['host'] = module.params['login_host'] - config['port'] = module.params['login_port'] - - # If login_user or login_password are given, they should override the - # config file - if login_user is not None: - config['user'] = login_user - if login_password is not None: - config['passwd'] = login_password - if ssl_cert is not None: - config['ssl']['cert'] = ssl_cert - if ssl_key is not None: - config['ssl']['key'] = ssl_key - if ssl_ca is not None: - config['ssl']['ca'] = ssl_ca - if db is not None: - config['db'] = db - if connect_timeout is not None: - config['connect_timeout'] = connect_timeout - - if _mysql_cursor_param == 'cursor': - # In case of PyMySQL driver: - db_connection = mysql_driver.connect(autocommit=autocommit, **config) - else: - # In case of MySQLdb driver - db_connection = mysql_driver.connect(**config) - if autocommit: - db_connection.autocommit(True) - - if cursor_class == 'DictCursor': - return db_connection.cursor(**{_mysql_cursor_param: mysql_driver.cursors.DictCursor}), db_connection - else: - return db_connection.cursor(), db_connection - - -def mysql_common_argument_spec(): - return dict( - login_user=dict(type='str', default=None), - login_password=dict(type='str', no_log=True), - login_host=dict(type='str', default='localhost'), - login_port=dict(type='int', default=3306), - login_unix_socket=dict(type='str'), - config_file=dict(type='path', default='~/.my.cnf'), - connect_timeout=dict(type='int', default=30), - client_cert=dict(type='path', aliases=['ssl_cert']), - client_key=dict(type='path', aliases=['ssl_key']), - ca_cert=dict(type='path', aliases=['ssl_ca']), - ) diff --git a/plugins/modules/database/mysql/mysql_db.py b/plugins/modules/database/mysql/mysql_db.py deleted file mode 100644 index 111b04aaa4..0000000000 --- a/plugins/modules/database/mysql/mysql_db.py +++ /dev/null @@ -1,727 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2012, Mark Theunissen -# Sponsored by Four Kitchens http://fourkitchens.com. -# 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 - -DOCUMENTATION = r''' ---- -module: mysql_db -short_description: Add or remove MySQL databases from a remote host -description: -- Add or remove MySQL databases from a remote host. -options: - name: - description: - - Name of the database to add or remove. - - I(name=all) may only be provided if I(state) is C(dump) or C(import). - - List of databases is provided with I(state=dump), I(state=present) and I(state=absent). - - If I(name=all) it works like --all-databases option for mysqldump (Added in 2.0). - required: true - type: list - elements: str - aliases: [db] - state: - description: - - The database state - type: str - default: present - choices: ['absent', 'dump', 'import', 'present'] - collation: - description: - - Collation mode (sorting). This only applies to new table/databases and - does not update existing ones, this is a limitation of MySQL. - type: str - default: '' - encoding: - description: - - Encoding mode to use, examples include C(utf8) or C(latin1_swedish_ci), - at creation of database, dump or importation of sql script. - type: str - default: '' - 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)) and - xz (Added in 2.0) compressed files are supported. - type: path - single_transaction: - description: - - Execute the dump in a single transaction. - type: bool - default: no - quick: - description: - - Option used for dumping large tables. - type: bool - default: yes - ignore_tables: - description: - - A list of table names that will be ignored in the dump - of the form database_name.table_name. - type: list - elements: str - required: no - default: [] - hex_blob: - description: - - Dump binary columns using hexadecimal notation. - required: no - default: no - type: bool - version_added: '0.2.0' - force: - description: - - Continue dump or import even if we get an SQL error. - - Used only when I(state) is C(dump) or C(import). - required: no - type: bool - default: no - version_added: '0.2.0' - master_data: - description: - - Option to dump a master replication server to produce a dump file - that can be used to set up another server as a slave of the master. - - C(0) to not include master data. - - C(1) to generate a 'CHANGE MASTER TO' statement - required on the slave to start the replication process. - - C(2) to generate a commented 'CHANGE MASTER TO'. - - Can be used when I(state=dump). - required: no - type: int - choices: [0, 1, 2] - default: 0 - version_added: '0.2.0' - skip_lock_tables: - description: - - Skip locking tables for read. Used when I(state=dump), ignored otherwise. - required: no - type: bool - default: no - version_added: '0.2.0' - dump_extra_args: - description: - - Provide additional arguments for mysqldump. - Used when I(state=dump) only, ignored otherwise. - required: no - type: str - version_added: '0.2.0' - use_shell: - description: - - Used to prevent C(Broken pipe) errors when the imported I(target) file is compressed. - - If C(yes), the module will internally execute commands via a shell. - - Used when I(state=import), ignored otherwise. - required: no - type: bool - default: no - version_added: '0.2.0' - unsafe_login_password: - description: - - If C(no), the module will safely use a shell-escaped version of the I(login_password) value. - - It makes sense to use C(yes) only if there are special symbols in the value and errors C(Access denied) occur. - - Used only when I(state) is C(import) or C(dump) and I(login_password) is passed, ignored otherwise. - type: bool - default: no - version_added: '0.2.0' - restrict_config_file: - description: - - Read only passed I(config_file). - - When I(state) is C(dump) or C(import), by default the module passes I(config_file) parameter - using C(--defaults-extra-file) command-line argument to C(mysql/mysqldump) utilities - under the hood that read named option file in addition to usual option files. - - If this behavior is undesirable, use C(yes) to read only named option file. - type: bool - default: no - version_added: '0.2.0' - check_implicit_admin: - description: - - Check if mysql allows login as root/nopassword before trying supplied credentials. - - If success, passed I(login_user)/I(login_password) will be ignored. - type: bool - default: no - version_added: '0.2.0' - config_overrides_defaults: - description: - - If C(yes), connection parameters from I(config_file) will override the default - values of I(login_host) and I(login_port) parameters. - - Used when I(stat) is C(present) or C(absent), ignored otherwise. - - It needs Python 3.5+ as the default interpreter on a target host. - type: bool - default: no - version_added: '0.2.0' - -seealso: -- module: community.general.mysql_info -- module: community.general.mysql_variables -- module: community.general.mysql_user -- module: community.general.mysql_replication -- name: MySQL command-line client reference - description: Complete reference of the MySQL command-line client documentation. - link: https://dev.mysql.com/doc/refman/8.0/en/mysql.html -- name: mysqldump reference - description: Complete reference of the ``mysqldump`` client utility documentation. - link: https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html -- name: CREATE DATABASE reference - description: Complete reference of the CREATE DATABASE command documentation. - link: https://dev.mysql.com/doc/refman/8.0/en/create-database.html -- name: DROP DATABASE reference - description: Complete reference of the DROP DATABASE command documentation. - link: https://dev.mysql.com/doc/refman/8.0/en/drop-database.html -author: "Ansible Core Team" -requirements: - - mysql (command line binary) - - mysqldump (command line binary) -notes: - - Requires the mysql and mysqldump binaries on the remote host. - - This module is B(not idempotent) when I(state) is C(import), - and will import the dump file each time if run more than once. -extends_documentation_fragment: -- community.general.mysql - -''' - -EXAMPLES = r''' -- name: Create a new database with name 'bobdata' - mysql_db: - name: bobdata - state: present - -- name: Create new databases with names 'foo' and 'bar' - mysql_db: - name: - - foo - - bar - state: present - -# Copy database dump file to remote host and restore it to database 'my_db' -- name: Copy database dump file - copy: - src: dump.sql.bz2 - dest: /tmp - -- name: Restore database - mysql_db: - name: my_db - state: import - target: /tmp/dump.sql.bz2 - -- name: Restore database ignoring errors - mysql_db: - name: my_db - state: import - target: /tmp/dump.sql.bz2 - force: yes - -- name: Dump multiple databases - mysql_db: - state: dump - name: db_1,db_2 - target: /tmp/dump.sql - -- name: Dump multiple databases - mysql_db: - state: dump - name: - - db_1 - - db_2 - target: /tmp/dump.sql - -- name: Dump all databases to hostname.sql - mysql_db: - state: dump - name: all - target: /tmp/dump.sql - -- name: Dump all databases to hostname.sql including master data - mysql_db: - state: dump - name: all - target: /tmp/dump.sql - master_data: 1 - -# Import of sql script with encoding option -- name: > - Import dump.sql with specific latin1 encoding, - similar to mysql -u --default-character-set=latin1 -p < dump.sql - mysql_db: - state: import - name: all - encoding: latin1 - target: /tmp/dump.sql - -# Dump of database with encoding option -- name: > - Dump of Databse with specific latin1 encoding, - similar to mysqldump -u --default-character-set=latin1 -p - mysql_db: - state: dump - name: db_1 - encoding: latin1 - target: /tmp/dump.sql - -- name: Delete database with name 'bobdata' - mysql_db: - name: bobdata - state: absent - -- name: Make sure there is neither a database with name 'foo', nor one with name 'bar' - mysql_db: - name: - - foo - - bar - state: absent - -# Dump database with argument not directly supported by this module -# using dump_extra_args parameter -- name: Dump databases without including triggers - mysql_db: - state: dump - name: foo - target: /tmp/dump.sql - dump_extra_args: --skip-triggers - -- name: Try to create database as root/nopassword first. If not allowed, pass the credentials - mysql_db: - check_implicit_admin: yes - login_user: bob - login_password: 123456 - name: bobdata - state: present -''' - -RETURN = r''' -db: - description: Database names in string format delimited by white space. - returned: always - type: str - sample: "foo bar" -db_list: - description: List of database names. - returned: always - type: list - sample: ["foo", "bar"] -executed_commands: - description: List of commands which tried to run. - returned: if executed - type: list - sample: ["CREATE DATABASE acme"] - version_added: '0.2.0' -''' - -import os -import subprocess -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.community.general.plugins.module_utils.database import mysql_quote_identifier -from ansible_collections.community.general.plugins.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg -from ansible.module_utils.six.moves import shlex_quote -from ansible.module_utils._text import to_native - -executed_commands = [] - -# =========================================== -# MySQL module specific support methods. -# - - -def db_exists(cursor, db): - res = 0 - for each_db in db: - res += cursor.execute("SHOW DATABASES LIKE %s", (each_db.replace("_", r"\_"),)) - return res == len(db) - - -def db_delete(cursor, db): - if not db: - return False - for each_db in db: - query = "DROP DATABASE %s" % mysql_quote_identifier(each_db, 'database') - executed_commands.append(query) - cursor.execute(query) - return True - - -def db_dump(module, host, user, password, db_name, target, all_databases, port, - config_file, socket=None, ssl_cert=None, ssl_key=None, ssl_ca=None, - single_transaction=None, quick=None, ignore_tables=None, hex_blob=None, - 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): - 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 += " --defaults-file=%s" % shlex_quote(config_file) - else: - cmd += " --defaults-extra-file=%s" % shlex_quote(config_file) - - if check_implicit_admin: - cmd += " --user=root --password=''" - else: - if user is not None: - cmd += " --user=%s" % shlex_quote(user) - - if password is not None: - if not unsafe_password: - cmd += " --password=%s" % shlex_quote(password) - else: - cmd += " --password=%s" % password - - if ssl_cert is not None: - cmd += " --ssl-cert=%s" % shlex_quote(ssl_cert) - if ssl_key is not None: - cmd += " --ssl-key=%s" % shlex_quote(ssl_key) - if ssl_ca is not None: - cmd += " --ssl-ca=%s" % shlex_quote(ssl_ca) - if force: - cmd += " --force" - if socket is not None: - cmd += " --socket=%s" % shlex_quote(socket) - else: - cmd += " --host=%s --port=%i" % (shlex_quote(host), port) - - if all_databases: - cmd += " --all-databases" - elif len(db_name) > 1: - cmd += " --databases {0}".format(' '.join(db_name)) - else: - cmd += " %s" % shlex_quote(' '.join(db_name)) - - if skip_lock_tables: - cmd += " --skip-lock-tables" - if (encoding is not None) and (encoding != ""): - cmd += " --default-character-set=%s" % shlex_quote(encoding) - if single_transaction: - cmd += " --single-transaction=true" - if quick: - cmd += " --quick" - if ignore_tables: - for an_ignored_table in ignore_tables: - cmd += " --ignore-table={0}".format(an_ignored_table) - if hex_blob: - cmd += " --hex-blob" - if master_data: - cmd += " --master-data=%s" % master_data - if dump_extra_args is not None: - cmd += " " + dump_extra_args - - path = None - if os.path.splitext(target)[-1] == '.gz': - path = module.get_bin_path('gzip', True) - elif os.path.splitext(target)[-1] == '.bz2': - path = module.get_bin_path('bzip2', True) - elif os.path.splitext(target)[-1] == '.xz': - path = module.get_bin_path('xz', True) - - if path: - cmd = '%s | %s > %s' % (cmd, path, shlex_quote(target)) - else: - cmd += " > %s" % shlex_quote(target) - - executed_commands.append(cmd) - rc, stdout, stderr = module.run_command(cmd, use_unsafe_shell=True) - return rc, stdout, stderr - - -def db_import(module, host, user, password, db_name, target, all_databases, port, config_file, - 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 = [module.get_bin_path('mysql', True)] - # --defaults-file must go first, or errors out - if config_file: - if restrict_config_file: - cmd.append("--defaults-file=%s" % shlex_quote(config_file)) - else: - cmd.append("--defaults-extra-file=%s" % shlex_quote(config_file)) - - if check_implicit_admin: - cmd += " --user=root --password=''" - else: - if user: - cmd.append("--user=%s" % shlex_quote(user)) - - if password: - if not unsafe_password: - cmd.append("--password=%s" % shlex_quote(password)) - else: - cmd.append("--password=%s" % password) - - if ssl_cert is not None: - cmd.append("--ssl-cert=%s" % shlex_quote(ssl_cert)) - if ssl_key is not None: - cmd.append("--ssl-key=%s" % shlex_quote(ssl_key)) - if ssl_ca is not None: - cmd.append("--ssl-ca=%s" % shlex_quote(ssl_ca)) - if force: - cmd.append("-f") - if socket is not None: - cmd.append("--socket=%s" % shlex_quote(socket)) - else: - cmd.append("--host=%s" % shlex_quote(host)) - cmd.append("--port=%i" % port) - if (encoding is not None) and (encoding != ""): - cmd.append("--default-character-set=%s" % shlex_quote(encoding)) - if not all_databases: - cmd.append("--one-database") - cmd.append(shlex_quote(''.join(db_name))) - - comp_prog_path = None - if os.path.splitext(target)[-1] == '.gz': - comp_prog_path = module.get_bin_path('gzip', required=True) - elif os.path.splitext(target)[-1] == '.bz2': - 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) - if comp_prog_path: - # The line below is for returned data only: - executed_commands.append('%s -dc %s | %s' % (comp_prog_path, target, cmd)) - - if not use_shell: - p1 = subprocess.Popen([comp_prog_path, '-dc', target], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - p2 = subprocess.Popen(cmd, stdin=p1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - (stdout2, stderr2) = p2.communicate() - p1.stdout.close() - p1.wait() - - if p1.returncode != 0: - stderr1 = p1.stderr.read() - return p1.returncode, '', stderr1 - else: - return p2.returncode, stdout2, stderr2 - else: - # Used to prevent 'Broken pipe' errors that - # occasionaly occur when target files are compressed. - # FYI: passing the `shell=True` argument to p2 = subprocess.Popen() - # doesn't solve the problem. - cmd = " ".join(cmd) - cmd = "%s -dc %s | %s" % (comp_prog_path, shlex_quote(target), cmd) - rc, stdout, stderr = module.run_command(cmd, use_unsafe_shell=True) - return rc, stdout, stderr - - else: - cmd = ' '.join(cmd) - cmd += " < %s" % shlex_quote(target) - executed_commands.append(cmd) - rc, stdout, stderr = module.run_command(cmd, use_unsafe_shell=True) - return rc, stdout, stderr - - -def db_create(cursor, db, encoding, collation): - if not db: - return False - query_params = dict(enc=encoding, collate=collation) - res = 0 - for each_db in db: - query = ['CREATE DATABASE %s' % mysql_quote_identifier(each_db, 'database')] - if encoding: - query.append("CHARACTER SET %(enc)s") - if collation: - query.append("COLLATE %(collate)s") - query = ' '.join(query) - res += cursor.execute(query, query_params) - try: - executed_commands.append(cursor.mogrify(query, query_params)) - except AttributeError: - executed_commands.append(cursor._executed) - except Exception: - executed_commands.append(query) - return res > 0 - - -# =========================================== -# Module execution. -# - - -def main(): - module = AnsibleModule( - argument_spec=dict( - login_user=dict(type='str'), - login_password=dict(type='str', no_log=True), - login_host=dict(type='str', default='localhost'), - login_port=dict(type='int', default=3306), - login_unix_socket=dict(type='str'), - name=dict(type='list', required=True, aliases=['db']), - encoding=dict(type='str', default=''), - collation=dict(type='str', default=''), - target=dict(type='path'), - state=dict(type='str', default='present', choices=['absent', 'dump', 'import', 'present']), - client_cert=dict(type='path', aliases=['ssl_cert']), - client_key=dict(type='path', aliases=['ssl_key']), - ca_cert=dict(type='path', aliases=['ssl_ca']), - connect_timeout=dict(type='int', default=30), - config_file=dict(type='path', default='~/.my.cnf'), - single_transaction=dict(type='bool', default=False), - quick=dict(type='bool', default=True), - ignore_tables=dict(type='list', default=[]), - hex_blob=dict(default=False, type='bool'), - force=dict(type='bool', default=False), - master_data=dict(type='int', default=0, choices=[0, 1, 2]), - skip_lock_tables=dict(type='bool', default=False), - dump_extra_args=dict(type='str'), - use_shell=dict(type='bool', default=False), - unsafe_login_password=dict(type='bool', default=False), - restrict_config_file=dict(type='bool', default=False), - check_implicit_admin=dict(type='bool', default=False), - config_overrides_defaults=dict(type='bool', default=False), - ), - supports_check_mode=True, - ) - - if mysql_driver is None: - module.fail_json(msg=mysql_driver_fail_msg) - - db = module.params["name"] - if not db: - module.exit_json(changed=False, db=db, db_list=[]) - db = [each_db.strip() for each_db in db] - - encoding = module.params["encoding"] - collation = module.params["collation"] - state = module.params["state"] - target = module.params["target"] - socket = module.params["login_unix_socket"] - login_port = module.params["login_port"] - if login_port < 0 or login_port > 65535: - module.fail_json(msg="login_port must be a valid unix port number (0-65535)") - ssl_cert = module.params["client_cert"] - ssl_key = module.params["client_key"] - ssl_ca = module.params["ca_cert"] - connect_timeout = module.params['connect_timeout'] - config_file = module.params['config_file'] - login_password = module.params["login_password"] - unsafe_login_password = module.params["unsafe_login_password"] - login_user = module.params["login_user"] - login_host = module.params["login_host"] - ignore_tables = module.params["ignore_tables"] - for a_table in ignore_tables: - if a_table == "": - module.fail_json(msg="Name of ignored table cannot be empty") - single_transaction = module.params["single_transaction"] - quick = module.params["quick"] - hex_blob = module.params["hex_blob"] - force = module.params["force"] - master_data = module.params["master_data"] - skip_lock_tables = module.params["skip_lock_tables"] - dump_extra_args = module.params["dump_extra_args"] - use_shell = module.params["use_shell"] - restrict_config_file = module.params["restrict_config_file"] - check_implicit_admin = module.params['check_implicit_admin'] - config_overrides_defaults = module.params['config_overrides_defaults'] - - if len(db) > 1 and state == 'import': - module.fail_json(msg="Multiple databases are not supported with state=import") - db_name = ' '.join(db) - - all_databases = False - if state in ['dump', 'import']: - if target is None: - module.fail_json(msg="with state=%s target is required" % state) - if db == ['all']: - all_databases = True - else: - if db == ['all']: - module.fail_json(msg="name is not allowed to equal 'all' unless state equals import, or dump.") - try: - cursor = None - if check_implicit_admin: - try: - cursor, db_conn = mysql_connect(module, 'root', '', config_file, ssl_cert, ssl_key, ssl_ca, - connect_timeout=connect_timeout, - config_overrides_defaults=config_overrides_defaults) - except Exception as e: - check_implicit_admin = False - pass - - if not cursor: - cursor, db_conn = mysql_connect(module, login_user, login_password, config_file, ssl_cert, ssl_key, ssl_ca, - connect_timeout=connect_timeout, config_overrides_defaults=config_overrides_defaults) - except Exception as e: - 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, to_native(e))) - else: - module.fail_json(msg="unable to find %s. Exception message: %s" % (config_file, to_native(e))) - - changed = False - if not os.path.exists(config_file): - config_file = None - - existence_list = [] - non_existence_list = [] - - if not all_databases: - for each_database in db: - if db_exists(cursor, [each_database]): - existence_list.append(each_database) - else: - non_existence_list.append(each_database) - - if state == "absent": - if module.check_mode: - module.exit_json(changed=bool(existence_list), db=db_name, db_list=db) - try: - changed = db_delete(cursor, existence_list) - except Exception as e: - module.fail_json(msg="error deleting database: %s" % to_native(e)) - module.exit_json(changed=changed, db=db_name, db_list=db, executed_commands=executed_commands) - elif state == "present": - if module.check_mode: - module.exit_json(changed=bool(non_existence_list), db=db_name, db_list=db) - changed = False - if non_existence_list: - try: - changed = db_create(cursor, non_existence_list, encoding, collation) - except Exception as e: - module.fail_json(msg="error creating database: %s" % to_native(e), - exception=traceback.format_exc()) - module.exit_json(changed=changed, db=db_name, db_list=db, executed_commands=executed_commands) - elif state == "dump": - if non_existence_list and not all_databases: - module.fail_json(msg="Cannot dump database(s) %r - not found" % (', '.join(non_existence_list))) - if module.check_mode: - module.exit_json(changed=True, db=db_name, db_list=db) - rc, stdout, stderr = db_dump(module, login_host, login_user, - login_password, db, target, all_databases, - login_port, config_file, socket, ssl_cert, ssl_key, - ssl_ca, single_transaction, quick, ignore_tables, - hex_blob, encoding, force, master_data, skip_lock_tables, - dump_extra_args, unsafe_login_password, restrict_config_file, - check_implicit_admin) - if rc != 0: - module.fail_json(msg="%s" % stderr) - module.exit_json(changed=True, db=db_name, db_list=db, msg=stdout, - executed_commands=executed_commands) - elif state == "import": - if module.check_mode: - module.exit_json(changed=True, db=db_name, db_list=db) - if non_existence_list and not all_databases: - try: - db_create(cursor, non_existence_list, encoding, collation) - except Exception as e: - module.fail_json(msg="error creating database: %s" % to_native(e), - exception=traceback.format_exc()) - rc, stdout, stderr = db_import(module, login_host, login_user, - login_password, db, target, - all_databases, - 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: - module.fail_json(msg="%s" % stderr) - module.exit_json(changed=True, db=db_name, db_list=db, msg=stdout, - executed_commands=executed_commands) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/database/mysql/mysql_info.py b/plugins/modules/database/mysql/mysql_info.py deleted file mode 100644 index ac376252e9..0000000000 --- a/plugins/modules/database/mysql/mysql_info.py +++ /dev/null @@ -1,543 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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 - -DOCUMENTATION = r''' ---- -module: mysql_info -short_description: Gather information about MySQL servers -description: -- Gathers information about MySQL servers. - -options: - filter: - description: - - Limit the collected information by comma separated string or YAML list. - - Allowable values are C(version), C(databases), C(settings), C(global_status), - C(users), C(engines), C(master_status), C(slave_status), C(slave_hosts). - - By default, collects all subsets. - - You can use '!' before value (for example, C(!settings)) to exclude it from the information. - - If you pass including and excluding values to the filter, for example, I(filter=!settings,version), - the excluding values, C(!settings) in this case, will be ignored. - type: list - elements: str - login_db: - description: - - Database name to connect to. - - It makes sense if I(login_user) is allowed to connect to a specific database only. - type: str - exclude_fields: - description: - - List of fields which are not needed to collect. - - "Supports elements: C(db_size). Unsupported elements will be ignored" - type: list - elements: str - version_added: '0.2.0' - return_empty_dbs: - description: - - Includes names of empty databases to returned dictionary. - type: bool - default: no - -notes: -- Calculating the size of a database might be slow, depending on the number and size of tables in it. - To avoid this, use I(exclude_fields=db_size). - -seealso: -- module: community.general.mysql_variables -- module: community.general.mysql_db -- module: community.general.mysql_user -- module: community.general.mysql_replication - -author: -- Andrew Klychkov (@Andersson007) - -extends_documentation_fragment: -- community.general.mysql - -''' - -EXAMPLES = r''' -# Display info from mysql-hosts group (using creds from ~/.my.cnf to connect): -# ansible mysql-hosts -m mysql_info - -# Display only databases and users info: -# ansible mysql-hosts -m mysql_info -a 'filter=databases,users' - -# Display only slave status: -# ansible standby -m mysql_info -a 'filter=slave_status' - -# Display all info from databases group except settings: -# ansible databases -m mysql_info -a 'filter=!settings' - -- name: Collect all possible information using passwordless root access - mysql_info: - login_user: root - -- name: Get MySQL version with non-default credentials - mysql_info: - login_user: mysuperuser - login_password: mysuperpass - filter: version - -- name: Collect all info except settings and users by root - mysql_info: - login_user: root - login_password: rootpass - filter: "!settings,!users" - -- name: Collect info about databases and version using ~/.my.cnf as a credential file - become: yes - mysql_info: - filter: - - databases - - version - -- name: Collect info about databases and version using ~alice/.my.cnf as a credential file - become: yes - mysql_info: - config_file: /home/alice/.my.cnf - filter: - - databases - - version - -- name: Collect info about databases including empty and excluding their sizes - become: yes - mysql_info: - config_file: /home/alice/.my.cnf - filter: - - databases - exclude_fields: db_size - return_empty_dbs: yes -''' - -RETURN = r''' -version: - description: Database server version. - returned: if not excluded by filter - type: dict - sample: { "version": { "major": 5, "minor": 5, "release": 60 } } - contains: - major: - description: Major server version. - returned: if not excluded by filter - type: int - sample: 5 - minor: - description: Minor server version. - returned: if not excluded by filter - type: int - sample: 5 - release: - description: Release server version. - returned: if not excluded by filter - type: int - sample: 60 -databases: - description: Information about databases. - returned: if not excluded by filter - type: dict - sample: - - { "mysql": { "size": 656594 }, "information_schema": { "size": 73728 } } - contains: - size: - description: Database size in bytes. - returned: if not excluded by filter - type: dict - sample: { 'size': 656594 } -settings: - description: Global settings (variables) information. - returned: if not excluded by filter - type: dict - sample: - - { "innodb_open_files": 300, innodb_page_size": 16384 } -global_status: - description: Global status information. - returned: if not excluded by filter - type: dict - sample: - - { "Innodb_buffer_pool_read_requests": 123, "Innodb_buffer_pool_reads": 32 } -users: - description: Users information. - returned: if not excluded by filter - type: dict - sample: - - { "localhost": { "root": { "Alter_priv": "Y", "Alter_routine_priv": "Y" } } } -engines: - description: Information about the server's storage engines. - returned: if not excluded by filter - type: dict - sample: - - { "CSV": { "Comment": "CSV storage engine", "Savepoints": "NO", "Support": "YES", "Transactions": "NO", "XA": "NO" } } -master_status: - description: Master status information. - returned: if master - type: dict - sample: - - { "Binlog_Do_DB": "", "Binlog_Ignore_DB": "mysql", "File": "mysql-bin.000001", "Position": 769 } -slave_status: - description: Slave status information. - returned: if standby - type: dict - sample: - - { "192.168.1.101": { "3306": { "replication_user": { "Connect_Retry": 60, "Exec_Master_Log_Pos": 769, "Last_Errno": 0 } } } } -slave_hosts: - description: Slave status information. - returned: if master - type: dict - sample: - - { "2": { "Host": "", "Master_id": 1, "Port": 3306 } } -''' - -from decimal import Decimal - -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.community.general.plugins.module_utils.mysql import ( - mysql_connect, - mysql_common_argument_spec, - mysql_driver, - mysql_driver_fail_msg, -) -from ansible.module_utils.six import iteritems -from ansible.module_utils._text import to_native - - -# =========================================== -# MySQL module specific support methods. -# - -class MySQL_Info(object): - - """Class for collection MySQL instance information. - - Arguments: - module (AnsibleModule): Object of AnsibleModule class. - cursor (pymysql/mysql-python): Cursor class for interaction with - the database. - - Note: - If you need to add a new subset: - 1. add a new key with the same name to self.info attr in self.__init__() - 2. add a new private method to get the information - 3. add invocation of the new method to self.__collect() - 4. add info about the new subset to the DOCUMENTATION block - 5. add info about the new subset with an example to RETURN block - """ - - def __init__(self, module, cursor): - self.module = module - self.cursor = cursor - self.info = { - 'version': {}, - 'databases': {}, - 'settings': {}, - 'global_status': {}, - 'engines': {}, - 'users': {}, - 'master_status': {}, - 'slave_hosts': {}, - 'slave_status': {}, - } - - def get_info(self, filter_, exclude_fields, return_empty_dbs): - """Get MySQL instance information based on filter_. - - Arguments: - filter_ (list): List of collected subsets (e.g., databases, users, etc.), - when it is empty, return all available information. - """ - - inc_list = [] - exc_list = [] - - if filter_: - partial_info = {} - - for fi in filter_: - if fi.lstrip('!') not in self.info: - self.module.warn('filter element: %s is not allowable, ignored' % fi) - continue - - if fi[0] == '!': - exc_list.append(fi.lstrip('!')) - - else: - inc_list.append(fi) - - if inc_list: - self.__collect(exclude_fields, return_empty_dbs, set(inc_list)) - - for i in self.info: - if i in inc_list: - partial_info[i] = self.info[i] - - else: - not_in_exc_list = list(set(self.info) - set(exc_list)) - self.__collect(exclude_fields, return_empty_dbs, set(not_in_exc_list)) - - for i in self.info: - if i not in exc_list: - partial_info[i] = self.info[i] - - return partial_info - - else: - self.__collect(exclude_fields, return_empty_dbs, set(self.info)) - return self.info - - def __collect(self, exclude_fields, return_empty_dbs, wanted): - """Collect all possible subsets.""" - if 'version' in wanted or 'settings' in wanted: - self.__get_global_variables() - - if 'databases' in wanted: - self.__get_databases(exclude_fields, return_empty_dbs) - - if 'global_status' in wanted: - self.__get_global_status() - - if 'engines' in wanted: - self.__get_engines() - - if 'users' in wanted: - self.__get_users() - - if 'master_status' in wanted: - self.__get_master_status() - - if 'slave_status' in wanted: - self.__get_slave_status() - - if 'slave_hosts' in wanted: - self.__get_slaves() - - def __get_engines(self): - """Get storage engines info.""" - res = self.__exec_sql('SHOW ENGINES') - - if res: - for line in res: - engine = line['Engine'] - self.info['engines'][engine] = {} - - for vname, val in iteritems(line): - if vname != 'Engine': - self.info['engines'][engine][vname] = val - - def __convert(self, val): - """Convert unserializable data.""" - try: - if isinstance(val, Decimal): - val = float(val) - else: - val = int(val) - - except ValueError: - pass - - except TypeError: - pass - - return val - - def __get_global_variables(self): - """Get global variables (instance settings).""" - res = self.__exec_sql('SHOW GLOBAL VARIABLES') - - if res: - for var in res: - self.info['settings'][var['Variable_name']] = self.__convert(var['Value']) - - ver = self.info['settings']['version'].split('.') - release = ver[2].split('-')[0] - - self.info['version'] = dict( - major=int(ver[0]), - minor=int(ver[1]), - release=int(release), - ) - - def __get_global_status(self): - """Get global status.""" - res = self.__exec_sql('SHOW GLOBAL STATUS') - - if res: - for var in res: - self.info['global_status'][var['Variable_name']] = self.__convert(var['Value']) - - def __get_master_status(self): - """Get master status if the instance is a master.""" - res = self.__exec_sql('SHOW MASTER STATUS') - if res: - for line in res: - for vname, val in iteritems(line): - self.info['master_status'][vname] = self.__convert(val) - - def __get_slave_status(self): - """Get slave status if the instance is a slave.""" - res = self.__exec_sql('SHOW SLAVE STATUS') - if res: - for line in res: - host = line['Master_Host'] - if host not in self.info['slave_status']: - self.info['slave_status'][host] = {} - - port = line['Master_Port'] - if port not in self.info['slave_status'][host]: - self.info['slave_status'][host][port] = {} - - user = line['Master_User'] - if user not in self.info['slave_status'][host][port]: - self.info['slave_status'][host][port][user] = {} - - for vname, val in iteritems(line): - if vname not in ('Master_Host', 'Master_Port', 'Master_User'): - self.info['slave_status'][host][port][user][vname] = self.__convert(val) - - def __get_slaves(self): - """Get slave hosts info if the instance is a master.""" - res = self.__exec_sql('SHOW SLAVE HOSTS') - if res: - for line in res: - srv_id = line['Server_id'] - if srv_id not in self.info['slave_hosts']: - self.info['slave_hosts'][srv_id] = {} - - for vname, val in iteritems(line): - if vname != 'Server_id': - self.info['slave_hosts'][srv_id][vname] = self.__convert(val) - - def __get_users(self): - """Get user info.""" - res = self.__exec_sql('SELECT * FROM mysql.user') - if res: - for line in res: - host = line['Host'] - if host not in self.info['users']: - self.info['users'][host] = {} - - user = line['User'] - self.info['users'][host][user] = {} - - for vname, val in iteritems(line): - if vname not in ('Host', 'User'): - self.info['users'][host][user][vname] = self.__convert(val) - - def __get_databases(self, exclude_fields, return_empty_dbs): - """Get info about databases.""" - if not exclude_fields: - query = ('SELECT table_schema AS "name", ' - 'SUM(data_length + index_length) AS "size" ' - 'FROM information_schema.TABLES GROUP BY table_schema') - else: - if 'db_size' in exclude_fields: - query = ('SELECT table_schema AS "name" ' - 'FROM information_schema.TABLES GROUP BY table_schema') - - res = self.__exec_sql(query) - - if res: - for db in res: - self.info['databases'][db['name']] = {} - - if not exclude_fields or 'db_size' not in exclude_fields: - self.info['databases'][db['name']]['size'] = int(db['size']) - - # If empty dbs are not needed in the returned dict, exit from the method - if not return_empty_dbs: - return None - - # Add info about empty databases (issue #65727): - res = self.__exec_sql('SHOW DATABASES') - if res: - for db in res: - if db['Database'] not in self.info['databases']: - self.info['databases'][db['Database']] = {} - - if not exclude_fields or 'db_size' not in exclude_fields: - self.info['databases'][db['Database']]['size'] = 0 - - def __exec_sql(self, query, ddl=False): - """Execute SQL. - - Arguments: - ddl (bool): If True, return True or False. - Used for queries that don't return any rows - (mainly for DDL queries) (default False). - """ - try: - self.cursor.execute(query) - - if not ddl: - res = self.cursor.fetchall() - return res - return True - - except Exception as e: - self.module.fail_json(msg="Cannot execute SQL '%s': %s" % (query, to_native(e))) - return False - - -# =========================================== -# Module execution. -# - - -def main(): - argument_spec = mysql_common_argument_spec() - argument_spec.update( - login_db=dict(type='str'), - filter=dict(type='list'), - exclude_fields=dict(type='list'), - return_empty_dbs=dict(type='bool', default=False), - ) - - module = AnsibleModule( - argument_spec=argument_spec, - supports_check_mode=True, - ) - - db = module.params['login_db'] - connect_timeout = module.params['connect_timeout'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - ssl_cert = module.params['client_cert'] - ssl_key = module.params['client_key'] - ssl_ca = module.params['ca_cert'] - config_file = module.params['config_file'] - filter_ = module.params['filter'] - exclude_fields = module.params['exclude_fields'] - return_empty_dbs = module.params['return_empty_dbs'] - - if filter_: - filter_ = [f.strip() for f in filter_] - - if exclude_fields: - exclude_fields = set([f.strip() for f in exclude_fields]) - - if mysql_driver is None: - module.fail_json(msg=mysql_driver_fail_msg) - - try: - cursor, db_conn = mysql_connect(module, login_user, login_password, - config_file, ssl_cert, ssl_key, ssl_ca, db, - connect_timeout=connect_timeout, cursor_class='DictCursor') - except Exception as e: - 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, to_native(e))) - - ############################### - # Create object and do main job - - mysql = MySQL_Info(module, cursor) - - module.exit_json(changed=False, **mysql.get_info(filter_, exclude_fields, return_empty_dbs)) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/database/mysql/mysql_query.py b/plugins/modules/database/mysql/mysql_query.py deleted file mode 100644 index 4b6ad3b911..0000000000 --- a/plugins/modules/database/mysql/mysql_query.py +++ /dev/null @@ -1,233 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2020, 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 - -DOCUMENTATION = r''' ---- -module: mysql_query -short_description: Run MySQL queries -description: -- Runs arbitrary MySQL queries. -- Pay attention, the module does not support check mode! - All queries will be executed in autocommit mode. -version_added: '0.2.0' -options: - query: - description: - - SQL query to run. Multiple queries can be passed using YAML list syntax. - type: list - elements: str - required: yes - positional_args: - description: - - List of values to be passed as positional arguments to the query. - - Mutually exclusive with I(named_args). - type: list - named_args: - description: - - Dictionary of key-value arguments to pass to the query. - - Mutually exclusive with I(positional_args). - type: dict - login_db: - description: - - Name of database to connect to and run queries against. - type: str - single_transaction: - description: - - Where passed queries run in a single transaction (C(yes)) or commit them one-by-one (C(no)). - type: bool - default: no -notes: -- To pass a query containing commas, use YAML list notation with hyphen (see EXAMPLES block). -author: -- Andrew Klychkov (@Andersson007) -extends_documentation_fragment: -- community.general.mysql - -''' - -EXAMPLES = r''' -- name: Simple select query to acme db - mysql_query: - login_db: acme - query: SELECT * FROM orders - -- name: Select query to db acme with positional arguments - mysql_query: - login_db: acme - query: SELECT * FROM acme WHERE id = %s AND story = %s - positional_args: - - 1 - - test - -- name: Select query to test_db with named_args - mysql_query: - login_db: test_db - query: SELECT * FROM test WHERE id = %(id_val)s AND story = %(story_val)s - named_args: - id_val: 1 - story_val: test - -- name: Run several insert queries against db test_db in single transaction - mysql_query: - login_db: test_db - query: - - INSERT INTO articles (id, story) VALUES (2, 'my_long_story') - - INSERT INTO prices (id, price) VALUES (123, '100.00') - single_transaction: yes -''' - -RETURN = r''' -executed_queries: - description: List of executed queries. - returned: always - type: list - sample: ['SELECT * FROM bar', 'UPDATE bar SET id = 1 WHERE id = 2'] -query_result: - description: - - List of lists (sublist for each query) containing dictionaries - in column:value form representing returned rows. - returned: changed - type: list - sample: [[{"Column": "Value1"},{"Column": "Value2"}], [{"ID": 1}, {"ID": 2}]] -rowcount: - description: Number of affected rows for each subquery. - returned: changed - type: list - sample: [5, 1] -''' - -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.community.general.plugins.module_utils.mysql import ( - mysql_connect, - mysql_common_argument_spec, - mysql_driver, - mysql_driver_fail_msg, -) -from ansible.module_utils._text import to_native - -DML_QUERY_KEYWORDS = ('INSERT', 'UPDATE', 'DELETE') -# TRUNCATE is not DDL query but it also returns 0 rows affected: -DDL_QUERY_KEYWORDS = ('CREATE', 'DROP', 'ALTER', 'RENAME', 'TRUNCATE') - - -# =========================================== -# Module execution. -# - -def main(): - argument_spec = mysql_common_argument_spec() - argument_spec.update( - query=dict(type='list', elements='str', required=True), - login_db=dict(type='str'), - positional_args=dict(type='list'), - named_args=dict(type='dict'), - single_transaction=dict(type='bool', default=False), - ) - - module = AnsibleModule( - argument_spec=argument_spec, - mutually_exclusive=( - ('positional_args', 'named_args'), - ), - ) - - db = module.params['login_db'] - connect_timeout = module.params['connect_timeout'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - ssl_cert = module.params['client_cert'] - ssl_key = module.params['client_key'] - ssl_ca = module.params['ca_cert'] - config_file = module.params['config_file'] - query = module.params["query"] - if module.params["single_transaction"]: - autocommit = False - else: - autocommit = True - # Prepare args: - if module.params.get("positional_args"): - arguments = module.params["positional_args"] - elif module.params.get("named_args"): - arguments = module.params["named_args"] - else: - arguments = None - - if mysql_driver is None: - module.fail_json(msg=mysql_driver_fail_msg) - - # Connect to DB: - try: - cursor, db_connection = mysql_connect(module, login_user, login_password, - config_file, ssl_cert, ssl_key, ssl_ca, db, - connect_timeout=connect_timeout, - cursor_class='DictCursor', autocommit=autocommit) - except Exception as e: - 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, to_native(e))) - # Set defaults: - changed = False - - max_keyword_len = len(max(DML_QUERY_KEYWORDS + DDL_QUERY_KEYWORDS, key=len)) - - # Execute query: - query_result = [] - executed_queries = [] - rowcount = [] - for q in query: - try: - cursor.execute(q, arguments) - - except Exception as e: - if not autocommit: - db_connection.rollback() - - cursor.close() - module.fail_json(msg="Cannot execute SQL '%s' args [%s]: %s" % (q, arguments, to_native(e))) - - try: - query_result.append([dict(row) for row in cursor.fetchall()]) - - except Exception as e: - if not autocommit: - db_connection.rollback() - - module.fail_json(msg="Cannot fetch rows from cursor: %s" % to_native(e)) - - # Check DML or DDL keywords in query and set changed accordingly: - q = q.lstrip()[0:max_keyword_len].upper() - for keyword in DML_QUERY_KEYWORDS: - if keyword in q and cursor.rowcount > 0: - changed = True - - for keyword in DDL_QUERY_KEYWORDS: - if keyword in q: - changed = True - - executed_queries.append(cursor._last_executed) - rowcount.append(cursor.rowcount) - - # When the module run with the single_transaction == True: - if not autocommit: - db_connection.commit() - - # Create dict with returned values: - kw = { - 'changed': changed, - 'executed_queries': executed_queries, - 'query_result': query_result, - 'rowcount': rowcount, - } - - # Exit: - module.exit_json(**kw) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/database/mysql/mysql_replication.py b/plugins/modules/database/mysql/mysql_replication.py deleted file mode 100644 index 5980deffb4..0000000000 --- a/plugins/modules/database/mysql/mysql_replication.py +++ /dev/null @@ -1,573 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2013, Balazs Pocze -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# Certain parts are taken from Mark Theunissen's mysqldb module -# 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 - - -DOCUMENTATION = r''' ---- -module: mysql_replication -short_description: Manage MySQL replication -description: -- Manages MySQL server replication, slave, master status, get and change master host. -author: -- Balazs Pocze (@banyek) -- Andrew Klychkov (@Andersson007) -options: - mode: - description: - - Module operating mode. Could be - C(changemaster) (CHANGE MASTER TO), - C(getmaster) (SHOW MASTER STATUS), - C(getslave) (SHOW SLAVE STATUS), - C(startslave) (START SLAVE), - C(stopslave) (STOP SLAVE), - C(resetmaster) (RESET MASTER) - supported since community.general 0.2.0, - C(resetslave) (RESET SLAVE), - C(resetslaveall) (RESET SLAVE ALL). - type: str - choices: - - changemaster - - getmaster - - getslave - - startslave - - stopslave - - resetmaster - - resetslave - - resetslaveall - default: getslave - master_host: - description: - - Same as mysql variable. - type: str - master_user: - description: - - Same as mysql variable. - type: str - master_password: - description: - - Same as mysql variable. - type: str - master_port: - description: - - Same as mysql variable. - type: int - master_connect_retry: - description: - - Same as mysql variable. - type: int - master_log_file: - description: - - Same as mysql variable. - type: str - master_log_pos: - description: - - Same as mysql variable. - type: int - relay_log_file: - description: - - Same as mysql variable. - type: str - relay_log_pos: - description: - - Same as mysql variable. - type: int - master_ssl: - description: - - Same as mysql variable. - type: bool - master_ssl_ca: - description: - - Same as mysql variable. - type: str - master_ssl_capath: - description: - - Same as mysql variable. - type: str - master_ssl_cert: - description: - - Same as mysql variable. - type: str - master_ssl_key: - description: - - Same as mysql variable. - type: str - master_ssl_cipher: - description: - - Same as mysql variable. - type: str - master_auto_position: - description: - - Whether the host uses GTID based replication or not. - type: bool - master_use_gtid: - description: - - Configures the slave to use the MariaDB Global Transaction ID. - - C(disabled) equals MASTER_USE_GTID=no command. - - To find information about available values see - U(https://mariadb.com/kb/en/library/change-master-to/#master_use_gtid). - - Available since MariaDB 10.0.2. - choices: [current_pos, slave_pos, disabled] - type: str - version_added: '0.2.0' - master_delay: - description: - - Time lag behind the master's state (in seconds). - - Available from MySQL 5.6. - - For more information see U(https://dev.mysql.com/doc/refman/8.0/en/replication-delayed.html). - type: int - version_added: '0.2.0' - connection_name: - description: - - Name of the master connection. - - Supported from MariaDB 10.0.1. - - Mutually exclusive with I(channel). - - For more information see U(https://mariadb.com/kb/en/library/multi-source-replication/). - type: str - version_added: '0.2.0' - channel: - description: - - Name of replication channel. - - Multi-source replication is supported from MySQL 5.7. - - Mutually exclusive with I(connection_name). - - For more information see U(https://dev.mysql.com/doc/refman/8.0/en/replication-multi-source.html). - type: str - version_added: '0.2.0' - fail_on_error: - description: - - Fails on error when calling mysql. - type: bool - default: False - version_added: '0.2.0' - -notes: -- If an empty value for the parameter of string type is needed, use an empty string. - -extends_documentation_fragment: -- community.general.mysql - - -seealso: -- module: community.general.mysql_info -- name: MySQL replication reference - description: Complete reference of the MySQL replication documentation. - link: https://dev.mysql.com/doc/refman/8.0/en/replication.html -- name: MariaDB replication reference - description: Complete reference of the MariaDB replication documentation. - link: https://mariadb.com/kb/en/library/setting-up-replication/ -''' - -EXAMPLES = r''' -- name: Stop mysql slave thread - mysql_replication: - mode: stopslave - -- name: Get master binlog file name and binlog position - mysql_replication: - mode: getmaster - -- name: Change master to master server 192.0.2.1 and use binary log 'mysql-bin.000009' with position 4578 - mysql_replication: - mode: changemaster - master_host: 192.0.2.1 - master_log_file: mysql-bin.000009 - master_log_pos: 4578 - -- name: Check slave status using port 3308 - mysql_replication: - mode: getslave - login_host: ansible.example.com - login_port: 3308 - -- name: On MariaDB change master to use GTID current_pos - mysql_replication: - mode: changemaster - master_use_gtid: current_pos - -- name: Change master to use replication delay 3600 seconds - mysql_replication: - mode: changemaster - master_host: 192.0.2.1 - master_delay: 3600 - -- name: Start MariaDB standby with connection name master-1 - mysql_replication: - mode: startslave - connection_name: master-1 - -- name: Stop replication in channel master-1 - mysql_replication: - mode: stopslave - channel: master-1 - -- name: > - Run RESET MASTER command which will delete all existing binary log files - and reset the binary log index file on the master - mysql_replication: - mode: resetmaster - -- name: Run start slave and fail the task on errors - mysql_replication: - mode: startslave - connection_name: master-1 - fail_on_error: yes - -- name: Change master and fail on error (like when slave thread is running) - mysql_replication: - mode: changemaster - fail_on_error: yes - -''' - -RETURN = r''' -queries: - description: List of executed queries which modified DB's state. - returned: always - type: list - sample: ["CHANGE MASTER TO MASTER_HOST='master2.example.com',MASTER_PORT=3306"] - version_added: '0.2.0' -''' - -import os -import warnings - -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.community.general.plugins.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg -from ansible.module_utils._text import to_native - -executed_queries = [] - - -def get_master_status(cursor): - cursor.execute("SHOW MASTER STATUS") - masterstatus = cursor.fetchone() - return masterstatus - - -def get_slave_status(cursor, connection_name='', channel=''): - if connection_name: - query = "SHOW SLAVE '%s' STATUS" % connection_name - else: - query = "SHOW SLAVE STATUS" - - if channel: - query += " FOR CHANNEL '%s'" % channel - - cursor.execute(query) - slavestatus = cursor.fetchone() - return slavestatus - - -def stop_slave(module, cursor, connection_name='', channel='', fail_on_error=False): - if connection_name: - query = "STOP SLAVE '%s'" % connection_name - else: - query = 'STOP SLAVE' - - if channel: - query += " FOR CHANNEL '%s'" % channel - - try: - executed_queries.append(query) - cursor.execute(query) - stopped = True - except mysql_driver.Warning as e: - stopped = False - except Exception as e: - if fail_on_error: - module.fail_json(msg="STOP SLAVE failed: %s" % to_native(e)) - stopped = False - return stopped - - -def reset_slave(module, cursor, connection_name='', channel='', fail_on_error=False): - if connection_name: - query = "RESET SLAVE '%s'" % connection_name - else: - query = 'RESET SLAVE' - - if channel: - query += " FOR CHANNEL '%s'" % channel - - try: - executed_queries.append(query) - cursor.execute(query) - reset = True - except mysql_driver.Warning as e: - reset = False - except Exception as e: - if fail_on_error: - module.fail_json(msg="RESET SLAVE failed: %s" % to_native(e)) - reset = False - return reset - - -def reset_slave_all(module, cursor, connection_name='', channel='', fail_on_error=False): - if connection_name: - query = "RESET SLAVE '%s' ALL" % connection_name - else: - query = 'RESET SLAVE ALL' - - if channel: - query += " FOR CHANNEL '%s'" % channel - - try: - executed_queries.append(query) - cursor.execute(query) - reset = True - except mysql_driver.Warning as e: - reset = False - except Exception as e: - if fail_on_error: - module.fail_json(msg="RESET SLAVE ALL failed: %s" % to_native(e)) - reset = False - return reset - - -def reset_master(module, cursor, fail_on_error=False): - query = 'RESET MASTER' - try: - executed_queries.append(query) - cursor.execute(query) - reset = True - except mysql_driver.Warning as e: - reset = False - except Exception as e: - if fail_on_error: - module.fail_json(msg="RESET MASTER failed: %s" % to_native(e)) - reset = False - return reset - - -def start_slave(module, cursor, connection_name='', channel='', fail_on_error=False): - if connection_name: - query = "START SLAVE '%s'" % connection_name - else: - query = 'START SLAVE' - - if channel: - query += " FOR CHANNEL '%s'" % channel - - try: - executed_queries.append(query) - cursor.execute(query) - started = True - except mysql_driver.Warning as e: - started = False - except Exception as e: - if fail_on_error: - module.fail_json(msg="START SLAVE failed: %s" % to_native(e)) - started = False - return started - - -def changemaster(cursor, chm, connection_name='', channel=''): - if connection_name: - query = "CHANGE MASTER '%s' TO %s" % (connection_name, ','.join(chm)) - else: - query = 'CHANGE MASTER TO %s' % ','.join(chm) - - if channel: - query += " FOR CHANNEL '%s'" % channel - - executed_queries.append(query) - cursor.execute(query) - - -def main(): - module = AnsibleModule( - argument_spec=dict( - login_user=dict(type='str'), - login_password=dict(type='str', no_log=True), - login_host=dict(type='str', default='localhost'), - login_port=dict(type='int', default=3306), - login_unix_socket=dict(type='str'), - mode=dict(type='str', default='getslave', choices=[ - 'getmaster', 'getslave', 'changemaster', 'stopslave', - 'startslave', 'resetmaster', 'resetslave', 'resetslaveall']), - master_auto_position=dict(type='bool', default=False), - master_host=dict(type='str'), - master_user=dict(type='str'), - master_password=dict(type='str', no_log=True), - master_port=dict(type='int'), - master_connect_retry=dict(type='int'), - master_log_file=dict(type='str'), - master_log_pos=dict(type='int'), - relay_log_file=dict(type='str'), - relay_log_pos=dict(type='int'), - master_ssl=dict(type='bool', default=False), - master_ssl_ca=dict(type='str'), - master_ssl_capath=dict(type='str'), - master_ssl_cert=dict(type='str'), - master_ssl_key=dict(type='str'), - master_ssl_cipher=dict(type='str'), - connect_timeout=dict(type='int', default=30), - config_file=dict(type='path', default='~/.my.cnf'), - client_cert=dict(type='path', aliases=['ssl_cert']), - client_key=dict(type='path', aliases=['ssl_key']), - ca_cert=dict(type='path', aliases=['ssl_ca']), - master_use_gtid=dict(type='str', choices=['current_pos', 'slave_pos', 'disabled']), - master_delay=dict(type='int'), - connection_name=dict(type='str'), - channel=dict(type='str'), - fail_on_error=dict(type='bool', default=False), - ), - mutually_exclusive=[ - ['connection_name', 'channel'] - ], - ) - mode = module.params["mode"] - master_host = module.params["master_host"] - master_user = module.params["master_user"] - master_password = module.params["master_password"] - master_port = module.params["master_port"] - master_connect_retry = module.params["master_connect_retry"] - master_log_file = module.params["master_log_file"] - master_log_pos = module.params["master_log_pos"] - relay_log_file = module.params["relay_log_file"] - relay_log_pos = module.params["relay_log_pos"] - master_ssl = module.params["master_ssl"] - master_ssl_ca = module.params["master_ssl_ca"] - master_ssl_capath = module.params["master_ssl_capath"] - master_ssl_cert = module.params["master_ssl_cert"] - master_ssl_key = module.params["master_ssl_key"] - master_ssl_cipher = module.params["master_ssl_cipher"] - master_auto_position = module.params["master_auto_position"] - ssl_cert = module.params["client_cert"] - ssl_key = module.params["client_key"] - ssl_ca = module.params["ca_cert"] - connect_timeout = module.params['connect_timeout'] - config_file = module.params['config_file'] - master_delay = module.params['master_delay'] - if module.params.get("master_use_gtid") == 'disabled': - master_use_gtid = 'no' - else: - master_use_gtid = module.params["master_use_gtid"] - connection_name = module.params["connection_name"] - channel = module.params['channel'] - fail_on_error = module.params['fail_on_error'] - - if mysql_driver is None: - module.fail_json(msg=mysql_driver_fail_msg) - else: - warnings.filterwarnings('error', category=mysql_driver.Warning) - - login_password = module.params["login_password"] - login_user = module.params["login_user"] - - try: - cursor, db_conn = mysql_connect(module, login_user, login_password, config_file, - ssl_cert, ssl_key, ssl_ca, None, cursor_class='DictCursor', - connect_timeout=connect_timeout) - except Exception as e: - 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, to_native(e))) - else: - module.fail_json(msg="unable to find %s. Exception message: %s" % (config_file, to_native(e))) - - if mode in "getmaster": - status = get_master_status(cursor) - if not isinstance(status, dict): - status = dict(Is_Master=False, msg="Server is not configured as mysql master") - else: - status['Is_Master'] = True - module.exit_json(queries=executed_queries, **status) - - elif mode in "getslave": - status = get_slave_status(cursor, connection_name, channel) - if not isinstance(status, dict): - status = dict(Is_Slave=False, msg="Server is not configured as mysql slave") - else: - status['Is_Slave'] = True - module.exit_json(queries=executed_queries, **status) - - elif mode in "changemaster": - chm = [] - result = {} - if master_host is not None: - chm.append("MASTER_HOST='%s'" % master_host) - if master_user is not None: - chm.append("MASTER_USER='%s'" % master_user) - if master_password is not None: - chm.append("MASTER_PASSWORD='%s'" % master_password) - if master_port is not None: - chm.append("MASTER_PORT=%s" % master_port) - if master_connect_retry is not None: - chm.append("MASTER_CONNECT_RETRY=%s" % master_connect_retry) - if master_log_file is not None: - chm.append("MASTER_LOG_FILE='%s'" % master_log_file) - if master_log_pos is not None: - chm.append("MASTER_LOG_POS=%s" % master_log_pos) - if master_delay is not None: - chm.append("MASTER_DELAY=%s" % master_delay) - if relay_log_file is not None: - chm.append("RELAY_LOG_FILE='%s'" % relay_log_file) - if relay_log_pos is not None: - chm.append("RELAY_LOG_POS=%s" % relay_log_pos) - if master_ssl: - chm.append("MASTER_SSL=1") - if master_ssl_ca is not None: - chm.append("MASTER_SSL_CA='%s'" % master_ssl_ca) - if master_ssl_capath is not None: - chm.append("MASTER_SSL_CAPATH='%s'" % master_ssl_capath) - if master_ssl_cert is not None: - chm.append("MASTER_SSL_CERT='%s'" % master_ssl_cert) - if master_ssl_key is not None: - chm.append("MASTER_SSL_KEY='%s'" % master_ssl_key) - if master_ssl_cipher is not None: - chm.append("MASTER_SSL_CIPHER='%s'" % master_ssl_cipher) - if master_auto_position: - chm.append("MASTER_AUTO_POSITION=1") - if master_use_gtid is not None: - chm.append("MASTER_USE_GTID=%s" % master_use_gtid) - try: - changemaster(cursor, chm, connection_name, channel) - except mysql_driver.Warning as e: - result['warning'] = to_native(e) - except Exception as e: - module.fail_json(msg='%s. Query == CHANGE MASTER TO %s' % (to_native(e), chm)) - result['changed'] = True - module.exit_json(queries=executed_queries, **result) - elif mode in "startslave": - started = start_slave(module, cursor, connection_name, channel, fail_on_error) - if started is True: - module.exit_json(msg="Slave started ", changed=True, queries=executed_queries) - else: - module.exit_json(msg="Slave already started (Or cannot be started)", changed=False, queries=executed_queries) - elif mode in "stopslave": - stopped = stop_slave(module, cursor, connection_name, channel, fail_on_error) - if stopped is True: - module.exit_json(msg="Slave stopped", changed=True, queries=executed_queries) - else: - module.exit_json(msg="Slave already stopped", changed=False, queries=executed_queries) - elif mode in "resetmaster": - reset = reset_master(module, cursor, fail_on_error) - if reset is True: - module.exit_json(msg="Master reset", changed=True, queries=executed_queries) - else: - module.exit_json(msg="Master already reset", changed=False, queries=executed_queries) - elif mode in "resetslave": - reset = reset_slave(module, cursor, connection_name, channel, fail_on_error) - if reset is True: - module.exit_json(msg="Slave reset", changed=True, queries=executed_queries) - else: - module.exit_json(msg="Slave already reset", changed=False, queries=executed_queries) - elif mode in "resetslaveall": - reset = reset_slave_all(module, cursor, connection_name, channel, fail_on_error) - if reset is True: - module.exit_json(msg="Slave reset", changed=True, queries=executed_queries) - else: - module.exit_json(msg="Slave already reset", changed=False, queries=executed_queries) - - warnings.simplefilter("ignore") - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/database/mysql/mysql_user.py b/plugins/modules/database/mysql/mysql_user.py deleted file mode 100644 index 27565a1336..0000000000 --- a/plugins/modules/database/mysql/mysql_user.py +++ /dev/null @@ -1,991 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2012, Mark Theunissen -# Sponsored by Four Kitchens http://fourkitchens.com. -# 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 - - -DOCUMENTATION = r''' ---- -module: mysql_user -short_description: Adds or removes a user from a MySQL database -description: - - Adds or removes a user from a MySQL database. -options: - name: - description: - - Name of the user (role) to add or remove. - type: str - required: true - password: - description: - - Set the user's password.. - type: str - encrypted: - description: - - Indicate that the 'password' field is a `mysql_native_password` hash. - type: bool - default: no - host: - description: - - The 'host' part of the MySQL username. - type: str - default: localhost - host_all: - description: - - Override the host option, making ansible apply changes to all hostnames for a given user. - - This option cannot be used when creating users. - type: bool - default: no - priv: - description: - - "MySQL privileges string in the format: C(db.table:priv1,priv2)." - - "Multiple privileges can be specified by separating each one using - a forward slash: C(db.table:priv/db.table:priv)." - - The format is based on MySQL C(GRANT) statement. - - Database and table names can be quoted, MySQL-style. - - If column privileges are used, the C(priv1,priv2) part must be - exactly as returned by a C(SHOW GRANT) statement. If not followed, - the module will always report changes. It includes grouping columns - by permission (C(SELECT(col1,col2)) instead of C(SELECT(col1),SELECT(col2))). - - Can be passed as a dictionary (see the examples). - type: raw - append_privs: - description: - - Append the privileges defined by priv to the existing ones for this - user instead of overwriting existing ones. - type: bool - default: no - sql_log_bin: - description: - - Whether binary logging should be enabled or disabled for the connection. - type: bool - default: yes - state: - description: - - Whether the user should exist. - - When C(absent), removes the user. - type: str - choices: [ absent, present ] - default: present - check_implicit_admin: - description: - - Check if mysql allows login as root/nopassword before trying supplied credentials. - - If success, passed I(login_user)/I(login_password) will be ignored. - type: bool - default: no - update_password: - description: - - C(always) will update passwords if they differ. - - C(on_create) will only set the password for newly created users. - type: str - choices: [ always, on_create ] - default: always - plugin: - description: - - User's plugin to authenticate (``CREATE USER user IDENTIFIED WITH plugin``). - type: str - version_added: '0.2.0' - plugin_hash_string: - description: - - User's plugin hash string (``CREATE USER user IDENTIFIED WITH plugin AS plugin_hash_string``). - type: str - version_added: '0.2.0' - plugin_auth_string: - description: - - User's plugin auth_string (``CREATE USER user IDENTIFIED WITH plugin BY plugin_auth_string``). - type: str - version_added: '0.2.0' - resource_limits: - description: - - Limit the user for certain server resources. Provided since MySQL 5.6 / MariaDB 10.2. - - "Available options are C(MAX_QUERIES_PER_HOUR: num), C(MAX_UPDATES_PER_HOUR: num), - C(MAX_CONNECTIONS_PER_HOUR: num), C(MAX_USER_CONNECTIONS: num)." - - Used when I(state=present), ignored otherwise. - type: dict - version_added: '0.2.0' - -notes: - - "MySQL server installs with default login_user of 'root' and no password. To secure this user - as part of an idempotent playbook, you must create at least two tasks: the first must change the root user's password, - without providing any login_user/login_password details. The second must drop a ~/.my.cnf file containing - the new root credentials. Subsequent runs of the playbook will then succeed by reading the new credentials from - the file." - - Currently, there is only support for the `mysql_native_password` encrypted password hash module. - -seealso: -- module: community.general.mysql_info -- name: MySQL access control and account management reference - description: Complete reference of the MySQL access control and account management documentation. - link: https://dev.mysql.com/doc/refman/8.0/en/access-control.html -- name: MySQL provided privileges reference - description: Complete reference of the MySQL provided privileges documentation. - link: https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html - -author: -- Jonathan Mainguy (@Jmainguy) -- Benjamin Malynovytch (@bmalynovytch) -- Lukasz Tomaszkiewicz (@tomaszkiewicz) -extends_documentation_fragment: -- community.general.mysql - -''' - -EXAMPLES = r''' -- name: Removes anonymous user account for localhost - mysql_user: - name: '' - host: localhost - state: absent - -- name: Removes all anonymous user accounts - mysql_user: - name: '' - host_all: yes - state: absent - -- name: Create database user with name 'bob' and password '12345' with all database privileges - mysql_user: - name: bob - password: 12345 - priv: '*.*:ALL' - state: present - -- name: Create database user using hashed password with all database privileges - mysql_user: - name: bob - password: '*EE0D72C1085C46C5278932678FBE2C6A782821B4' - encrypted: yes - priv: '*.*:ALL' - state: present - -- name: Create database user with password and all database privileges and 'WITH GRANT OPTION' - mysql_user: - name: bob - password: 12345 - priv: '*.*:ALL,GRANT' - state: present - -- name: Create user with password, all database privileges and 'WITH GRANT OPTION' in db1 and db2 - mysql_user: - state: present - name: bob - password: 12345dd - priv: - 'db1.*': 'ALL,GRANT' - 'db2.*': 'ALL,GRANT' - -# Note that REQUIRESSL is a special privilege that should only apply to *.* by itself. -- name: Modify user to require SSL connections. - mysql_user: - name: bob - append_privs: yes - priv: '*.*:REQUIRESSL' - state: present - -- name: Ensure no user named 'sally'@'localhost' exists, also passing in the auth credentials. - mysql_user: - login_user: root - login_password: 123456 - name: sally - state: absent - -# check_implicit_admin example -- name: > - Ensure no user named 'sally'@'localhost' exists, also passing in the auth credentials. - If mysql allows root/nopassword login, try it without the credentials first. - If it's not allowed, pass the credentials. - mysql_user: - check_implicit_admin: yes - login_user: root - login_password: 123456 - name: sally - state: absent - -- name: Ensure no user named 'sally' exists at all - mysql_user: - name: sally - host_all: yes - state: absent - -- name: Specify grants composed of more than one word - mysql_user: - name: replication - password: 12345 - priv: "*.*:REPLICATION CLIENT" - state: present - -- name: Revoke all privileges for user 'bob' and password '12345' - mysql_user: - name: bob - password: 12345 - priv: "*.*:USAGE" - state: present - -# Example privileges string format -# mydb.*:INSERT,UPDATE/anotherdb.*:SELECT/yetanotherdb.*:ALL - -- name: Example using login_unix_socket to connect to server - mysql_user: - name: root - password: abc123 - login_unix_socket: /var/run/mysqld/mysqld.sock - -- name: Example of skipping binary logging while adding user 'bob' - mysql_user: - name: bob - password: 12345 - priv: "*.*:USAGE" - state: present - sql_log_bin: no - -- name: Create user 'bob' authenticated with plugin 'AWSAuthenticationPlugin' - mysql_user: - name: bob - plugin: AWSAuthenticationPlugin - plugin_hash_string: RDS - priv: '*.*:ALL' - state: present - -- name: Limit bob's resources to 10 queries per hour and 5 connections per hour - mysql_user: - name: bob - resource_limits: - MAX_QUERIES_PER_HOUR: 10 - MAX_CONNECTIONS_PER_HOUR: 5 - -# Example .my.cnf file for setting the root password -# [client] -# user=root -# password=n<_665{vS43y -''' - -import re -import string - -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.community.general.plugins.module_utils.database import SQLParseError -from ansible_collections.community.general.plugins.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg -from ansible.module_utils.six import iteritems -from ansible.module_utils._text import to_native - - -VALID_PRIVS = frozenset(('CREATE', 'DROP', 'GRANT', 'GRANT OPTION', - 'LOCK TABLES', 'REFERENCES', 'EVENT', 'ALTER', - 'DELETE', 'INDEX', 'INSERT', 'SELECT', 'UPDATE', - 'CREATE TEMPORARY TABLES', 'TRIGGER', 'CREATE VIEW', - 'SHOW VIEW', 'ALTER ROUTINE', 'CREATE ROUTINE', - 'EXECUTE', 'FILE', 'CREATE TABLESPACE', 'CREATE USER', - 'PROCESS', 'PROXY', 'RELOAD', 'REPLICATION CLIENT', - 'REPLICATION SLAVE', 'SHOW DATABASES', 'SHUTDOWN', - 'SUPER', 'ALL', 'ALL PRIVILEGES', 'USAGE', 'REQUIRESSL', - 'CREATE ROLE', 'DROP ROLE', 'APPLICATION_PASSWORD_ADMIN', - 'AUDIT_ADMIN', 'BACKUP_ADMIN', 'BINLOG_ADMIN', - 'BINLOG_ENCRYPTION_ADMIN', 'CLONE_ADMIN', 'CONNECTION_ADMIN', - 'ENCRYPTION_KEY_ADMIN', 'FIREWALL_ADMIN', 'FIREWALL_USER', - 'GROUP_REPLICATION_ADMIN', 'INNODB_REDO_LOG_ARCHIVE', - 'NDB_STORED_USER', 'PERSIST_RO_VARIABLES_ADMIN', - 'REPLICATION_APPLIER', 'REPLICATION_SLAVE_ADMIN', - 'RESOURCE_GROUP_ADMIN', 'RESOURCE_GROUP_USER', - 'ROLE_ADMIN', 'SESSION_VARIABLES_ADMIN', 'SET_USER_ID', - 'SYSTEM_USER', 'SYSTEM_VARIABLES_ADMIN', 'SYSTEM_USER', - 'TABLE_ENCRYPTION_ADMIN', 'VERSION_TOKEN_ADMIN', - 'XA_RECOVER_ADMIN', 'LOAD FROM S3', 'SELECT INTO S3', - 'INVOKE LAMBDA', - 'ALTER ROUTINE', - 'BINLOG ADMIN', - 'BINLOG MONITOR', - 'BINLOG REPLAY', - 'CONNECTION ADMIN', - 'READ_ONLY ADMIN', - 'REPLICATION MASTER ADMIN', - 'REPLICATION SLAVE', - 'REPLICATION SLAVE ADMIN', - 'SET USER',)) - - -class InvalidPrivsError(Exception): - pass - -# =========================================== -# MySQL module specific support methods. -# - - -# User Authentication Management changed in MySQL 5.7 and MariaDB 10.2.0 -def use_old_user_mgmt(cursor): - cursor.execute("SELECT VERSION()") - result = cursor.fetchone() - version_str = result[0] - version = version_str.split('.') - - if 'mariadb' in version_str.lower(): - # Prior to MariaDB 10.2 - if int(version[0]) * 1000 + int(version[1]) < 10002: - return True - else: - return False - else: - # Prior to MySQL 5.7 - if int(version[0]) * 1000 + int(version[1]) < 5007: - return True - else: - return False - - -def get_mode(cursor): - cursor.execute('SELECT @@GLOBAL.sql_mode') - result = cursor.fetchone() - mode_str = result[0] - if 'ANSI' in mode_str: - mode = 'ANSI' - else: - mode = 'NOTANSI' - return mode - - -def user_exists(cursor, user, host, host_all): - if host_all: - cursor.execute("SELECT count(*) FROM mysql.user WHERE user = %s", (user,)) - else: - cursor.execute("SELECT count(*) FROM mysql.user WHERE user = %s AND host = %s", (user, host)) - - count = cursor.fetchone() - return count[0] > 0 - - -def user_add(cursor, user, host, host_all, password, encrypted, - plugin, plugin_hash_string, plugin_auth_string, new_priv, check_mode): - # we cannot create users without a proper hostname - if host_all: - return False - - if check_mode: - return True - - # Determine what user management method server uses - old_user_mgmt = use_old_user_mgmt(cursor) - - if password and encrypted: - cursor.execute("CREATE USER %s@%s IDENTIFIED BY PASSWORD %s", (user, host, password)) - elif password and not encrypted: - if old_user_mgmt: - cursor.execute("CREATE USER %s@%s IDENTIFIED BY %s", (user, host, password)) - else: - cursor.execute("SELECT CONCAT('*', UCASE(SHA1(UNHEX(SHA1(%s)))))", (password,)) - encrypted_password = cursor.fetchone()[0] - cursor.execute("CREATE USER %s@%s IDENTIFIED WITH mysql_native_password AS %s", (user, host, encrypted_password)) - - elif plugin and plugin_hash_string: - cursor.execute("CREATE USER %s@%s IDENTIFIED WITH %s AS %s", (user, host, plugin, plugin_hash_string)) - elif plugin and plugin_auth_string: - cursor.execute("CREATE USER %s@%s IDENTIFIED WITH %s BY %s", (user, host, plugin, plugin_auth_string)) - elif plugin: - cursor.execute("CREATE USER %s@%s IDENTIFIED WITH %s", (user, host, plugin)) - else: - cursor.execute("CREATE USER %s@%s", (user, host)) - if new_priv is not None: - for db_table, priv in iteritems(new_priv): - privileges_grant(cursor, user, host, db_table, priv) - return True - - -def is_hash(password): - ishash = False - if len(password) == 41 and password[0] == '*': - if frozenset(password[1:]).issubset(string.hexdigits): - ishash = True - return ishash - - -def user_mod(cursor, user, host, host_all, password, encrypted, - plugin, plugin_hash_string, plugin_auth_string, new_priv, append_privs, module): - changed = False - msg = "User unchanged" - grant_option = False - - if host_all: - hostnames = user_get_hostnames(cursor, [user]) - else: - hostnames = [host] - - for host in hostnames: - # Handle clear text and hashed passwords. - if bool(password): - # Determine what user management method server uses - old_user_mgmt = use_old_user_mgmt(cursor) - - # Get a list of valid columns in mysql.user table to check if Password and/or authentication_string exist - cursor.execute(""" - SELECT COLUMN_NAME FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user' AND COLUMN_NAME IN ('Password', 'authentication_string') - ORDER BY COLUMN_NAME DESC LIMIT 1 - """) - colA = cursor.fetchone() - - cursor.execute(""" - SELECT COLUMN_NAME FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user' AND COLUMN_NAME IN ('Password', 'authentication_string') - ORDER BY COLUMN_NAME ASC LIMIT 1 - """) - colB = cursor.fetchone() - - # Select hash from either Password or authentication_string, depending which one exists and/or is filled - cursor.execute(""" - SELECT COALESCE( - CASE WHEN %s = '' THEN NULL ELSE %s END, - CASE WHEN %s = '' THEN NULL ELSE %s END - ) - FROM mysql.user WHERE user = %%s AND host = %%s - """ % (colA[0], colA[0], colB[0], colB[0]), (user, host)) - current_pass_hash = cursor.fetchone()[0] - if isinstance(current_pass_hash, bytes): - current_pass_hash = current_pass_hash.decode('ascii') - - if encrypted: - encrypted_password = password - if not is_hash(encrypted_password): - module.fail_json(msg="encrypted was specified however it does not appear to be a valid hash expecting: *SHA1(SHA1(your_password))") - else: - if old_user_mgmt: - cursor.execute("SELECT PASSWORD(%s)", (password,)) - else: - cursor.execute("SELECT CONCAT('*', UCASE(SHA1(UNHEX(SHA1(%s)))))", (password,)) - encrypted_password = cursor.fetchone()[0] - - if current_pass_hash != encrypted_password: - msg = "Password updated" - if module.check_mode: - return (True, msg) - if old_user_mgmt: - cursor.execute("SET PASSWORD FOR %s@%s = %s", (user, host, encrypted_password)) - msg = "Password updated (old style)" - else: - try: - cursor.execute("ALTER USER %s@%s IDENTIFIED WITH mysql_native_password AS %s", (user, host, encrypted_password)) - msg = "Password updated (new style)" - except (mysql_driver.Error) as e: - # https://stackoverflow.com/questions/51600000/authentication-string-of-root-user-on-mysql - # Replacing empty root password with new authentication mechanisms fails with error 1396 - if e.args[0] == 1396: - cursor.execute( - "UPDATE mysql.user SET plugin = %s, authentication_string = %s, Password = '' WHERE User = %s AND Host = %s", - ('mysql_native_password', encrypted_password, user, host) - ) - cursor.execute("FLUSH PRIVILEGES") - msg = "Password forced update" - else: - raise e - changed = True - - # Handle plugin authentication - if plugin: - cursor.execute("SELECT plugin, authentication_string FROM mysql.user " - "WHERE user = %s AND host = %s", (user, host)) - current_plugin = cursor.fetchone() - - update = False - - if current_plugin[0] != plugin: - update = True - - if plugin_hash_string and current_plugin[1] != plugin_hash_string: - update = True - - if plugin_auth_string and current_plugin[1] != plugin_auth_string: - # this case can cause more updates than expected, - # as plugin can hash auth_string in any way it wants - # and there's no way to figure it out for - # a check, so I prefer to update more often than never - update = True - - if update: - if plugin_hash_string: - cursor.execute("ALTER USER %s@%s IDENTIFIED WITH %s AS %s", (user, host, plugin, plugin_hash_string)) - elif plugin_auth_string: - cursor.execute("ALTER USER %s@%s IDENTIFIED WITH %s BY %s", (user, host, plugin, plugin_auth_string)) - else: - cursor.execute("ALTER USER %s@%s IDENTIFIED WITH %s", (user, host, plugin)) - changed = True - - # Handle privileges - if new_priv is not None: - curr_priv = privileges_get(cursor, user, host) - - # If the user has privileges on a db.table that doesn't appear at all in - # the new specification, then revoke all privileges on it. - for db_table, priv in iteritems(curr_priv): - # If the user has the GRANT OPTION on a db.table, revoke it first. - if "GRANT" in priv: - grant_option = True - if db_table not in new_priv: - if user != "root" and "PROXY" not in priv and not append_privs: - msg = "Privileges updated" - if module.check_mode: - return (True, msg) - privileges_revoke(cursor, user, host, db_table, priv, grant_option) - changed = True - - # If the user doesn't currently have any privileges on a db.table, then - # we can perform a straight grant operation. - for db_table, priv in iteritems(new_priv): - if db_table not in curr_priv: - msg = "New privileges granted" - if module.check_mode: - return (True, msg) - privileges_grant(cursor, user, host, db_table, priv) - changed = True - - # If the db.table specification exists in both the user's current privileges - # and in the new privileges, then we need to see if there's a difference. - db_table_intersect = set(new_priv.keys()) & set(curr_priv.keys()) - for db_table in db_table_intersect: - priv_diff = set(new_priv[db_table]) ^ set(curr_priv[db_table]) - if len(priv_diff) > 0: - msg = "Privileges updated" - if module.check_mode: - return (True, msg) - if not append_privs: - privileges_revoke(cursor, user, host, db_table, curr_priv[db_table], grant_option) - privileges_grant(cursor, user, host, db_table, new_priv[db_table]) - changed = True - - return (changed, msg) - - -def user_delete(cursor, user, host, host_all, check_mode): - if check_mode: - return True - - if host_all: - hostnames = user_get_hostnames(cursor, user) - - for hostname in hostnames: - cursor.execute("DROP USER %s@%s", (user, hostname)) - else: - cursor.execute("DROP USER %s@%s", (user, host)) - - return True - - -def user_get_hostnames(cursor, user): - cursor.execute("SELECT Host FROM mysql.user WHERE user = %s", (user,)) - hostnames_raw = cursor.fetchall() - hostnames = [] - - for hostname_raw in hostnames_raw: - hostnames.append(hostname_raw[0]) - - return hostnames - - -def privileges_get(cursor, user, host): - """ MySQL doesn't have a better method of getting privileges aside from the - SHOW GRANTS query syntax, which requires us to then parse the returned string. - Here's an example of the string that is returned from MySQL: - - GRANT USAGE ON *.* TO 'user'@'localhost' IDENTIFIED BY 'pass'; - - This function makes the query and returns a dictionary containing the results. - The dictionary format is the same as that returned by privileges_unpack() below. - """ - output = {} - cursor.execute("SHOW GRANTS FOR %s@%s", (user, host)) - grants = cursor.fetchall() - - def pick(x): - if x == 'ALL PRIVILEGES': - return 'ALL' - else: - return x - - for grant in grants: - res = re.match("""GRANT (.+) ON (.+) TO (['`"]).*\\3@(['`"]).*\\4( IDENTIFIED BY PASSWORD (['`"]).+\\6)? ?(.*)""", grant[0]) - if res is None: - raise InvalidPrivsError('unable to parse the MySQL grant string: %s' % grant[0]) - privileges = res.group(1).split(",") - privileges = [pick(x.strip()) for x in privileges] - if "WITH GRANT OPTION" in res.group(7): - privileges.append('GRANT') - if "REQUIRE SSL" in res.group(7): - privileges.append('REQUIRESSL') - db = res.group(2) - output.setdefault(db, []).extend(privileges) - return output - - -def privileges_unpack(priv, mode): - """ Take a privileges string, typically passed as a parameter, and unserialize - it into a dictionary, the same format as privileges_get() above. We have this - custom format to avoid using YAML/JSON strings inside YAML playbooks. Example - of a privileges string: - - mydb.*:INSERT,UPDATE/anotherdb.*:SELECT/yetanother.*:ALL - - The privilege USAGE stands for no privileges, so we add that in on *.* if it's - not specified in the string, as MySQL will always provide this by default. - """ - if mode == 'ANSI': - quote = '"' - else: - quote = '`' - output = {} - privs = [] - for item in priv.strip().split('/'): - pieces = item.strip().rsplit(':', 1) - dbpriv = pieces[0].rsplit(".", 1) - - # Check for FUNCTION or PROCEDURE object types - parts = dbpriv[0].split(" ", 1) - object_type = '' - if len(parts) > 1 and (parts[0] == 'FUNCTION' or parts[0] == 'PROCEDURE'): - object_type = parts[0] + ' ' - dbpriv[0] = parts[1] - - # Do not escape if privilege is for database or table, i.e. - # neither quote *. nor .* - for i, side in enumerate(dbpriv): - if side.strip('`') != '*': - dbpriv[i] = '%s%s%s' % (quote, side.strip('`'), quote) - pieces[0] = object_type + '.'.join(dbpriv) - - if '(' in pieces[1]: - output[pieces[0]] = re.split(r',\s*(?=[^)]*(?:\(|$))', pieces[1].upper()) - for i in output[pieces[0]]: - privs.append(re.sub(r'\s*\(.*\)', '', i)) - else: - output[pieces[0]] = pieces[1].upper().split(',') - privs = output[pieces[0]] - new_privs = frozenset(privs) - if not new_privs.issubset(VALID_PRIVS): - raise InvalidPrivsError('Invalid privileges specified: %s' % new_privs.difference(VALID_PRIVS)) - - if '*.*' not in output: - output['*.*'] = ['USAGE'] - - # if we are only specifying something like REQUIRESSL and/or GRANT (=WITH GRANT OPTION) in *.* - # we still need to add USAGE as a privilege to avoid syntax errors - if 'REQUIRESSL' in priv and not set(output['*.*']).difference(set(['GRANT', 'REQUIRESSL'])): - output['*.*'].append('USAGE') - - return output - - -def privileges_revoke(cursor, user, host, db_table, priv, grant_option): - # Escape '%' since mysql db.execute() uses a format string - db_table = db_table.replace('%', '%%') - if grant_option: - query = ["REVOKE GRANT OPTION ON %s" % db_table] - query.append("FROM %s@%s") - query = ' '.join(query) - cursor.execute(query, (user, host)) - priv_string = ",".join([p for p in priv if p not in ('GRANT', 'REQUIRESSL')]) - query = ["REVOKE %s ON %s" % (priv_string, db_table)] - query.append("FROM %s@%s") - query = ' '.join(query) - cursor.execute(query, (user, host)) - - -def privileges_grant(cursor, user, host, db_table, priv): - # Escape '%' since mysql db.execute uses a format string and the - # specification of db and table often use a % (SQL wildcard) - db_table = db_table.replace('%', '%%') - priv_string = ",".join([p for p in priv if p not in ('GRANT', 'REQUIRESSL')]) - query = ["GRANT %s ON %s" % (priv_string, db_table)] - query.append("TO %s@%s") - if 'REQUIRESSL' in priv: - query.append("REQUIRE SSL") - if 'GRANT' in priv: - query.append("WITH GRANT OPTION") - query = ' '.join(query) - cursor.execute(query, (user, host)) - - -def convert_priv_dict_to_str(priv): - """Converts privs dictionary to string of certain format. - - Args: - priv (dict): Dict of privileges that needs to be converted to string. - - Returns: - priv (str): String representation of input argument. - """ - priv_list = ['%s:%s' % (key, val) for key, val in iteritems(priv)] - - return '/'.join(priv_list) - - -# Alter user is supported since MySQL 5.6 and MariaDB 10.2.0 -def server_supports_alter_user(cursor): - """Check if the server supports ALTER USER statement or doesn't. - - Args: - cursor (cursor): DB driver cursor object. - - Returns: True if supports, False otherwise. - """ - cursor.execute("SELECT VERSION()") - version_str = cursor.fetchone()[0] - version = version_str.split('.') - - if 'mariadb' in version_str.lower(): - # MariaDB 10.2 and later - if int(version[0]) * 1000 + int(version[1]) >= 10002: - return True - else: - return False - else: - # MySQL 5.6 and later - if int(version[0]) * 1000 + int(version[1]) >= 5006: - return True - else: - return False - - -def get_resource_limits(cursor, user, host): - """Get user resource limits. - - Args: - cursor (cursor): DB driver cursor object. - user (str): User name. - host (str): User host name. - - Returns: Dictionary containing current resource limits. - """ - - query = ('SELECT max_questions AS MAX_QUERIES_PER_HOUR, ' - 'max_updates AS MAX_UPDATES_PER_HOUR, ' - 'max_connections AS MAX_CONNECTIONS_PER_HOUR, ' - 'max_user_connections AS MAX_USER_CONNECTIONS ' - 'FROM mysql.user WHERE User = %s AND Host = %s') - cursor.execute(query, (user, host)) - res = cursor.fetchone() - - if not res: - return None - - current_limits = { - 'MAX_QUERIES_PER_HOUR': res[0], - 'MAX_UPDATES_PER_HOUR': res[1], - 'MAX_CONNECTIONS_PER_HOUR': res[2], - 'MAX_USER_CONNECTIONS': res[3], - } - return current_limits - - -def match_resource_limits(module, current, desired): - """Check and match limits. - - Args: - module (AnsibleModule): Ansible module object. - current (dict): Dictionary with current limits. - desired (dict): Dictionary with desired limits. - - Returns: Dictionary containing parameters that need to change. - """ - - if not current: - # It means the user does not exists, so we need - # to set all limits after its creation - return desired - - needs_to_change = {} - - for key, val in iteritems(desired): - if key not in current: - # Supported keys are listed in the documentation - # and must be determined in the get_resource_limits function - # (follow 'AS' keyword) - module.fail_json(msg="resource_limits: key '%s' is unsupported." % key) - - try: - val = int(val) - except Exception: - module.fail_json(msg="Can't convert value '%s' to integer." % val) - - if val != current.get(key): - needs_to_change[key] = val - - return needs_to_change - - -def limit_resources(module, cursor, user, host, resource_limits, check_mode): - """Limit user resources. - - Args: - module (AnsibleModule): Ansible module object. - cursor (cursor): DB driver cursor object. - user (str): User name. - host (str): User host name. - resource_limit (dict): Dictionary with desired limits. - check_mode (bool): Run the function in check mode or not. - - Returns: True, if changed, False otherwise. - """ - if not server_supports_alter_user(cursor): - module.fail_json(msg="The server version does not match the requirements " - "for resource_limits parameter. See module's documentation.") - - current_limits = get_resource_limits(cursor, user, host) - - needs_to_change = match_resource_limits(module, current_limits, resource_limits) - - if not needs_to_change: - return False - - if needs_to_change and check_mode: - return True - - # If not check_mode - tmp = [] - for key, val in iteritems(needs_to_change): - tmp.append('%s %s' % (key, val)) - - query = "ALTER USER %s@%s" - query += ' WITH %s' % ' '.join(tmp) - cursor.execute(query, (user, host)) - return True - -# =========================================== -# Module execution. -# - - -def main(): - module = AnsibleModule( - argument_spec=dict( - login_user=dict(type='str'), - login_password=dict(type='str', no_log=True), - login_host=dict(type='str', default='localhost'), - login_port=dict(type='int', default=3306), - login_unix_socket=dict(type='str'), - user=dict(type='str', required=True, aliases=['name']), - password=dict(type='str', no_log=True), - encrypted=dict(type='bool', default=False), - host=dict(type='str', default='localhost'), - host_all=dict(type="bool", default=False), - state=dict(type='str', default='present', choices=['absent', 'present']), - priv=dict(type='raw'), - append_privs=dict(type='bool', default=False), - check_implicit_admin=dict(type='bool', default=False), - update_password=dict(type='str', default='always', choices=['always', 'on_create'], no_log=False), - connect_timeout=dict(type='int', default=30), - config_file=dict(type='path', default='~/.my.cnf'), - sql_log_bin=dict(type='bool', default=True), - client_cert=dict(type='path', aliases=['ssl_cert']), - client_key=dict(type='path', aliases=['ssl_key']), - ca_cert=dict(type='path', aliases=['ssl_ca']), - plugin=dict(default=None, type='str'), - plugin_hash_string=dict(default=None, type='str'), - plugin_auth_string=dict(default=None, type='str'), - resource_limits=dict(type='dict'), - ), - supports_check_mode=True, - ) - login_user = module.params["login_user"] - login_password = module.params["login_password"] - user = module.params["user"] - password = module.params["password"] - encrypted = module.boolean(module.params["encrypted"]) - host = module.params["host"].lower() - host_all = module.params["host_all"] - state = module.params["state"] - priv = module.params["priv"] - check_implicit_admin = module.params['check_implicit_admin'] - connect_timeout = module.params['connect_timeout'] - config_file = module.params['config_file'] - append_privs = module.boolean(module.params["append_privs"]) - update_password = module.params['update_password'] - ssl_cert = module.params["client_cert"] - ssl_key = module.params["client_key"] - ssl_ca = module.params["ca_cert"] - db = '' - sql_log_bin = module.params["sql_log_bin"] - plugin = module.params["plugin"] - plugin_hash_string = module.params["plugin_hash_string"] - plugin_auth_string = module.params["plugin_auth_string"] - resource_limits = module.params["resource_limits"] - if priv and not (isinstance(priv, str) or isinstance(priv, dict)): - module.fail_json(msg="priv parameter must be str or dict but %s was passed" % type(priv)) - - if priv and isinstance(priv, dict): - priv = convert_priv_dict_to_str(priv) - - if mysql_driver is None: - module.fail_json(msg=mysql_driver_fail_msg) - - cursor = None - try: - if check_implicit_admin: - try: - cursor, db_conn = mysql_connect(module, 'root', '', config_file, ssl_cert, ssl_key, ssl_ca, db, - connect_timeout=connect_timeout) - except Exception: - pass - - if not cursor: - cursor, db_conn = mysql_connect(module, login_user, login_password, config_file, ssl_cert, ssl_key, ssl_ca, db, - connect_timeout=connect_timeout) - except Exception as e: - 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, to_native(e))) - - if not sql_log_bin: - cursor.execute("SET SQL_LOG_BIN=0;") - - if priv is not None: - try: - mode = get_mode(cursor) - except Exception as e: - module.fail_json(msg=to_native(e)) - try: - priv = privileges_unpack(priv, mode) - except Exception as e: - module.fail_json(msg="invalid privileges string: %s" % to_native(e)) - - if state == "present": - if user_exists(cursor, user, host, host_all): - try: - if update_password == 'always': - changed, msg = user_mod(cursor, user, host, host_all, password, encrypted, - plugin, plugin_hash_string, plugin_auth_string, - priv, append_privs, module) - else: - changed, msg = user_mod(cursor, user, host, host_all, None, encrypted, - plugin, plugin_hash_string, plugin_auth_string, - priv, append_privs, module) - - except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e: - module.fail_json(msg=to_native(e)) - else: - if host_all: - module.fail_json(msg="host_all parameter cannot be used when adding a user") - try: - changed = user_add(cursor, user, host, host_all, password, encrypted, - plugin, plugin_hash_string, plugin_auth_string, - priv, module.check_mode) - if changed: - msg = "User added" - - except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e: - module.fail_json(msg=to_native(e)) - - if resource_limits: - changed = limit_resources(module, cursor, user, host, resource_limits, module.check_mode) or changed - - elif state == "absent": - if user_exists(cursor, user, host, host_all): - changed = user_delete(cursor, user, host, host_all, module.check_mode) - msg = "User deleted" - else: - changed = False - msg = "User doesn't exist" - module.exit_json(changed=changed, user=user, msg=msg) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/database/mysql/mysql_variables.py b/plugins/modules/database/mysql/mysql_variables.py deleted file mode 100644 index 153cbe523d..0000000000 --- a/plugins/modules/database/mysql/mysql_variables.py +++ /dev/null @@ -1,272 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2013, Balazs Pocze -# Certain parts are taken from Mark Theunissen's mysqldb module -# 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 - -DOCUMENTATION = r''' ---- -module: mysql_variables - -short_description: Manage MySQL global variables -description: -- Query / Set MySQL variables. -author: -- Balazs Pocze (@banyek) -options: - variable: - description: - - Variable name to operate - type: str - required: yes - value: - description: - - If set, then sets variable value to this - type: str - mode: - description: - - C(global) assigns C(value) to a global system variable which will be changed at runtime - but won't persist across server restarts. - - C(persist) assigns C(value) to a global system variable and persists it to - the mysqld-auto.cnf option file in the data directory - (the variable will survive service restarts). - - C(persist_only) persists C(value) to the mysqld-auto.cnf option file in the data directory - but without setting the global variable runtime value - (the value will be changed after the next service restart). - - Supported by MySQL 8.0 or later. - - For more information see U(https://dev.mysql.com/doc/refman/8.0/en/set-variable.html). - type: str - choices: ['global', 'persist', 'persist_only'] - default: global - version_added: '0.2.0' - -seealso: -- module: community.general.mysql_info -- name: MySQL SET command reference - description: Complete reference of the MySQL SET command documentation. - link: https://dev.mysql.com/doc/refman/8.0/en/set-statement.html - -extends_documentation_fragment: -- community.general.mysql - -''' - -EXAMPLES = r''' -- name: Check for sync_binlog setting - mysql_variables: - variable: sync_binlog - -- name: Set read_only variable to 1 persistently - mysql_variables: - variable: read_only - value: 1 - mode: persist -''' - -RETURN = r''' -queries: - description: List of executed queries which modified DB's state. - returned: if executed - type: list - sample: ["SET GLOBAL `read_only` = 1"] - version_added: '0.2.0' -''' - -import os -import warnings -from re import match - -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.community.general.plugins.module_utils.database import SQLParseError, mysql_quote_identifier -from ansible_collections.community.general.plugins.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg -from ansible.module_utils._text import to_native - -executed_queries = [] - - -def check_mysqld_auto(module, cursor, mysqlvar): - """Check variable's value in mysqld-auto.cnf.""" - query = ("SELECT VARIABLE_VALUE " - "FROM performance_schema.persisted_variables " - "WHERE VARIABLE_NAME = %s") - try: - cursor.execute(query, (mysqlvar,)) - res = cursor.fetchone() - except Exception as e: - if "Table 'performance_schema.persisted_variables' doesn't exist" in str(e): - module.fail_json(msg='Server version must be 8.0 or greater.') - - if res: - return res[0] - else: - return None - - -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): - cursor.execute("SHOW VARIABLES WHERE Variable_name = %s", (mysqlvar,)) - mysqlvar_val = cursor.fetchall() - if len(mysqlvar_val) == 1: - return mysqlvar_val[0][1] - else: - return None - - -def setvariable(cursor, mysqlvar, value, mode='global'): - """ 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. - - """ - if mode == 'persist': - query = "SET PERSIST %s = " % mysql_quote_identifier(mysqlvar, 'vars') - elif mode == 'global': - query = "SET GLOBAL %s = " % mysql_quote_identifier(mysqlvar, 'vars') - elif mode == 'persist_only': - query = "SET PERSIST_ONLY %s = " % mysql_quote_identifier(mysqlvar, 'vars') - - try: - cursor.execute(query + "%s", (value,)) - executed_queries.append(query + "%s" % value) - cursor.fetchall() - result = True - except Exception as e: - result = to_native(e) - - return result - - -def main(): - module = AnsibleModule( - argument_spec=dict( - login_user=dict(type='str'), - login_password=dict(type='str', no_log=True), - login_host=dict(type='str', default='localhost'), - login_port=dict(type='int', default=3306), - login_unix_socket=dict(type='str'), - variable=dict(type='str'), - value=dict(type='str'), - client_cert=dict(type='path', aliases=['ssl_cert']), - client_key=dict(type='path', aliases=['ssl_key']), - ca_cert=dict(type='path', aliases=['ssl_ca']), - connect_timeout=dict(type='int', default=30), - config_file=dict(type='path', default='~/.my.cnf'), - mode=dict(type='str', choices=['global', 'persist', 'persist_only'], default='global'), - ), - ) - user = module.params["login_user"] - password = module.params["login_password"] - connect_timeout = module.params['connect_timeout'] - ssl_cert = module.params["client_cert"] - ssl_key = module.params["client_key"] - ssl_ca = module.params["ca_cert"] - config_file = module.params['config_file'] - db = 'mysql' - - mysqlvar = module.params["variable"] - value = module.params["value"] - mode = module.params["mode"] - - if mysqlvar is None: - module.fail_json(msg="Cannot run without variable to operate with") - if match('^[0-9a-z_.]+$', mysqlvar) is None: - module.fail_json(msg="invalid variable name \"%s\"" % mysqlvar) - if mysql_driver is None: - module.fail_json(msg=mysql_driver_fail_msg) - else: - warnings.filterwarnings('error', category=mysql_driver.Warning) - - try: - cursor, db_conn = mysql_connect(module, user, password, config_file, ssl_cert, ssl_key, ssl_ca, db, - connect_timeout=connect_timeout) - except Exception as e: - 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, to_native(e)))) - else: - module.fail_json(msg="unable to find %s. Exception message: %s" % (config_file, to_native(e))) - - mysqlvar_val = None - var_in_mysqld_auto_cnf = None - - mysqlvar_val = getvariable(cursor, mysqlvar) - if mysqlvar_val is None: - module.fail_json(msg="Variable not available \"%s\"" % mysqlvar, changed=False) - - if value is None: - module.exit_json(msg=mysqlvar_val) - - if mode in ('persist', 'persist_only'): - var_in_mysqld_auto_cnf = check_mysqld_auto(module, cursor, mysqlvar) - - if mode == 'persist_only': - if var_in_mysqld_auto_cnf is None: - mysqlvar_val = False - else: - mysqlvar_val = var_in_mysqld_auto_cnf - - # Type values before using them - value_wanted = typedvalue(value) - value_actual = typedvalue(mysqlvar_val) - value_in_auto_cnf = None - if var_in_mysqld_auto_cnf is not None: - value_in_auto_cnf = typedvalue(var_in_mysqld_auto_cnf) - - if value_wanted == value_actual and mode in ('global', 'persist'): - if mode == 'persist' and value_wanted == value_in_auto_cnf: - module.exit_json(msg="Variable is already set to requested value globally" - "and stored into mysqld-auto.cnf file.", changed=False) - - elif mode == 'global': - module.exit_json(msg="Variable is already set to requested value.", changed=False) - - if mode == 'persist_only' and value_wanted == value_in_auto_cnf: - module.exit_json(msg="Variable is already stored into mysqld-auto.cnf " - "with requested value.", changed=False) - - try: - result = setvariable(cursor, mysqlvar, value_wanted, mode) - except SQLParseError as e: - result = to_native(e) - - if result is True: - module.exit_json(msg="Variable change succeeded prev_value=%s" % value_actual, - changed=True, queries=executed_queries) - else: - module.fail_json(msg=result, changed=False) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/mysql_db.py b/plugins/modules/mysql_db.py deleted file mode 120000 index eb08339591..0000000000 --- a/plugins/modules/mysql_db.py +++ /dev/null @@ -1 +0,0 @@ -./database/mysql/mysql_db.py \ No newline at end of file diff --git a/plugins/modules/mysql_info.py b/plugins/modules/mysql_info.py deleted file mode 120000 index 46f1ea5143..0000000000 --- a/plugins/modules/mysql_info.py +++ /dev/null @@ -1 +0,0 @@ -./database/mysql/mysql_info.py \ No newline at end of file diff --git a/plugins/modules/mysql_query.py b/plugins/modules/mysql_query.py deleted file mode 120000 index b31a8cab4a..0000000000 --- a/plugins/modules/mysql_query.py +++ /dev/null @@ -1 +0,0 @@ -./database/mysql/mysql_query.py \ No newline at end of file diff --git a/plugins/modules/mysql_replication.py b/plugins/modules/mysql_replication.py deleted file mode 120000 index 2e876888b1..0000000000 --- a/plugins/modules/mysql_replication.py +++ /dev/null @@ -1 +0,0 @@ -./database/mysql/mysql_replication.py \ No newline at end of file diff --git a/plugins/modules/mysql_user.py b/plugins/modules/mysql_user.py deleted file mode 120000 index 3baee002e3..0000000000 --- a/plugins/modules/mysql_user.py +++ /dev/null @@ -1 +0,0 @@ -./database/mysql/mysql_user.py \ No newline at end of file diff --git a/plugins/modules/mysql_variables.py b/plugins/modules/mysql_variables.py deleted file mode 120000 index 3ed7b62558..0000000000 --- a/plugins/modules/mysql_variables.py +++ /dev/null @@ -1 +0,0 @@ -./database/mysql/mysql_variables.py \ No newline at end of file diff --git a/tests/integration/targets/mariadb_replication/aliases b/tests/integration/targets/mariadb_replication/aliases deleted file mode 100644 index 1065935fc1..0000000000 --- a/tests/integration/targets/mariadb_replication/aliases +++ /dev/null @@ -1,7 +0,0 @@ -destructive -unsupported # these tests conflict with mysql_replication tests and do not run on changes to the mysql_replication module -skip/aix -skip/osx -skip/freebsd -skip/rhel -needs/root diff --git a/tests/integration/targets/mariadb_replication/defaults/main.yml b/tests/integration/targets/mariadb_replication/defaults/main.yml deleted file mode 100644 index 3751f4ef1c..0000000000 --- a/tests/integration/targets/mariadb_replication/defaults/main.yml +++ /dev/null @@ -1,7 +0,0 @@ -master_port: 3306 -standby_port: 3307 -test_db: test_db -replication_user: replication_user -replication_pass: replication_pass -dump_path: /tmp/dump.sql -conn_name: master-1 diff --git a/tests/integration/targets/mariadb_replication/meta/main.yml b/tests/integration/targets/mariadb_replication/meta/main.yml deleted file mode 100644 index 7198617132..0000000000 --- a/tests/integration/targets/mariadb_replication/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -dependencies: -- setup_mariadb diff --git a/tests/integration/targets/mariadb_replication/tasks/main.yml b/tests/integration/targets/mariadb_replication/tasks/main.yml deleted file mode 100644 index 4ea76a9e84..0000000000 --- a/tests/integration/targets/mariadb_replication/tasks/main.yml +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Initial CI tests of mysql_replication module -- import_tasks: mariadb_replication_initial.yml - when: - - ansible_facts.distribution == 'CentOS' - - ansible_facts.distribution_major_version is version('7', '>=') - -# Tests of master_use_gtid parameter -# https://github.com/ansible/ansible/pull/62648 -- import_tasks: mariadb_master_use_gtid.yml - when: - - ansible_facts.distribution == 'CentOS' - - ansible_facts.distribution_major_version is version('7', '>=') - -# Tests of connection_name parameter -- import_tasks: mariadb_replication_connection_name.yml - when: - - ansible_facts.distribution == 'CentOS' - - ansible_facts.distribution_major_version is version('7', '>=') diff --git a/tests/integration/targets/mariadb_replication/tasks/mariadb_master_use_gtid.yml b/tests/integration/targets/mariadb_replication/tasks/mariadb_master_use_gtid.yml deleted file mode 100644 index e3e760589d..0000000000 --- a/tests/integration/targets/mariadb_replication/tasks/mariadb_master_use_gtid.yml +++ /dev/null @@ -1,173 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Tests for master_use_gtid parameter. -# https://github.com/ansible/ansible/pull/62648 - -############################# -# master_use_gtid: "disabled" -############################# - -# Auxiliary step: -- name: Get master status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ primary_db.port }}" - mode: getmaster - register: primary_status - -# Set master_use_gtid disabled: -- name: Run replication - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: changemaster - master_host: 127.0.0.1 - master_port: "{{ primary_db.port }}" - master_user: "{{ replication_user }}" - master_password: "{{ replication_pass }}" - master_log_file: mysql-bin.000001 - master_log_pos: '{{ primary_status.Position }}' - master_use_gtid: disabled - register: result - -- assert: - that: - - result is changed - -# Start standby for further tests: -- name: Start standby - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ primary_db.port }}" - mode: startslave - -- name: Get standby status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: getslave - register: slave_status - -- assert: - that: - - slave_status.Using_Gtid == 'No' - -# Stop standby for further tests: -- name: Stop standby - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: stopslave - -################################ -# master_use_gtid: "current_pos" -################################ - -# Auxiliary step: -- name: Get master status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ primary_db.port }}" - mode: getmaster - register: primary_status - -# Set master_use_gtid current_pos: -- name: Run replication - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: changemaster - master_host: 127.0.0.1 - master_port: "{{ primary_db.port }}" - master_user: "{{ replication_user }}" - master_password: "{{ replication_pass }}" - master_log_file: mysql-bin.000001 - master_log_pos: '{{ primary_status.Position }}' - master_use_gtid: current_pos - register: result - -- assert: - that: - - result is changed - -# Start standby for further tests: -- name: Start standby - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ primary_db.port }}" - mode: startslave - -- name: Get standby status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: getslave - register: slave_status - -- assert: - that: - - slave_status.Using_Gtid == 'Current_Pos' - -# Stop standby for further tests: -- name: Stop standby - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: stopslave - -############################## -# master_use_gtid: "slave_pos" -############################## - -# Auxiliary step: -- name: Get master status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ primary_db.port }}" - mode: getmaster - register: primary_status - -# Set master_use_gtid slave_pos: -- name: Run replication - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: changemaster - master_host: 127.0.0.1 - master_port: "{{ primary_db.port }}" - master_user: "{{ replication_user }}" - master_password: "{{ replication_pass }}" - master_log_file: mysql-bin.000001 - master_log_pos: '{{ primary_status.Position }}' - master_use_gtid: slave_pos - register: result - -- assert: - that: - - result is changed - -# Start standby for further tests: -- name: Start standby - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ primary_db.port }}" - mode: startslave - -- name: Get standby status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: getslave - register: slave_status - -- assert: - that: - - slave_status.Using_Gtid == 'Slave_Pos' - -# Stop standby for further tests: -- name: Stop standby - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: stopslave diff --git a/tests/integration/targets/mariadb_replication/tasks/mariadb_replication_connection_name.yml b/tests/integration/targets/mariadb_replication/tasks/mariadb_replication_connection_name.yml deleted file mode 100644 index 98fa5fe62d..0000000000 --- a/tests/integration/targets/mariadb_replication/tasks/mariadb_replication_connection_name.yml +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Needs for further tests: -- name: Stop slave - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: stopslave - -- name: Reset slave all - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: resetslaveall - -# Get master log pos: -- name: Get master status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ primary_db.port }}" - mode: getmaster - register: primary_status - -# Test changemaster mode: -- name: Run replication with connection_name - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: changemaster - master_host: 127.0.0.1 - master_port: "{{ primary_db.port }}" - master_user: "{{ replication_user }}" - master_password: "{{ replication_pass }}" - master_log_file: mysql-bin.000001 - master_log_pos: '{{ primary_status.Position }}' - connection_name: '{{ conn_name }}' - register: result - -- assert: - that: - - result is changed - - result.queries[0] is match("CHANGE MASTER ('\S+' )?TO MASTER_HOST='[0-9.]+',MASTER_USER='\w+',MASTER_PASSWORD='[*]{8}',MASTER_PORT=\d+,MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=\d+") - -# Test startslave mode: -- name: Start slave with connection_name - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: startslave - connection_name: "{{ conn_name }}" - register: result - -- assert: - that: - - result is changed - - result.queries == ["START SLAVE \'{{ conn_name }}\'"] - -# Test getslave mode: -- name: Get standby statu with connection_name - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: getslave - connection_name: "{{ conn_name }}" - register: slave_status - -- assert: - that: - - slave_status.Is_Slave == true - - slave_status.Master_Host == '127.0.0.1' - - slave_status.Exec_Master_Log_Pos == primary_status.Position - - slave_status.Master_Port == {{ primary_db.port }} - - slave_status.Last_IO_Errno == 0 - - slave_status.Last_IO_Error == '' - - slave_status is not changed - -# Test stopslave mode: -- name: Stop slave with connection_name - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: stopslave - connection_name: "{{ conn_name }}" - register: result - -- assert: - that: - - result is changed - - result.queries == ["STOP SLAVE \'{{ conn_name }}\'"] - -# Test reset -- name: Reset slave with connection_name - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: resetslave - connection_name: "{{ conn_name }}" - register: result - -- assert: - that: - - result is changed - - result.queries == ["RESET SLAVE \'{{ conn_name }}\'"] - -# Test reset all -- name: Reset slave all with connection_name - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: resetslaveall - connection_name: "{{ conn_name }}" - register: result - -- assert: - that: - - result is changed - - result.queries == ["RESET SLAVE \'{{ conn_name }}\' ALL"] diff --git a/tests/integration/targets/mariadb_replication/tasks/mariadb_replication_initial.yml b/tests/integration/targets/mariadb_replication/tasks/mariadb_replication_initial.yml deleted file mode 100644 index 86a67606da..0000000000 --- a/tests/integration/targets/mariadb_replication/tasks/mariadb_replication_initial.yml +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Preparation: -- name: Create user for replication - shell: "echo \"GRANT REPLICATION SLAVE ON *.* TO '{{ replication_user }}'@'localhost' IDENTIFIED BY '{{ replication_pass }}'; FLUSH PRIVILEGES;\" | mysql -P {{ primary_db.port }} -h 127.0.0.1" - -- name: Create test database - mysql_db: - login_host: 127.0.0.1 - login_port: '{{ primary_db.port }}' - state: present - name: '{{ test_db }}' - -- name: Dump all databases from the master - shell: 'mysqldump -P {{ primary_db.port }} -h 127.0.01 --all-databases --master-data=2 > {{ dump_path }}' - -- name: Restore the dump to the replica - shell: 'mysql -P {{ replica_db.port }} -h 127.0.0.1 < {{ dump_path }}' - -# Test getmaster mode: -- name: Get master status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ primary_db.port }}" - mode: getmaster - register: master_status - -- assert: - that: - - master_status.Is_Master == true - - master_status.Position != 0 - - master_status is not changed - -# Test changemaster mode: -- name: Run replication - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: changemaster - master_host: 127.0.0.1 - master_port: "{{ primary_db.port }}" - master_user: "{{ replication_user }}" - master_password: "{{ replication_pass }}" - master_log_file: mysql-bin.000001 - master_log_pos: '{{ master_status.Position }}' - register: result - -- assert: - that: - - result is changed - - result.queries[0] is match("CHANGE MASTER ('\S+' )?TO MASTER_HOST='[0-9.]+',MASTER_USER='\w+',MASTER_PASSWORD='[*]{8}',MASTER_PORT=\d+,MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=\d+") - -# Test startslave mode: -- name: Start slave - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: startslave - register: result - -- assert: - that: - - result is changed - - result.queries == ["START SLAVE"] - -# Test getslave mode: -- name: Get replica status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: getslave - register: slave_status - -- assert: - that: - - slave_status.Is_Slave == true - - slave_status.Master_Host == '127.0.0.1' - - slave_status.Exec_Master_Log_Pos == master_status.Position - - slave_status.Master_Port == {{ primary_db.port }} - - slave_status.Last_IO_Errno == 0 - - slave_status.Last_IO_Error == '' - - slave_status is not changed - -# Test stopslave mode: -- name: Stop slave - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ replica_db.port }}" - mode: stopslave - register: result - -- assert: - that: - - result is changed - - result.queries == ["STOP SLAVE"] diff --git a/tests/integration/targets/mysql_db/aliases b/tests/integration/targets/mysql_db/aliases deleted file mode 100644 index ee2c7af58f..0000000000 --- a/tests/integration/targets/mysql_db/aliases +++ /dev/null @@ -1,5 +0,0 @@ -destructive -shippable/posix/group5 -skip/aix -skip/osx -skip/freebsd diff --git a/tests/integration/targets/mysql_db/defaults/main.yml b/tests/integration/targets/mysql_db/defaults/main.yml deleted file mode 100644 index 764064bcd6..0000000000 --- a/tests/integration/targets/mysql_db/defaults/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -# defaults file for test_mysql_db -db_name: 'data' -db_name2: 'data2' -db_user1: 'datauser1' -db_user2: 'datauser2' - -tmp_dir: '/tmp' -db_latin1_name: 'db_latin1' -file4: 'latin1_file' diff --git a/tests/integration/targets/mysql_db/meta/main.yml b/tests/integration/targets/mysql_db/meta/main.yml deleted file mode 100644 index 4aa170dc06..0000000000 --- a/tests/integration/targets/mysql_db/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - setup_mysql_db diff --git a/tests/integration/targets/mysql_db/tasks/config_overrides_defaults.yml b/tests/integration/targets/mysql_db/tasks/config_overrides_defaults.yml deleted file mode 100644 index 4dec21e4bb..0000000000 --- a/tests/integration/targets/mysql_db/tasks/config_overrides_defaults.yml +++ /dev/null @@ -1,71 +0,0 @@ -- set_fact: - db_to_create=testdb1 - config_file="/root/.my1.cnf" - fake_port=9999 - fake_host="blahblah.local" - -- name: Create custom config file - shell: 'echo "[client]" > {{ config_file }}' - -- name: Add fake port to config file - shell: 'echo "port = {{ fake_port }}" >> {{ config_file }}' - -- name: Create database using fake port to connect to, must fail - mysql_db: - name: '{{ db_to_create }}' - state: present - check_implicit_admin: yes - config_file: '{{ config_file }}' - config_overrides_defaults: yes - ignore_errors: yes - register: result - -- name: Must fail because login_port default has beed overriden by wrong value from config file - assert: - that: - - result is failed - - result.msg is search("unable to connect to database") - -- name: Create database using default port - mysql_db: - name: '{{ db_to_create }}' - state: present - check_implicit_admin: yes - config_file: '{{ config_file }}' - config_overrides_defaults: no - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: Must not fail because of the default of login_port is correct - assert: - that: - - result is changed - -- name: Reinit custom config file - shell: 'echo "[client]" > {{ config_file }}' - -- name: Add fake host to config file - shell: 'echo "host = {{ fake_host }}" >> {{ config_file }}' - -- name: Remove database using fake login_host - mysql_db: - name: '{{ db_to_create }}' - state: absent - config_file: '{{ config_file }}' - config_overrides_defaults: yes - register: result - ignore_errors: yes - -- name: Must fail because login_host default has beed overriden by wrong value from config file - assert: - that: - - result is failed - - result.msg is search("Can't connect to MySQL server on '{{ fake_host }}'") - -# Clean up -- name: Remove test db - mysql_db: - name: '{{ db_to_create }}' - state: absent - check_implicit_admin: yes - login_unix_socket: '{{ mysql_socket }}' diff --git a/tests/integration/targets/mysql_db/tasks/encoding_dump_import.yml b/tests/integration/targets/mysql_db/tasks/encoding_dump_import.yml deleted file mode 100644 index a1bacd1862..0000000000 --- a/tests/integration/targets/mysql_db/tasks/encoding_dump_import.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- - -- set_fact: - latin1_file1="{{tmp_dir}}/{{file}}" - -- name: Deleting Latin1 encoded Database - mysql_db: - name: '{{ db_latin1_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - -- name: create Latin1 encoded database - mysql_db: - name: '{{ db_latin1_name }}' - state: present - encoding: latin1 - login_unix_socket: '{{ mysql_socket }}' - -- name: create a table in Latin1 database - command: mysql {{ db_latin1_name }} -e 'create table testlatin1(id int, name varchar(100));' - - -# Inserting a string in latin1 into table, , this string be tested later, -# so report any change of content in the test too -- name: inserting data into Latin1 database - command: mysql {{ db_latin1_name }} -e "insert into testlatin1 value(47,'Amédée Bôlüt');" - -- name: selecting table - command: mysql {{ db_latin1_name }} -e "select * from testlatin1;" - register: output - -- name: Dumping a table in Latin1 database - mysql_db: - name: "{{ db_latin1_name }}" - encoding: latin1 - target: "{{ latin1_file1 }}" - state: dump - login_unix_socket: '{{ mysql_socket }}' - register: dump_result - -- assert: - that: - - result is changed - -- name: state dump - file name should exist - file: name={{ latin1_file1 }} state=file - -- name: od the file and check of latin1 encoded string is present - shell: grep -a 47 {{ latin1_file1 }} | od -c |grep "A m 351 d 351 e B 364\|A m 303 251 d 303 251 e B 303" - -- name: Dropping {{ db_latin1_name }} database - mysql_db: - name: '{{ db_latin1_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - -- name: Importing the latin1 mysql script - mysql_db: - state: import - encoding: latin1 - name: '{{ db_latin1_name }}' - target: "{{ latin1_file1 }}" - login_unix_socket: '{{ mysql_socket }}' - -- assert: - that: - - result is changed - -- name: check encoding of table - shell: mysql {{ db_latin1_name }} -e "SHOW FULL COLUMNS FROM testlatin1;" - register: output - failed_when: '"latin1_swedish_ci" not in output.stdout' - -- name: remove database - mysql_db: - name: '{{ db_latin1_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' diff --git a/tests/integration/targets/mysql_db/tasks/main.yml b/tests/integration/targets/mysql_db/tasks/main.yml deleted file mode 100644 index e719fe82ff..0000000000 --- a/tests/integration/targets/mysql_db/tasks/main.yml +++ /dev/null @@ -1,263 +0,0 @@ -# test code for the mysql_db module -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ - -- name: remove database if it exists - command: > - mysql -sse "drop database {{db_name}};" - ignore_errors: True - -- name: make sure the test database is not there - command: mysql {{db_name}} - register: mysql_db_check - failed_when: "'1049' not in mysql_db_check.stderr" - -- name: test state=present for a database name (expect changed=true) - mysql_db: - name: '{{ db_name }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message that database exist - assert: - that: - - result is changed - - result.db == '{{ db_name }}' - - result.executed_commands == ["CREATE DATABASE `{{ db_name }}`"] - -- name: run command to test state=present for a database name (expect db_name in stdout) - command: mysql "-e show databases like '{{ db_name }}';" - register: result - -- name: assert database exist - assert: { that: "'{{ db_name }}' in result.stdout" } - -# ============================================================ -- name: test state=absent for a database name (expect changed=true) - mysql_db: - name: '{{ db_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message that database does not exist - assert: - that: - - result is changed - - result.db == '{{ db_name }}' - - result.executed_commands == ["DROP DATABASE `{{ db_name }}`"] - -- name: run command to test state=absent for a database name (expect db_name not in stdout) - command: mysql "-e show databases like '{{ db_name }}';" - register: result - -- name: assert database does not exist - assert: { that: "'{{ db_name }}' not in result.stdout" } - -# ============================================================ -- name: test mysql_db encoding param not valid - issue 8075 - mysql_db: - name: datanotvalid - state: present - encoding: notvalid - login_unix_socket: '{{ mysql_socket }}' - register: result - ignore_errors: true - -- name: assert test mysql_db encoding param not valid - issue 8075 (failed=true) - assert: - that: - - "result.failed == true" - - "'Traceback' not in result.msg" - - "'Unknown character set' in result.msg" - -# ============================================================ -- name: test mysql_db using a valid encoding utf8 (expect changed=true) - mysql_db: - name: 'en{{ db_name }}' - state: present - encoding: utf8 - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message created a database - assert: - that: - - result is changed - - result.executed_commands == ["CREATE DATABASE `en{{ db_name }}` CHARACTER SET 'utf8'"] - -- name: test database was created - command: mysql "-e SHOW CREATE DATABASE en{{ db_name }};" - register: result - -- name: assert created database is of encoding utf8 - assert: { that: "'utf8' in result.stdout" } - -- name: remove database - mysql_db: - name: 'en{{ db_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - -# ============================================================ -- name: test mysql_db using valid encoding binary (expect changed=true) - mysql_db: - name: 'en{{ db_name }}' - state: present - encoding: binary - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message that database was created - assert: - that: - - result is changed - - result.executed_commands == ["CREATE DATABASE `en{{ db_name }}` CHARACTER SET 'binary'"] - -- name: run command to test database was created - command: mysql "-e SHOW CREATE DATABASE en{{ db_name }};" - register: result - -- name: assert created database is of encoding binary - assert: { that: "'binary' in result.stdout" } - -- name: remove database - mysql_db: - name: 'en{{ db_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - -# ============================================================ -- name: create user1 to access database dbuser1 - mysql_user: - name: user1 - password: 'Hfd6fds^dfA8Ga' - priv: '*.*:ALL' - state: present - login_unix_socket: '{{ mysql_socket }}' - -- name: create database dbuser1 using user1 - mysql_db: - name: '{{ db_user1 }}' - state: present - login_user: user1 - login_password: 'Hfd6fds^dfA8Ga' - register: result - -- name: assert output message that database was created - assert: { that: "result.changed == true" } - -- name: run command to test database was created using user1 - command: mysql "-e show databases like '{{ db_user1 }}';" - register: result - -- name: assert database exist - assert: { that: "'{{ db_user1 }}' in result.stdout" } - -# ============================================================ -- name: create user2 to access database with privilege select only - mysql_user: - name: user2 - password: 'kjsfd&F7safjad' - priv: '*.*:SELECT' - state: present - login_unix_socket: '{{ mysql_socket }}' - -- name: create database dbuser2 using user2 with no privilege to create (expect failed=true) - mysql_db: - name: '{{ db_user2 }}' - state: present - login_user: user2 - login_password: 'kjsfd&F7safjad' - register: result - ignore_errors: true - -- name: assert output message that database was not created using dbuser2 - assert: - that: - - "result.failed == true" - - "'Access denied' in result.msg" - -- name: run command to test that database was not created - command: mysql "-e show databases like '{{ db_user2 }}';" - register: result - -- name: assert database does not exist - assert: { that: "'{{ db_user2 }}' not in result.stdout" } - -# ============================================================ -- name: delete database using user2 with no privilege to delete (expect failed=true) - mysql_db: - name: '{{ db_user1 }}' - state: absent - login_user: user2 - login_password: 'kjsfd&F7safjad' - register: result - ignore_errors: true - -- name: assert output message that database was not deleted using dbuser2 - assert: - that: - - "result.failed == true" - - "'Access denied' in result.msg" - -- name: run command to test database was not deleted - command: mysql "-e show databases like '{{ db_user1 }}';" - register: result - -- name: assert database still exist - assert: { that: "'{{ db_user1 }}' in result.stdout" } - -# ============================================================ -- name: delete database using user1 with all privilege to delete a database (expect changed=true) - mysql_db: - name: '{{ db_user1 }}' - state: absent - login_user: user1 - login_password: 'Hfd6fds^dfA8Ga' - register: result - ignore_errors: true - -- name: assert output message that database was deleted using user1 - assert: - that: - - result is changed - - result.executed_commands == ["DROP DATABASE `{{ db_user1 }}`"] - -- name: run command to test database was deleted using user1 - command: mysql "-e show databases like '{{ db_name }}';" - register: result - -- name: assert database does not exist - assert: { that: "'{{ db_user1 }}' not in result.stdout" } - -# ============================================================ -- include: state_dump_import.yml format_type=sql file=dbdata.sql format_msg_type=ASCII file2=dump2.sql file3=dump3.sql file4=dump4.sql - -- include: state_dump_import.yml format_type=gz file=dbdata.gz format_msg_type=gzip file2=dump2.gz file3=dump3.gz file4=dump4.gz - -- include: state_dump_import.yml format_type=bz2 file=dbdata.bz2 format_msg_type=bzip2 file2=dump2.bz2 file3=dump3.bz2 file4=dump4.bz2 - -- include: multi_db_create_delete.yml - -- include: encoding_dump_import.yml file=latin1.sql format_msg_type=ASCII - -- include: config_overrides_defaults.yml - when: ansible_python.version_info[0] >= 3 diff --git a/tests/integration/targets/mysql_db/tasks/multi_db_create_delete.yml b/tests/integration/targets/mysql_db/tasks/multi_db_create_delete.yml deleted file mode 100644 index da8a94e819..0000000000 --- a/tests/integration/targets/mysql_db/tasks/multi_db_create_delete.yml +++ /dev/null @@ -1,557 +0,0 @@ -# Copyright (c) 2019, Pratik Gadiya -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- set_fact: - db1_name="database1" - db2_name="database2" - db3_name="database3" - db4_name="database4" - db5_name="database5" - dump1_file="/tmp/dump1_file.sql" - dump2_file="/tmp/all.sql" - -# ============================== CREATE TEST =============================== -# -# ========================================================================== -# Initial check - To confirm that database does not exist before executing check mode tasks -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases does not exist - assert: - that: - - "'{{ db1_name }}' not in mysql_result.stdout" - - "'{{ db2_name }}' not in mysql_result.stdout" - - "'{{ db3_name }}' not in mysql_result.stdout" - -# ========================================================================== -# Create multiple databases that does not exists (check mode) -- name: Create multiple databases that does not exists (check mode) - mysql_db: - name: - - '{{ db1_name }}' - - '{{ db2_name }}' - - '{{ db3_name }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: check_mode_result - check_mode: yes - -- name: assert successful completion of create database using check_mode since databases does not exist prior - assert: - that: - - check_mode_result.changed == true - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases does not exist (since created via check mode) - assert: - that: - - "'{{ db1_name }}' not in mysql_result.stdout" - - "'{{ db2_name }}' not in mysql_result.stdout" - - "'{{ db3_name }}' not in mysql_result.stdout" - -# ========================================================================== -# Create multiple databases -- name: Create multiple databases - mysql_db: - name: - - '{{ db1_name }}' - - '{{ db2_name }}' - - '{{ db3_name }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert successful completion of create database - assert: - that: - - result.changed == true - - result.db_list == ['{{ db1_name }}', '{{ db2_name }}', '{{ db3_name }}'] - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases exist after creation - assert: - that: - - "'{{ db1_name }}' in mysql_result.stdout" - - "'{{ db2_name }}' in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - -# ========================================================================= -# Recreate already existing databases (check mode) -- name: Recreate already existing databases (check mode) - mysql_db: - name: - - '{{ db1_name }}' - - '{{ db2_name }}' - - '{{ db3_name }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: check_mode_result - check_mode: yes - -- name: assert that recreation of existing databases does not make change (since recreated using check mode) - assert: - that: - - check_mode_result.changed == false - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases exist (since performed recreation of existing databases via check mode) - assert: - that: - - "'{{ db1_name }}' in mysql_result.stdout" - - "'{{ db2_name }}' in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - -# ========================================================================== -# Recreate same databases -- name: Recreate multiple databases - mysql_db: - name: - - '{{ db1_name }}' - - '{{ db2_name }}' - - '{{ db3_name }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert that recreation of existing databases does not make change - assert: - that: - - result.changed == false - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases does priorly exist - assert: - that: - - "'{{ db1_name }}' in mysql_result.stdout" - - "'{{ db2_name }}' in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - -# ========================================================================== -# Delete one of the databases (db2 here) -- name: Delete db2 database - mysql_db: - name: - - '{{ db2_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert successful completion of deleting database - assert: - that: - - result.changed == true - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that only db2 database does not exist - assert: - that: - - "'{{ db1_name }}' in mysql_result.stdout" - - "'{{ db2_name }}' not in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - -# ========================================================================= -# Recreate multiple databases in which few databases does not exists (check mode) -- name: Recreate multiple databases in which few databases does not exists (check mode) - mysql_db: - name: - - '{{ db1_name }}' - - '{{ db2_name }}' - - '{{ db3_name }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: check_mode_result - check_mode: yes - -- name: assert successful completion of recreation of partially existing database using check mode - assert: - that: - - check_mode_result.changed == true - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that recreated non existing databases does not exist (since created via check mode) - assert: - that: - - "'{{ db1_name }}' in mysql_result.stdout" - - "'{{ db2_name }}' not in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - -# ========================================================================== -# Create multiple databases -- name: Create multiple databases - mysql_db: - name: - - '{{ db1_name }}' - - '{{ db2_name }}' - - '{{ db3_name }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert successful completion of create database - assert: - that: - - result.changed == true - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases exist - assert: - that: - - "'{{ db1_name }}' in mysql_result.stdout" - - "'{{ db2_name }}' in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - -# ============================== DUMP TEST ================================= -# -# ========================================================================== -# Check that dump file does not exist -- name: Dump file does not exist - file: name={{ dump1_file }} state=absent - -# ========================================================================== -# Dump existing databases (check mode) -- name: Dump existing databases (check mode) - mysql_db: - name: - - '{{ db1_name }}' - - '{{ db3_name }}' - state: dump - target: '{{ dump1_file }}' - login_unix_socket: '{{ mysql_socket }}' - register: check_mode_dump_result - check_mode: yes - -- name: assert successful completion of dump operation using check mode - assert: - that: - - check_mode_dump_result.changed == true - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases exist (check mode) - assert: - that: - - "'{{ db1_name }}' in mysql_result.stdout" - - "'{{ db2_name }}' in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - -- name: state dump - file name should not exist (since dumped via check mode) - file: name={{ dump1_file }} state=absent - -# ========================================================================== -# Dump existing and non-existing databases (check mode) -- name: Dump existing and non-existing databases (check mode) - mysql_db: - name: - - "{{ db1_name }}" - - "{{ db4_name }}" - - "{{ db3_name }}" - state: dump - login_unix_socket: '{{ mysql_socket }}' - target: "{{ dump1_file }}" - register: check_mode_dump_result - ignore_errors: True - check_mode: yes - -- name: assert that dump operation of existing and non existing databases does not make change (using check mode) - assert: - that: - - "'Cannot dump database' in check_mode_dump_result['msg']" - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases exist (since check mode) - assert: - that: - - "'{{ db1_name }}' in mysql_result.stdout" - - "'{{ db2_name }}' in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - - "'{{ db4_name }}' not in mysql_result.stdout" - -- name: state dump - file name should not exist (since prior dump operation performed via check mode) - file: name={{ dump1_file }} state=absent - -# ========================================================================== -# Dump non-existing databases (check mode) -- name: Dump non-existing databases (check mode) - mysql_db: - name: - - "{{ db4_name }}" - - "{{ db5_name }}" - state: dump - target: "{{ dump1_file }}" - login_unix_socket: '{{ mysql_socket }}' - register: check_mode_dump_result - ignore_errors: True - check_mode: yes - -- name: assert successful completion of dump operation using check mode - assert: - that: - - "'Cannot dump database' in check_mode_dump_result['msg']" - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases exist (since delete via check mode) - assert: - that: - - "'{{ db1_name }}' in mysql_result.stdout" - - "'{{ db2_name }}' in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - - "'{{ db4_name }}' not in mysql_result.stdout" - - "'{{ db5_name }}' not in mysql_result.stdout" - -- name: state dump - file name should not exist (since prior dump operation performed via check mode) - file: name={{ dump1_file }} state=absent - -# ========================================================================== -# Dump existing databases -- name: Dump existing databases - mysql_db: - name: - - '{{ db1_name }}' - - '{{ db2_name }}' - - '{{ db3_name }}' - state: dump - target: '{{ dump1_file }}' - login_unix_socket: '{{ mysql_socket }}' - register: dump_result - -- name: assert successful completion of dump operation - assert: - that: - - dump_result.changed == true - - dump_result.db_list == ['{{ db1_name }}', '{{ db2_name }}', '{{ db3_name }}'] - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases exist - assert: - that: - - "'{{ db1_name }}' in mysql_result.stdout" - - "'{{ db2_name }}' in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - -- name: state dump - file name should exist - file: name={{ dump1_file }} state=file - -- name: Check if db1 database create command is present in the dumped file - shell: "grep -i 'CREATE DATABASE.*`{{ db1_name }}`' {{ dump1_file }}" - -- name: Check if db2 database create command is present in the dumped file - shell: "grep -i 'CREATE DATABASE.*`{{ db2_name }}`' {{ dump1_file }}" - -- name: Check if db3 database create command is present in the dumped file - shell: "grep -i 'CREATE DATABASE.*`{{ db3_name }}`' {{ dump1_file }}" - -# ========================================================================== -# Dump all databases - -- name: state dump - dump2 file name should not exist - file: name={{ dump2_file }} state=absent - -- name: Dump existing databases - mysql_db: - name: all - state: dump - target: '{{ dump2_file }}' - login_unix_socket: '{{ mysql_socket }}' - register: dump_result - -- name: assert successful completion of dump operation - assert: - that: - - dump_result.changed == true - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases exist - assert: - that: - - "'{{ db1_name }}' in mysql_result.stdout" - - "'{{ db2_name }}' in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - - "'{{ db4_name }}' not in mysql_result.stdout" - - "'{{ db5_name }}' not in mysql_result.stdout" - -- name: state dump - file name should exist - file: name={{ dump2_file }} state=file - -# ============================ DELETE TEST ================================= -# -# ========================================================================== -# Delete multiple databases which already exists (check mode) -- name: Delete multiple databases which already exists (check mode) - mysql_db: - name: - - '{{ db2_name }}' - - '{{ db3_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: check_mode_result - check_mode: yes - -- name: assert successful completion of delete databases which already exists using check mode - assert: - that: - - check_mode_result.changed == true - -- name: run command to test state=absent for a database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases exist even after deleting (since deleted via check mode) - assert: - that: - - "'{{ db2_name }}' in mysql_result.stdout" - - "'{{ db3_name }}' in mysql_result.stdout" - -# ========================================================================== -# Delete multiple databases -- name: Delete multiple databases - mysql_db: - name: - - '{{ db2_name }}' - - '{{ db3_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert successful completion of deleting database - assert: - that: - - result.changed == true - - result.db_list == ['{{ db2_name }}', '{{ db3_name }}'] - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases does not exist - assert: - that: - - "'{{ db2_name }}' not in mysql_result.stdout" - - "'{{ db3_name }}' not in mysql_result.stdout" - -# ========================================================================== -# Delete non existing databases (check mode) -- name: Delete non existing databases (check mode) - mysql_db: - name: - - '{{ db2_name }}' - - '{{ db4_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: check_mode_result - check_mode: yes - -- name: assert that deletion of non existing databases does not make change (using check mode) - assert: - that: - - check_mode_result.changed == false - -- name: run command to test state=absent for a database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases does not exist since were deleted priorly (check mode) - assert: - that: - - "'{{ db2_name }}' not in mysql_result.stdout" - - "'{{ db4_name }}' not in mysql_result.stdout" - -# ========================================================================== -# Delete already deleted databases -- name: Delete already deleted databases - mysql_db: - name: - - '{{ db2_name }}' - - '{{ db4_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert that deletion of non existing databases does not make change - assert: - that: - - result.changed == false - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that databases does not exists - assert: - that: - - "'{{ db2_name }}' not in mysql_result.stdout" - - "'{{ db4_name }}' not in mysql_result.stdout" - -# ========================================================================== -# Delete all databases -- name: Delete all databases - mysql_db: - name: - - '{{ db1_name }}' - - '{{ db2_name }}' - - '{{ db3_name }}' - - '{{ db4_name }}' - - '{{ db5_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert successful completion of deleting database - assert: - that: - - result.changed == true - -- name: run command to list databases like specified database name - command: mysql "-e show databases like 'database%';" - register: mysql_result - -- name: assert that specific databases does not exist - assert: - that: - - "'{{ db1_name }}' not in mysql_result.stdout" - - "'{{ db2_name }}' not in mysql_result.stdout" - - "'{{ db3_name }}' not in mysql_result.stdout" - - "'{{ db4_name }}' not in mysql_result.stdout" - - "'{{ db5_name }}' not in mysql_result.stdout" - -- name: state dump - dump 1 file name should be removed - file: name={{ dump1_file }} state=absent - -- name: state dump - dump 2 file name should be removed - file: name={{ dump2_file }} state=absent diff --git a/tests/integration/targets/mysql_db/tasks/state_dump_import.yml b/tests/integration/targets/mysql_db/tasks/state_dump_import.yml deleted file mode 100644 index a21b3f2fa2..0000000000 --- a/tests/integration/targets/mysql_db/tasks/state_dump_import.yml +++ /dev/null @@ -1,375 +0,0 @@ -# test code for state dump and import for mysql_db module -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ -- set_fact: - db_file_name="{{tmp_dir}}/{{file}}" - wrong_sql_file="{{tmp_dir}}/wrong.sql" - dump_file1="{{tmp_dir}}/{{file2}}" - dump_file2="{{tmp_dir}}/{{file3}}" - db_user="test" - db_user_unsafe_password="pass!word" - config_file="/root/.my.cnf" - -- name: create custom config file - shell: 'echo "[client]" > {{ config_file }}' - -- name: create user for test unsafe_login_password parameter - mysql_user: - name: '{{ db_user }}' - password: '{{ db_user_unsafe_password }}' - priv: '*.*:ALL' - state: present - login_unix_socket: '{{ mysql_socket }}' - -- name: state dump/import - create database - mysql_db: - name: '{{ db_name }}' - state: present - check_implicit_admin: yes - login_unix_socket: '{{ mysql_socket }}' - -- name: create database - mysql_db: - name: '{{ db_name2 }}' - state: present - check_implicit_admin: no - login_unix_socket: '{{ mysql_socket }}' - -- name: state dump/import - create table department - command: mysql {{ db_name }} '-e create table department(id int, name varchar(100));' - -- name: state dump/import - create table employee - command: mysql {{ db_name }} '-e create table employee(id int, name varchar(100));' - -- name: state dump/import - insert data into table employee - command: mysql {{ db_name }} "-e insert into employee value(47,'Joe Smith');" - -- name: state dump/import - insert data into table department - command: mysql {{ db_name }} "-e insert into department value(2,'Engineering');" - -- name: state dump/import - file name should not exist - file: name={{ db_file_name }} state=absent - -- name: database dump file1 should not exist - file: name={{ dump_file1 }} state=absent - -- name: database dump file2 should not exist - file: name={{ dump_file2 }} state=absent - -- name: state dump without department table. - mysql_db: - login_user: '{{ db_user }}' - login_password: '{{ db_user_unsafe_password }}' - unsafe_login_password: yes - name: "{{ db_name }}" - state: dump - target: "{{ db_file_name }}" - ignore_tables: - - "{{ db_name }}.department" - login_unix_socket: '{{ mysql_socket }}' - force: yes - master_data: 1 - skip_lock_tables: yes - dump_extra_args: --skip-triggers - config_file: '{{ config_file }}' - restrict_config_file: yes - check_implicit_admin: no - register: result - -- name: assert successful completion of dump operation - assert: - that: - - result is changed - - result.executed_commands[0] is search("mysqldump --defaults-file={{ config_file }} --user={{ db_user }} --password=\*\*\*\*\*\*\*\* --force --socket={{ mysql_socket }} {{ db_name }} --skip-lock-tables --quick --ignore-table={{ db_name }}.department --master-data=1 --skip-triggers") - -- name: state dump/import - file name should exist - file: name={{ db_file_name }} state=file - -- name: state dump with multiple databases in comma separated form. - mysql_db: - name: "{{ db_name }},{{ db_name2 }}" - state: dump - target: "{{ dump_file1 }}" - login_unix_socket: '{{ mysql_socket }}' - check_implicit_admin: yes - register: dump_result1 - -- name: assert successful completion of dump operation (with multiple databases in comma separated form) - assert: - that: - - dump_result1 is changed - - dump_result1.executed_commands[0] is search(" --user=root --password=''") - -- name: state dump - dump file1 should exist - file: name={{ dump_file1 }} state=file - -- name: state dump with multiple databases in list form via check_mode - mysql_db: - name: - - "{{ db_name }}" - - "{{ db_name2 }}" - state: dump - target: "{{ dump_file2 }}" - login_unix_socket: '{{ mysql_socket }}' - register: dump_result - check_mode: yes - -- name: assert successful completion of dump operation (with multiple databases in list form) via check mode - assert: - that: - - "dump_result.changed == true" - -- name: database dump file2 should not exist - stat: - path: "{{ dump_file2 }}" - register: stat_result - -- name: assert that check_mode does not create dump file for databases - assert: - that: - - stat_result.stat.exists is defined and not stat_result.stat.exists - -- name: state dump with multiple databases in list form. - mysql_db: - name: - - "{{ db_name }}" - - "{{ db_name2 }}" - state: dump - target: "{{ dump_file2 }}" - login_unix_socket: '{{ mysql_socket }}' - register: dump_result2 - -- name: assert successful completion of dump operation (with multiple databases in list form) - assert: - that: - - "dump_result2.changed == true" - -- name: state dump - dump file2 should exist - file: name={{ dump_file2 }} state=file - -- name: state dump/import - remove database - mysql_db: - name: '{{ db_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - -- name: remove database - mysql_db: - name: '{{ db_name2 }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - -- name: test state=import to restore the database of type {{ format_type }} (expect changed=true) - mysql_db: - login_user: '{{ db_user }}' - login_password: '{{ db_user_unsafe_password }}' - unsafe_login_password: yes - name: '{{ db_name }}' - state: import - target: '{{ db_file_name }}' - login_unix_socket: '{{ mysql_socket }}' - use_shell: yes - register: result - -- name: show the tables - command: mysql {{ db_name }} "-e show tables;" - register: result - -- name: assert that the department table is absent. - assert: - that: - - "'department' not in result.stdout" - -- name: test state=import to restore a database from multiple database dumped file1 - mysql_db: - name: '{{ db_name2 }}' - state: import - target: '{{ dump_file1 }}' - login_unix_socket: '{{ mysql_socket }}' - use_shell: no - register: import_result - -- name: assert output message restored a database from dump file1 - assert: { that: "import_result.changed == true" } - -- name: remove database - mysql_db: - name: '{{ db_name2 }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - -- name: run command to list databases - command: mysql "-e show databases like 'data%';" - register: mysql_result - -- name: assert that db_name2 database does not exist - assert: - that: - - "'{{ db_name2 }}' not in mysql_result.stdout" - -- name: test state=import to restore a database from dumped file2 (check mode) - mysql_db: - name: '{{ db_name2 }}' - state: import - target: '{{ dump_file2 }}' - login_unix_socket: '{{ mysql_socket }}' - register: check_import_result - check_mode: yes - -- name: assert output message restored a database from dump file2 (check mode) - assert: { that: "check_import_result.changed == true" } - -- name: run command to list databases - command: mysql "-e show databases like 'data%';" - register: mysql_result - -- name: assert that db_name2 database does not exist (check mode) - assert: - that: - - "'{{ db_name2 }}' not in mysql_result.stdout" - -- name: test state=import to restore a database from multiple database dumped file2 - mysql_db: - name: '{{ db_name2 }}' - state: import - target: '{{ dump_file2 }}' - login_unix_socket: '{{ mysql_socket }}' - register: import_result2 - -- name: assert output message restored a database from dump file2 - assert: - that: - - import_result2.changed == true - - import_result2.db_list == ['{{ db_name2 }}'] - -- name: run command to list databases - command: mysql "-e show databases like 'data%';" - register: mysql_result - -- name: assert that db_name2 database does exist after import - assert: - that: - - "'{{ db_name2 }}' in mysql_result.stdout" - -- name: test state=dump to backup the database of type {{ format_type }} (expect changed=true) - mysql_db: - name: '{{ db_name }}' - state: dump - target: '{{ db_file_name }}' - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message backup the database - assert: - that: - - "result.changed == true" - - "result.db =='{{ db_name }}'" - -- name: assert database was backed up successfully - command: file {{ db_file_name }} - register: result - -- name: assert file format type - assert: { that: "'{{format_msg_type}}' in result.stdout" } - -- name: update database table employee - command: mysql {{ db_name }} "-e update employee set name='John Doe' where id=47;" - -- name: test state=import to restore the database of type {{ format_type }} (expect changed=true) - mysql_db: - name: '{{ db_name }}' - state: import - target: '{{ db_file_name }}' - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message restore the database - assert: { that: "result.changed == true" } - -- name: select data from table employee - command: mysql {{ db_name }} "-e select * from employee;" - register: result - -- name: assert data in database is from the restore database - assert: - that: - - "'47' in result.stdout" - - "'Joe Smith' in result.stdout" - -########################## -# Test ``force`` parameter -########################## - -- name: create wrong sql file - shell: echo 'CREATE TABLE hello (id int); CREATE ELBAT ehlo (int id);' >> '{{ wrong_sql_file }}' - -- name: try to import without force parameter, must fail - mysql_db: - name: '{{ db_name }}' - state: import - target: '{{ wrong_sql_file }}' - login_unix_socket: '{{ mysql_socket }}' - force: no - register: result - ignore_errors: yes - -- assert: - that: - - result.failed == true - -- name: try to import with force parameter - mysql_db: - name: '{{ db_name }}' - state: import - target: '{{ wrong_sql_file }}' - login_unix_socket: '{{ mysql_socket }}' - force: yes - register: result - -- assert: - that: - - result is changed - -########## -# Clean up -########## - -- name: remove database name - mysql_db: - name: '{{ db_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - -- name: remove database - mysql_db: - name: '{{ db_name2 }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - -- name: remove file name - file: name={{ db_file_name }} state=absent - -- name: remove file name - file: name={{ wrong_sql_file }} state=absent - -- name: remove dump file1 - file: name={{ dump_file1 }} state=absent - -- name: remove dump file2 - file: name={{ dump_file2 }} state=absent diff --git a/tests/integration/targets/mysql_info/aliases b/tests/integration/targets/mysql_info/aliases deleted file mode 100644 index f37e6c6fb0..0000000000 --- a/tests/integration/targets/mysql_info/aliases +++ /dev/null @@ -1,6 +0,0 @@ -destructive -shippable/posix/group1 -skip/aix -skip/osx -skip/freebsd -skip/rhel diff --git a/tests/integration/targets/mysql_info/defaults/main.yml b/tests/integration/targets/mysql_info/defaults/main.yml deleted file mode 100644 index 6d44dbd377..0000000000 --- a/tests/integration/targets/mysql_info/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -# defaults file for test_mysql_info -db_name: data -user_name: alice -user_pass: alice diff --git a/tests/integration/targets/mysql_info/meta/main.yml b/tests/integration/targets/mysql_info/meta/main.yml deleted file mode 100644 index 1892924b21..0000000000 --- a/tests/integration/targets/mysql_info/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -dependencies: - - setup_mysql_db - - setup_remote_tmp_dir diff --git a/tests/integration/targets/mysql_info/tasks/main.yml b/tests/integration/targets/mysql_info/tasks/main.yml deleted file mode 100644 index f413447787..0000000000 --- a/tests/integration/targets/mysql_info/tasks/main.yml +++ /dev/null @@ -1,190 +0,0 @@ -# Test code for mysql_info module -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -################### -# Prepare for tests -# - -# Create role for tests -- name: mysql_info - create mysql user {{ user_name }} - mysql_user: - name: '{{ user_name }}' - password: '{{ user_pass }}' - state: present - priv: '*.*:ALL' - login_unix_socket: '{{ mysql_socket }}' - -# Create default MySQL config file with credentials -- name: mysql_info - create default config file - template: - src: my.cnf.j2 - dest: /root/.my.cnf - mode: '0400' - -# Create non-default MySQL config file with credentials -- name: mysql_info - create non-default config file - template: - src: my.cnf.j2 - dest: /root/non-default_my.cnf - mode: '0400' - -############### -# Do tests - -# Access by default cred file -- name: mysql_info - collect default cred file - mysql_info: - login_user: '{{ user_name }}' - register: result - -- assert: - that: - - result.changed == false - - result.version != {} - - result.settings != {} - - result.global_status != {} - - result.databases != {} - - result.engines != {} - - result.users != {} - -# Access by non-default cred file -- name: mysql_info - check non-default cred file - mysql_info: - login_user: '{{ user_name }}' - config_file: /root/non-default_my.cnf - register: result - -- assert: - that: - - result.changed == false - - result.version != {} - -# Remove cred files -- name: mysql_info - remove cred files - file: - path: '{{ item }}' - state: absent - with_items: - - /root/.my.cnf - - /root/non-default_my.cnf - -# Access with password -- name: mysql_info - check access with password - mysql_info: - login_user: '{{ user_name }}' - login_password: '{{ user_pass }}' - register: result - -- assert: - that: - - result.changed == false - - result.version != {} - -# Test excluding -- name: Collect all info except settings and users - mysql_info: - login_user: '{{ user_name }}' - login_password: '{{ user_pass }}' - filter: '!settings,!users' - register: result - -- assert: - that: - - result.changed == false - - result.version != {} - - result.global_status != {} - - result.databases != {} - - result.engines != {} - - result.settings is not defined - - result.users is not defined - -# Test including -- name: Collect info only about version and databases - mysql_info: - login_user: '{{ user_name }}' - login_password: '{{ user_pass }}' - filter: - - version - - databases - register: result - -- assert: - that: - - result.changed == false - - result.version != {} - - result.databases != {} - - result.engines is not defined - - result.settings is not defined - - result.global_status is not defined - - result.users is not defined - -# Test exclude_fields: db_size -# 'unsupported' element is passed to check that an unsupported value -# won't break anything (will be ignored regarding to the module's documentation). -- name: Collect info about databases excluding their sizes - mysql_info: - login_user: '{{ user_name }}' - login_password: '{{ user_pass }}' - filter: - - databases - exclude_fields: - - db_size - - unsupported - register: result - -- assert: - that: - - result.changed == false - - result.databases != {} - - result.databases.mysql == {} - -######################################################## -# Issue #65727, empty databases must be in returned dict -# -- name: Create empty database acme - mysql_db: - login_user: '{{ user_name }}' - login_password: '{{ user_pass }}' - name: acme - -- name: Collect info about databases - mysql_info: - login_user: '{{ user_name }}' - login_password: '{{ user_pass }}' - filter: - - databases - return_empty_dbs: true - register: result - -# Check acme is in returned dict -- assert: - that: - - result.changed == false - - result.databases.acme.size == 0 - - result.databases.mysql != {} - -- name: Collect info about databases excluding their sizes - mysql_info: - login_user: '{{ user_name }}' - login_password: '{{ user_pass }}' - filter: - - databases - exclude_fields: - - db_size - return_empty_dbs: true - register: result - -# Check acme is in returned dict -- assert: - that: - - result.changed == false - - result.databases.acme == {} - - result.databases.mysql == {} - -- name: Remove acme database - mysql_db: - login_user: '{{ user_name }}' - login_password: '{{ user_pass }}' - name: acme - state: absent diff --git a/tests/integration/targets/mysql_info/templates/my.cnf.j2 b/tests/integration/targets/mysql_info/templates/my.cnf.j2 deleted file mode 100644 index 467afa0746..0000000000 --- a/tests/integration/targets/mysql_info/templates/my.cnf.j2 +++ /dev/null @@ -1,3 +0,0 @@ -[client] -user={{ user_name }} -password={{ user_pass }} diff --git a/tests/integration/targets/mysql_query/aliases b/tests/integration/targets/mysql_query/aliases deleted file mode 100644 index c72bb40e18..0000000000 --- a/tests/integration/targets/mysql_query/aliases +++ /dev/null @@ -1,6 +0,0 @@ -destructive -shippable/posix/group3 -skip/aix -skip/osx -skip/freebsd -skip/rhel diff --git a/tests/integration/targets/mysql_query/defaults/main.yml b/tests/integration/targets/mysql_query/defaults/main.yml deleted file mode 100644 index 9fa44b650e..0000000000 --- a/tests/integration/targets/mysql_query/defaults/main.yml +++ /dev/null @@ -1,6 +0,0 @@ -root_user: root -db_name: data -test_db: testdb -test_table1: test1 -test_table2: test2 -test_script_path: /tmp/test.sql diff --git a/tests/integration/targets/mysql_query/meta/main.yml b/tests/integration/targets/mysql_query/meta/main.yml deleted file mode 100644 index 3b3414c6ca..0000000000 --- a/tests/integration/targets/mysql_query/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_mysql8 diff --git a/tests/integration/targets/mysql_query/tasks/main.yml b/tests/integration/targets/mysql_query/tasks/main.yml deleted file mode 100644 index 72ff4798a3..0000000000 --- a/tests/integration/targets/mysql_query/tasks/main.yml +++ /dev/null @@ -1,5 +0,0 @@ -# mysql_query module initial CI tests -- import_tasks: mysql_query_initial.yml - when: - - ansible_distribution == 'CentOS' - - ansible_distribution_major_version >= '7' diff --git a/tests/integration/targets/mysql_query/tasks/mysql_query_initial.yml b/tests/integration/targets/mysql_query/tasks/mysql_query_initial.yml deleted file mode 100644 index 4c3a99789e..0000000000 --- a/tests/integration/targets/mysql_query/tasks/mysql_query_initial.yml +++ /dev/null @@ -1,249 +0,0 @@ -# Test code for mysql_query module -# Copyright: (c) 2020, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -- vars: - mysql_parameters: &mysql_params - login_unix_socket: '{{ mysql_socket }}' - login_user: '{{ root_user }}' - login_password: '{{ root_pass }}' - - block: - - - name: Create db {{ test_db }} - mysql_query: - <<: *mysql_params - query: 'CREATE DATABASE {{ test_db }}' - register: result - - - assert: - that: - - result is changed - - result.executed_queries == ['CREATE DATABASE {{ test_db }}'] - - - name: Create {{ test_table1 }} - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'CREATE TABLE {{ test_table1 }} (id int)' - register: result - - - assert: - that: - - result is changed - - result.executed_queries == ['CREATE TABLE {{ test_table1 }} (id int)'] - - - name: Insert test data - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: - - 'INSERT INTO {{ test_table1 }} VALUES (1), (2)' - - 'INSERT INTO {{ test_table1 }} VALUES (3)' - single_transaction: yes - register: result - - - assert: - that: - - result is changed - - result.rowcount == [2, 1] - - result.executed_queries == ['INSERT INTO {{ test_table1 }} VALUES (1), (2)', 'INSERT INTO {{ test_table1 }} VALUES (3)'] - - - name: Check data in {{ test_table1 }} - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'SELECT * FROM {{ test_table1 }}' - register: result - - - assert: - that: - - result is not changed - - result.executed_queries == ['SELECT * FROM {{ test_table1 }}'] - - result.rowcount == [3] - - result.query_result[0][0].id == 1 - - result.query_result[0][1].id == 2 - - result.query_result[0][2].id == 3 - - - name: Check data in {{ test_table1 }} using positional args - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'SELECT * FROM {{ test_table1 }} WHERE id = %s' - positional_args: - - 1 - register: result - - - assert: - that: - - result is not changed - - result.executed_queries == ["SELECT * FROM {{ test_table1 }} WHERE id = 1"] - - result.rowcount == [1] - - result.query_result[0][0].id == 1 - - - name: Check data in {{ test_table1 }} using named args - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'SELECT * FROM {{ test_table1 }} WHERE id = %(some_id)s' - named_args: - some_id: 1 - register: result - - - assert: - that: - - result is not changed - - result.executed_queries == ["SELECT * FROM {{ test_table1 }} WHERE id = 1"] - - result.rowcount == [1] - - result.query_result[0][0].id == 1 - - - name: Update data in {{ test_table1 }} - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'UPDATE {{ test_table1 }} SET id = %(new_id)s WHERE id = %(current_id)s' - named_args: - current_id: 1 - new_id: 0 - register: result - - - assert: - that: - - result is changed - - result.executed_queries == ['UPDATE {{ test_table1 }} SET id = 0 WHERE id = 1'] - - result.rowcount == [1] - - - name: Check the prev update - row with value 1 does not exist anymore - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'SELECT * FROM {{ test_table1 }} WHERE id = %(some_id)s' - named_args: - some_id: 1 - register: result - - - assert: - that: - - result is not changed - - result.executed_queries == ['SELECT * FROM {{ test_table1 }} WHERE id = 1'] - - result.rowcount == [0] - - - name: Check the prev update - row with value - exist - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'SELECT * FROM {{ test_table1 }} WHERE id = %(some_id)s' - named_args: - some_id: 0 - register: result - - - assert: - that: - - result is not changed - - result.executed_queries == ['SELECT * FROM {{ test_table1 }} WHERE id = 0'] - - result.rowcount == [1] - - - name: Update data in {{ test_table1 }} again - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'UPDATE {{ test_table1 }} SET id = %(new_id)s WHERE id = %(current_id)s' - named_args: - current_id: 1 - new_id: 0 - register: result - - - assert: - that: - - result is not changed - - result.executed_queries == ['UPDATE {{ test_table1 }} SET id = 0 WHERE id = 1'] - - result.rowcount == [0] - - - name: Delete data from {{ test_table1 }} - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: - - 'DELETE FROM {{ test_table1 }} WHERE id = 0' - - 'SELECT * FROM {{ test_table1 }} WHERE id = 0' - register: result - - - assert: - that: - - result is changed - - result.executed_queries == ['DELETE FROM {{ test_table1 }} WHERE id = 0', 'SELECT * FROM {{ test_table1 }} WHERE id = 0'] - - result.rowcount == [1, 0] - - - name: Delete data from {{ test_table1 }} again - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'DELETE FROM {{ test_table1 }} WHERE id = 0' - register: result - - - assert: - that: - - result is not changed - - result.executed_queries == ['DELETE FROM {{ test_table1 }} WHERE id = 0'] - - result.rowcount == [0] - - - name: Truncate {{ test_table1 }} - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: - - 'TRUNCATE {{ test_table1 }}' - - 'SELECT * FROM {{ test_table1 }}' - register: result - - - assert: - that: - - result is changed - - result.executed_queries == ['TRUNCATE {{ test_table1 }}', 'SELECT * FROM {{ test_table1 }}'] - - result.rowcount == [0, 0] - - - name: Rename {{ test_table1 }} - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'RENAME TABLE {{ test_table1 }} TO {{ test_table2 }}' - register: result - - - assert: - that: - - result is changed - - result.executed_queries == ['RENAME TABLE {{ test_table1 }} TO {{ test_table2 }}'] - - result.rowcount == [0] - - - name: Check the prev rename - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'SELECT * FROM {{ test_table1 }}' - register: result - ignore_errors: yes - - - assert: - that: - - result.failed == true - - - name: Check the prev rename - mysql_query: - <<: *mysql_params - login_db: '{{ test_db }}' - query: 'SELECT * FROM {{ test_table2 }}' - register: result - - - assert: - that: - - result.rowcount == [0] - - - name: Drop db {{ test_db }} - mysql_query: - <<: *mysql_params - query: 'DROP DATABASE {{ test_db }}' - register: result - - - assert: - that: - - result is changed - - result.executed_queries == ['DROP DATABASE {{ test_db }}'] diff --git a/tests/integration/targets/mysql_replication/aliases b/tests/integration/targets/mysql_replication/aliases deleted file mode 100644 index fca5c0258a..0000000000 --- a/tests/integration/targets/mysql_replication/aliases +++ /dev/null @@ -1,8 +0,0 @@ -destructive -shippable/posix/group4 -# Make sure that this test runs in a different group than mariadb_replication! -skip/aix -skip/osx -skip/freebsd -skip/rhel -needs/root diff --git a/tests/integration/targets/mysql_replication/defaults/main.yml b/tests/integration/targets/mysql_replication/defaults/main.yml deleted file mode 100644 index b22578600d..0000000000 --- a/tests/integration/targets/mysql_replication/defaults/main.yml +++ /dev/null @@ -1,9 +0,0 @@ -master_port: 3306 -standby_port: 3307 -test_db: test_db -test_table: test_table -test_master_delay: 60 -replication_user: replication_user -replication_pass: replication_pass -dump_path: /tmp/dump.sql -test_channel: test_channel-1 diff --git a/tests/integration/targets/mysql_replication/meta/main.yml b/tests/integration/targets/mysql_replication/meta/main.yml deleted file mode 100644 index 73c6abad84..0000000000 --- a/tests/integration/targets/mysql_replication/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -dependencies: -- setup_mysql_replication diff --git a/tests/integration/targets/mysql_replication/tasks/main.yml b/tests/integration/targets/mysql_replication/tasks/main.yml deleted file mode 100644 index 6538d89ad2..0000000000 --- a/tests/integration/targets/mysql_replication/tasks/main.yml +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Initial CI tests of mysql_replication module: -- import_tasks: mysql_replication_initial.yml - when: - - ansible_facts.distribution == 'CentOS' - - ansible_facts.distribution_major_version is version('7', '==') - -# Tests of master_delay parameter: -- import_tasks: mysql_replication_master_delay.yml - when: - - ansible_facts.distribution == 'CentOS' - - ansible_facts.distribution_major_version is version('7', '==') - -# Tests of channel parameter: -- import_tasks: mysql_replication_channel.yml - when: - - ansible_facts.distribution == 'CentOS' - - ansible_facts.distribution_major_version is version('7', '==') - -# Tests of resetmaster mode: -- import_tasks: mysql_replication_resetmaster_mode.yml - when: - - ansible_facts.distribution == 'CentOS' - - ansible_facts.distribution_major_version is version('7', '==') diff --git a/tests/integration/targets/mysql_replication/tasks/mysql_replication_channel.yml b/tests/integration/targets/mysql_replication/tasks/mysql_replication_channel.yml deleted file mode 100644 index aeab2b6d00..0000000000 --- a/tests/integration/targets/mysql_replication/tasks/mysql_replication_channel.yml +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Needs for further tests: -- name: Stop slave - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: stopslave - -- name: Reset slave all - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: resetslaveall - -# Get master log file and log pos: -- name: Get master status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ master_port }}" - mode: getmaster - register: master_status - -# Test changemaster mode: -- name: Run replication with channel - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: changemaster - master_host: 127.0.0.1 - master_port: "{{ master_port }}" - master_user: "{{ replication_user }}" - master_password: "{{ replication_pass }}" - master_log_file: "{{ master_status.File }}" - master_log_pos: "{{ master_status.Position }}" - channel: "{{ test_channel }}" - register: result - -- assert: - that: - - result is changed - - result.queries == ["CHANGE MASTER TO MASTER_HOST='127.0.0.1',MASTER_USER='replication_user',MASTER_PASSWORD='********',MASTER_PORT=3306,MASTER_LOG_FILE='{{ master_status.File }}',MASTER_LOG_POS={{ master_status.Position }} FOR CHANNEL '{{ test_channel }}'"] - -# Test startslave mode: -- name: Start slave with channel - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: startslave - channel: '{{ test_channel }}' - register: result - -- assert: - that: - - result is changed - - result.queries == ["START SLAVE FOR CHANNEL '{{ test_channel }}'"] - -# Test getslave mode: -- name: Get standby status with channel - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: getslave - channel: '{{ test_channel }}' - register: slave_status - -- assert: - that: - - slave_status.Is_Slave == true - - slave_status.Master_Host == '127.0.0.1' - - slave_status.Exec_Master_Log_Pos == master_status.Position - - slave_status.Master_Port == {{ master_port }} - - slave_status.Last_IO_Errno == 0 - - slave_status.Last_IO_Error == '' - - slave_status.Channel_Name == '{{ test_channel }}' - - slave_status is not changed - -# Test stopslave mode: -- name: Stop slave with channel - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: stopslave - channel: '{{ test_channel }}' - register: result - -- assert: - that: - - result is changed - - result.queries == ["STOP SLAVE FOR CHANNEL '{{ test_channel }}'"] - -# Test reset -- name: Reset slave with channel - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: resetslave - channel: '{{ test_channel }}' - register: result - -- assert: - that: - - result is changed - - result.queries == ["RESET SLAVE FOR CHANNEL '{{ test_channel }}'"] - -# Test reset all -- name: Reset slave all with channel - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: resetslaveall - channel: '{{ test_channel }}' - register: result - -- assert: - that: - - result is changed - - result.queries == ["RESET SLAVE ALL FOR CHANNEL '{{ test_channel }}'"] diff --git a/tests/integration/targets/mysql_replication/tasks/mysql_replication_initial.yml b/tests/integration/targets/mysql_replication/tasks/mysql_replication_initial.yml deleted file mode 100644 index f0c8f1e7bb..0000000000 --- a/tests/integration/targets/mysql_replication/tasks/mysql_replication_initial.yml +++ /dev/null @@ -1,191 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Preparation: -- name: Create user for replication - shell: "echo \"GRANT REPLICATION SLAVE ON *.* TO '{{ replication_user }}'@'localhost' IDENTIFIED BY '{{ replication_pass }}'; FLUSH PRIVILEGES;\" | mysql -P {{ master_port }} -h 127.0.0.1" - -- name: Create test database - mysql_db: - login_host: 127.0.0.1 - login_port: '{{ master_port }}' - state: present - name: '{{ test_db }}' - -- name: Dump all databases from the master - shell: 'mysqldump -P {{ master_port }} -h 127.0.0.1 --all-databases --master-data=2 > {{ dump_path }}' - -- name: Restore the dump to the standby - shell: 'mysql -P {{ standby_port }} -h 127.0.0.1 < {{ dump_path }}' - -# Test getmaster mode: -- name: Get master status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ master_port }}" - mode: getmaster - register: master_status - -- assert: - that: - - master_status.Is_Master == true - - master_status.Position != 0 - - master_status is not changed - -# Test startslave fails without changemaster first. This needs fail_on_error -- name: Start slave and fail because master is not specified; failing on error as requested - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: startslave - fail_on_error: yes - register: result - ignore_errors: yes - -- assert: - that: - - result is failed - -# Test startslave doesn't fail if fail_on_error: no -- name: Start slave and fail without propagating it to ansible as we were asked not to - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: startslave - fail_on_error: no - register: result - -- assert: - that: - - result is not failed - -# Test startslave doesn't fail if there is no fail_on_error. -# This is suboptimal because nothing happens, but it's the old behavior. -- name: Start slave and fail without propagating it to ansible as previous versions did not fail on error - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: startslave - register: result - -- assert: - that: - - result is not failed - -# Test changemaster mode: -# master_ssl_ca will be set as '' to check the module's behaviour for #23976, -# must be converted to an empty string -- name: Run replication - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: changemaster - master_host: 127.0.0.1 - master_port: "{{ master_port }}" - master_user: "{{ replication_user }}" - master_password: "{{ replication_pass }}" - master_log_file: "{{ master_status.File }}" - master_log_pos: "{{ master_status.Position }}" - master_ssl_ca: '' - register: result - -- assert: - that: - - result is changed - - result.queries == ["CHANGE MASTER TO MASTER_HOST='127.0.0.1',MASTER_USER='replication_user',MASTER_PASSWORD='********',MASTER_PORT=3306,MASTER_LOG_FILE='{{ master_status.File }}',MASTER_LOG_POS={{ master_status.Position }},MASTER_SSL_CA=''"] - -# Test startslave mode: -- name: Start slave - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: startslave - register: result - -- assert: - that: - - result is changed - - result.queries == ["START SLAVE"] - -# Test getslave mode: -- name: Get standby status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: getslave - register: slave_status - -- assert: - that: - - slave_status.Is_Slave == true - - slave_status.Master_Host == '127.0.0.1' - - slave_status.Exec_Master_Log_Pos == master_status.Position - - slave_status.Master_Port == {{ master_port }} - - slave_status.Last_IO_Errno == 0 - - slave_status.Last_IO_Error == '' - - slave_status is not changed - -# Create test table and add data to it: -- name: Create test table - shell: "echo \"CREATE TABLE {{ test_table }} (id int);\" | mysql -P {{ master_port }} -h 127.0.0.1 {{ test_db }}" - -- name: Insert data - shell: > - echo "INSERT INTO {{ test_table }} (id) VALUES (1), (2), (3); FLUSH LOGS;" | - mysql -P {{ master_port }} -h 127.0.0.1 {{ test_db }} - -- name: Small pause to be sure the bin log, which was flushed previously, reached the slave - pause: - seconds: 2 - -# Test master log pos has been changed: -- name: Get standby status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: getslave - register: slave_status - -# master_status.Position is not actual and it has been changed by the prev step, -# so slave_status.Exec_Master_Log_Pos must be different: -- assert: - that: - - slave_status.Exec_Master_Log_Pos != master_status.Position - -- name: Start slave that is already running - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: startslave - fail_on_error: true - register: result - -- assert: - that: - - result is not changed - -# Test stopslave mode: -- name: Stop slave - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: stopslave - register: result - -- assert: - that: - - result is changed - - result.queries == ["STOP SLAVE"] - -# Test stopslave mode: -- name: Stop slave that is no longer running - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: stopslave - fail_on_error: true - register: result - -- assert: - that: - - result is not changed diff --git a/tests/integration/targets/mysql_replication/tasks/mysql_replication_master_delay.yml b/tests/integration/targets/mysql_replication/tasks/mysql_replication_master_delay.yml deleted file mode 100644 index c6b329283c..0000000000 --- a/tests/integration/targets/mysql_replication/tasks/mysql_replication_master_delay.yml +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Test master_delay mode: -- name: Run replication - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: changemaster - master_delay: '{{ test_master_delay }}' - register: result - -- assert: - that: - - result is changed - - result.queries == ["CHANGE MASTER TO MASTER_DELAY=60"] - -# Auxiliary step: -- name: Start slave - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: startslave - register: result - -# Check master_delay: -- name: Get standby status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: getslave - register: slave_status - -- assert: - that: - - slave_status.SQL_Delay == {{ test_master_delay }} - - slave_status is not changed - -# Stop standby for further tests: -- name: Stop slave - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: stopslave diff --git a/tests/integration/targets/mysql_replication/tasks/mysql_replication_resetmaster_mode.yml b/tests/integration/targets/mysql_replication/tasks/mysql_replication_resetmaster_mode.yml deleted file mode 100644 index 19ea4ab4d3..0000000000 --- a/tests/integration/targets/mysql_replication/tasks/mysql_replication_resetmaster_mode.yml +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Needs for further tests: -- name: Stop slave - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: stopslave - -- name: Reset slave all - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ standby_port }}" - mode: resetslaveall - -# Get master initial status: -- name: Get master status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ master_port }}" - mode: getmaster - register: master_initial_status - -# Test resetmaster mode: -- name: Reset master - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ master_port }}" - mode: resetmaster - register: result - -- assert: - that: - - result is changed - - result.queries == ["RESET MASTER"] - -# Get master final status: -- name: Get master status - mysql_replication: - login_host: 127.0.0.1 - login_port: "{{ master_port }}" - mode: getmaster - register: master_final_status - -- assert: - that: - - master_initial_status.File != master_final_status.File diff --git a/tests/integration/targets/mysql_user/aliases b/tests/integration/targets/mysql_user/aliases deleted file mode 100644 index e93cd86b56..0000000000 --- a/tests/integration/targets/mysql_user/aliases +++ /dev/null @@ -1,5 +0,0 @@ -destructive -shippable/posix/group1 -skip/aix -skip/osx -skip/freebsd diff --git a/tests/integration/targets/mysql_user/defaults/main.yml b/tests/integration/targets/mysql_user/defaults/main.yml deleted file mode 100644 index 7522aba14f..0000000000 --- a/tests/integration/targets/mysql_user/defaults/main.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -# defaults file for test_mysql_user -db_name: 'data' -user_name_1: 'db_user1' -user_name_2: 'db_user2' -user_name_3: 'db_user3' - -user_password_1: 'gadfFDSdtTU^Sdfuj' -user_password_2: 'jkFKUdfhdso78yi&td' -user_password_3: 'jkFKUdfhdso78yi&tk' - -root_password: 'zevuR6oPh7' - -db_names: - - clientdb - - employeedb - - providerdb - -tmp_dir: '/tmp' diff --git a/tests/integration/targets/mysql_user/files/create-function.sql b/tests/integration/targets/mysql_user/files/create-function.sql deleted file mode 100644 index dda7bd7fbf..0000000000 --- a/tests/integration/targets/mysql_user/files/create-function.sql +++ /dev/null @@ -1,8 +0,0 @@ -USE foo; -DELIMITER ;; -CREATE FUNCTION `function` () RETURNS tinyint(4) -BEGIN - DECLARE NAME_FOUND tinyint DEFAULT 0; - RETURN NAME_FOUND; -END;; -DELIMITER ; diff --git a/tests/integration/targets/mysql_user/files/create-procedure.sql b/tests/integration/targets/mysql_user/files/create-procedure.sql deleted file mode 100644 index d0d45aa4c3..0000000000 --- a/tests/integration/targets/mysql_user/files/create-procedure.sql +++ /dev/null @@ -1,5 +0,0 @@ -USE bar; -DELIMITER ;; -CREATE PROCEDURE `procedure` () -SELECT * FROM bar;; -DELIMITER ; diff --git a/tests/integration/targets/mysql_user/meta/main.yml b/tests/integration/targets/mysql_user/meta/main.yml deleted file mode 100644 index 1892924b21..0000000000 --- a/tests/integration/targets/mysql_user/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -dependencies: - - setup_mysql_db - - setup_remote_tmp_dir diff --git a/tests/integration/targets/mysql_user/tasks/assert_no_user.yml b/tests/integration/targets/mysql_user/tasks/assert_no_user.yml deleted file mode 100644 index 0031a6887b..0000000000 --- a/tests/integration/targets/mysql_user/tasks/assert_no_user.yml +++ /dev/null @@ -1,25 +0,0 @@ -# test code to assert no mysql user -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ -- name: run command to query for mysql user - command: mysql "-e SELECT User FROM mysql.user where user='{{ user_name }}';" - register: result - -- name: assert mysql user is not present - assert: { that: "'{{ user_name }}' not in result.stdout" } diff --git a/tests/integration/targets/mysql_user/tasks/assert_user.yml b/tests/integration/targets/mysql_user/tasks/assert_user.yml deleted file mode 100644 index 9ac7cbff13..0000000000 --- a/tests/integration/targets/mysql_user/tasks/assert_user.yml +++ /dev/null @@ -1,34 +0,0 @@ -# test code to assert mysql user -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ -- name: run command to query for mysql user - command: mysql "-e SELECT User FROM mysql.user where user='{{ user_name }}';" - register: result - -- name: assert mysql user is present - assert: { that: "'{{ user_name }}' in result.stdout" } - -- name: run command to show privileges for user (expect privileges in stdout) - command: mysql "-e SHOW GRANTS FOR '{{ user_name }}'@'localhost';" - register: result - when: priv is defined - -- name: assert user has giving privileges - assert: { that: "'GRANT {{priv}} ON *.*' in result.stdout" } - when: priv is defined diff --git a/tests/integration/targets/mysql_user/tasks/create_user.yml b/tests/integration/targets/mysql_user/tasks/create_user.yml deleted file mode 100644 index 15f1eb9dbd..0000000000 --- a/tests/integration/targets/mysql_user/tasks/create_user.yml +++ /dev/null @@ -1,29 +0,0 @@ -# test code to create mysql user -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ -- name: create mysql user {{user_name}} - mysql_user: - name: '{{user_name}}' - password: '{{user_password}}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message mysql user was created - assert: { that: "result.changed == true" } diff --git a/tests/integration/targets/mysql_user/tasks/issue-29511.yaml b/tests/integration/targets/mysql_user/tasks/issue-29511.yaml deleted file mode 100644 index fa5d8eddc4..0000000000 --- a/tests/integration/targets/mysql_user/tasks/issue-29511.yaml +++ /dev/null @@ -1,78 +0,0 @@ ---- - -- name: Issue test setup - drop database - mysql_db: - name: "{{ item }}" - state: absent - login_unix_socket: '{{ mysql_socket }}' - loop: - - foo - - bar - -- name: Issue test setup - create database - mysql_db: - name: "{{ item }}" - state: present - login_unix_socket: '{{ mysql_socket }}' - loop: - - foo - - bar - -- name: Copy SQL scripts to remote - copy: - src: "{{ item }}" - dest: "{{ remote_tmp_dir }}/{{ item | basename }}" - with_items: - - create-function.sql - - create-procedure.sql - -- name: Create function for test - shell: "mysql < {{ remote_tmp_dir }}/create-function.sql" - -- name: Create procedure for test - shell: "mysql < {{ remote_tmp_dir }}/create-procedure.sql" - -- name: Create user with FUNCTION and PROCEDURE privileges - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - state: present - priv: 'FUNCTION foo.function:EXECUTE/foo.*:SELECT/PROCEDURE bar.procedure:EXECUTE' - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: Assert Create user with FUNCTION and PROCEDURE privileges - assert: - that: - - result is success - - result is changed - -- name: Create user with FUNCTION and PROCEDURE privileges - Idempotent check - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - state: present - priv: 'FUNCTION foo.function:EXECUTE/foo.*:SELECT/PROCEDURE bar.procedure:EXECUTE' - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: Assert Create user with FUNCTION and PROCEDURE privileges - assert: - that: - - result is success - - result is not changed - -- name: Remove user - mysql_user: - name: '{{ user_name_2 }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - -- name: Issue test teardown - cleanup databases - mysql_db: - name: "{{ item }}" - state: absent - login_unix_socket: '{{ mysql_socket }}' - loop: - - foo - - bar diff --git a/tests/integration/targets/mysql_user/tasks/issue-64560.yaml b/tests/integration/targets/mysql_user/tasks/issue-64560.yaml deleted file mode 100644 index 3851d859ed..0000000000 --- a/tests/integration/targets/mysql_user/tasks/issue-64560.yaml +++ /dev/null @@ -1,27 +0,0 @@ ---- - -- name: Set root password - mysql_user: - name: root - password: '{{ root_password }}' - login_user: root - login_password: '{{ root_password }}' - check_implicit_admin: yes - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert root password is changed - assert: { that: "result.changed == true" } - -- name: Set root password again - mysql_user: - name: root - password: '{{ root_password }}' - login_user: root - login_password: '{{ root_password }}' - check_implicit_admin: yes - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: Assert root password is not changed - assert: { that: "result.changed == false" } diff --git a/tests/integration/targets/mysql_user/tasks/main.yml b/tests/integration/targets/mysql_user/tasks/main.yml deleted file mode 100644 index 9bc78a64cc..0000000000 --- a/tests/integration/targets/mysql_user/tasks/main.yml +++ /dev/null @@ -1,222 +0,0 @@ -# test code for the mysql_user module -# (c) 2014, Wayne Rosario - -# 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 dof 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 . - -# ============================================================ -# create mysql user and verify user is added to mysql database -# -- include: create_user.yml user_name={{user_name_1}} user_password={{ user_password_1 }} - -- include: resource_limits.yml - -- include: assert_user.yml user_name={{user_name_1}} - -- include: remove_user.yml user_name={{user_name_1}} user_password={{ user_password_1 }} - -- include: assert_no_user.yml user_name={{user_name_1}} - -# ============================================================ -# Create mysql user that already exist on mysql database -# -- include: create_user.yml user_name={{user_name_1}} user_password={{ user_password_1 }} - -- name: create mysql user that already exist (expect changed=false) - mysql_user: - name: '{{user_name_1}}' - password: '{{user_password_1}}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message mysql user was not created - assert: { that: "result.changed == false" } - -# ============================================================ -# remove mysql user and verify user is removed from mysql database -# -- name: remove mysql user state=absent (expect changed=true) - mysql_user: - name: '{{ user_name_1 }}' - password: '{{ user_password_1 }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message mysql user was removed - assert: { that: "result.changed == true" } - -- include: assert_no_user.yml user_name={{user_name_1}} - -# ============================================================ -# remove mysql user that does not exist on mysql database -# -- name: remove mysql user that does not exist state=absent (expect changed=false) - mysql_user: - name: '{{ user_name_1 }}' - password: '{{ user_password_1 }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message mysql user that does not exist - assert: { that: "result.changed == false" } - -- include: assert_no_user.yml user_name={{user_name_1}} - -# ============================================================ -# Create user with no privileges and verify default privileges are assign -# -- name: create user with select privilege state=present (expect changed=true) - mysql_user: - name: '{{ user_name_1 }}' - password: '{{ user_password_1 }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- include: assert_user.yml user_name={{user_name_1}} priv=USAGE - -- include: remove_user.yml user_name={{user_name_1}} user_password={{ user_password_1 }} - -- include: assert_no_user.yml user_name={{user_name_1}} - -# ============================================================ -# Create user with select privileges and verify select privileges are assign -# -- name: create user with select privilege state=present (expect changed=true) - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - state: present - priv: '*.*:SELECT' - login_unix_socket: '{{ mysql_socket }}' - register: result - -- include: assert_user.yml user_name={{user_name_2}} priv=SELECT - -- include: remove_user.yml user_name={{user_name_2}} user_password={{ user_password_2 }} - -- include: assert_no_user.yml user_name={{user_name_2}} - -# ============================================================ -# Assert user has access to multiple databases -# -- name: give users access to multiple databases - mysql_user: - name: '{{ item[0] }}' - priv: '{{ item[1] }}.*:ALL' - append_privs: yes - password: '{{ user_password_1 }}' - login_unix_socket: '{{ mysql_socket }}' - with_nested: - - [ '{{ user_name_1 }}', '{{ user_name_2 }}'] - - "{{db_names}}" - -- name: show grants access for user1 on multiple database - command: mysql "-e SHOW GRANTS FOR '{{ user_name_1 }}'@'localhost';" - register: result - -- name: assert grant access for user1 on multiple database - assert: { that: "'{{ item }}' in result.stdout" } - with_items: "{{db_names}}" - -- name: show grants access for user2 on multiple database - command: mysql "-e SHOW GRANTS FOR '{{ user_name_2 }}'@'localhost';" - register: result - -- name: assert grant access for user2 on multiple database - assert: { that: "'{{ item }}' in result.stdout" } - with_items: "{{db_names}}" - -- include: remove_user.yml user_name={{user_name_1}} user_password={{ user_password_1 }} - -- include: remove_user.yml user_name={{user_name_2}} user_password={{ user_password_1 }} - -- name: give user access to database via wildcard - mysql_user: - name: '{{ user_name_1 }}' - priv: '%db.*:SELECT' - append_privs: yes - password: '{{ user_password_1 }}' - login_unix_socket: '{{ mysql_socket }}' - -- name: show grants access for user1 on multiple database - command: mysql "-e SHOW GRANTS FOR '{{ user_name_1 }}'@'localhost';" - register: result - -- name: assert grant access for user1 on multiple database - assert: - that: - - "'%db' in result.stdout" - - "'SELECT' in result.stdout" - -- name: change user access to database via wildcard - mysql_user: - name: '{{ user_name_1 }}' - priv: '%db.*:INSERT' - append_privs: yes - password: '{{ user_password_1 }}' - login_unix_socket: '{{ mysql_socket }}' - -- name: show grants access for user1 on multiple database - command: mysql "-e SHOW GRANTS FOR '{{ user_name_1 }}'@'localhost';" - register: result - -- name: assert grant access for user1 on multiple database - assert: - that: - - "'%db' in result.stdout" - - "'INSERT' in result.stdout" - -- include: remove_user.yml user_name={{user_name_1}} user_password={{ user_password_1 }} - -# ============================================================ -# Update user password for a user. -# Assert the user password is updated and old password can no longer be used. -# -#- include: user_password_update_test.yml - -# ============================================================ -# Assert create user with SELECT privileges, attempt to create database and update privileges to create database -# -- include: test_privs.yml current_privilege=SELECT current_append_privs=no - -# ============================================================ -# Assert creating user with SELECT privileges, attempt to create database and append privileges to create database -# -- include: test_privs.yml current_privilege=DROP current_append_privs=yes - -# ============================================================ -# Assert create user with SELECT privileges, attempt to create database and update privileges to create database -# -- include: test_privs.yml current_privilege='UPDATE,ALTER' current_append_privs=no - -# ============================================================ -# Assert creating user with SELECT privileges, attempt to create database and append privileges to create database -# -- include: test_privs.yml current_privilege='INSERT,DELETE' current_append_privs=yes - -# Tests for the priv parameter with dict value (https://github.com/ansible/ansible/issues/57533) -- include: test_priv_dict.yml - -- import_tasks: issue-29511.yaml - tags: - - issue-29511 - -- import_tasks: issue-64560.yaml - tags: - - issue-64560 diff --git a/tests/integration/targets/mysql_user/tasks/remove_user.yml b/tests/integration/targets/mysql_user/tasks/remove_user.yml deleted file mode 100644 index 9546760e17..0000000000 --- a/tests/integration/targets/mysql_user/tasks/remove_user.yml +++ /dev/null @@ -1,59 +0,0 @@ -# test code to remove mysql user -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ -- name: remove mysql user {{user_name}} - mysql_user: - name: '{{user_name}}' - password: '{{user_password}}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message mysql user was removed - assert: { that: "result.changed == true" } - -# ============================================================ -- name: create blank mysql user to be removed later - mysql_user: - name: "" - state: present - password: 'KJFDY&D*Sfuydsgf' - login_unix_socket: '{{ mysql_socket }}' - -- name: remove blank mysql user with hosts=all (expect changed) - mysql_user: - user: "" - host_all: true - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert changed is true for removing all blank users - assert: { that: "result.changed == true" } - -- name: remove blank mysql user with hosts=all (expect ok) - mysql_user: - user: "" - host_all: true - state: absent - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert changed is true for removing all blank users - assert: { that: "result.changed == false" } diff --git a/tests/integration/targets/mysql_user/tasks/resource_limits.yml b/tests/integration/targets/mysql_user/tasks/resource_limits.yml deleted file mode 100644 index 1e2928f0da..0000000000 --- a/tests/integration/targets/mysql_user/tasks/resource_limits.yml +++ /dev/null @@ -1,112 +0,0 @@ -# test code for resource_limits parameter - -- block: - - - name: Drop mysql user {{ user_name_1 }} if exists - mysql_user: - name: '{{ user_name_1 }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - - - name: Create mysql user {{ user_name_1 }} with resource limits in check_mode - mysql_user: - name: '{{ user_name_1 }}' - password: '{{ user_password_1 }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - resource_limits: - MAX_QUERIES_PER_HOUR: 10 - MAX_CONNECTIONS_PER_HOUR: 5 - check_mode: yes - register: result - - - assert: - that: - - result is changed - - - name: Create mysql user {{ user_name_1 }} with resource limits in actual mode - mysql_user: - name: '{{ user_name_1 }}' - password: '{{ user_password_1 }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - resource_limits: - MAX_QUERIES_PER_HOUR: 10 - MAX_CONNECTIONS_PER_HOUR: 5 - register: result - - - assert: - that: - - result is changed - - - name: Check - mysql_query: - query: > - SELECT User FROM mysql.user WHERE User = '{{ user_name_1 }}' AND Host = 'localhost' - AND max_questions = 10 AND max_connections = 5 - login_unix_socket: '{{ mysql_socket }}' - register: result - - - assert: - that: - - result.rowcount[0] == 1 - - - name: Try to set the same limits again in check mode - mysql_user: - name: '{{ user_name_1 }}' - password: '{{ user_password_1 }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - resource_limits: - MAX_QUERIES_PER_HOUR: 10 - MAX_CONNECTIONS_PER_HOUR: 5 - check_mode: yes - register: result - - - assert: - that: - - result is not changed - - - name: Try to set the same limits again in actual mode - mysql_user: - name: '{{ user_name_1 }}' - password: '{{ user_password_1 }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - resource_limits: - MAX_QUERIES_PER_HOUR: 10 - MAX_CONNECTIONS_PER_HOUR: 5 - register: result - - - assert: - that: - - result is not changed - - - name: Change limits - mysql_user: - name: '{{ user_name_1 }}' - password: '{{ user_password_1 }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - resource_limits: - MAX_QUERIES_PER_HOUR: 5 - MAX_CONNECTIONS_PER_HOUR: 5 - register: result - - - assert: - that: - - result is changed - - - name: Check - mysql_query: - query: > - SELECT User FROM mysql.user WHERE User = '{{ user_name_1 }}' AND Host = 'localhost' - AND max_questions = 5 AND max_connections = 5 - login_unix_socket: '{{ mysql_socket }}' - register: result - - - assert: - that: - - result.rowcount[0] == 1 - - when: (ansible_distribution == 'Ubuntu' and ansible_distribution_major_version >= '18') or (ansible_distribution == 'CentOS' and ansible_distribution_major_version >= '8') diff --git a/tests/integration/targets/mysql_user/tasks/test_priv_dict.yml b/tests/integration/targets/mysql_user/tasks/test_priv_dict.yml deleted file mode 100644 index a28cc806f6..0000000000 --- a/tests/integration/targets/mysql_user/tasks/test_priv_dict.yml +++ /dev/null @@ -1,46 +0,0 @@ -# Tests for priv parameter value passed as a dict -- name: Create test databases - mysql_db: - name: '{{ item }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - loop: - - data1 - - data2 - -- name: Create user with privileges - mysql_user: - name: '{{ user_name_3 }}' - password: '{{ user_password_3 }}' - priv: - "data1.*": "SELECT" - "data2.*": "SELECT" - state: present - login_unix_socket: '{{ mysql_socket }}' - -- name: Run command to show privileges for user (expect privileges in stdout) - command: mysql "-e SHOW GRANTS FOR '{{ user_name_3 }}'@'localhost';" - register: result - -- name: Assert user has giving privileges - assert: - that: - - "'GRANT SELECT ON `data1`.*' in result.stdout" - - "'GRANT SELECT ON `data2`.*' in result.stdout" - -########## -# Clean up -- name: Drop test databases - mysql_db: - name: '{{ item }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - loop: - - data1 - - data2 - -- name: Drop test user - mysql_user: - name: '{{ user_name_3 }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' diff --git a/tests/integration/targets/mysql_user/tasks/test_privs.yml b/tests/integration/targets/mysql_user/tasks/test_privs.yml deleted file mode 100644 index cec13c2c8a..0000000000 --- a/tests/integration/targets/mysql_user/tasks/test_privs.yml +++ /dev/null @@ -1,155 +0,0 @@ -# test code for privileges for mysql_user module -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ -- name: create user with basic select privileges - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - priv: '*.*:SELECT' - state: present - login_unix_socket: '{{ mysql_socket }}' - when: current_append_privs == "yes" - -- include: assert_user.yml user_name={{user_name_2}} priv='SELECT' - when: current_append_privs == "yes" - -- name: create user with current privileges (expect changed=true) - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - priv: '*.*:{{current_privilege}}' - append_privs: '{{current_append_privs}}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output message for current privileges - assert: { that: "result.changed == true" } - -- name: run command to show privileges for user (expect privileges in stdout) - command: mysql "-e SHOW GRANTS FOR '{{user_name_2}}'@'localhost';" - register: result - -- name: assert user has correct privileges - assert: { that: "'GRANT {{current_privilege | replace(',', ', ')}} ON *.*' in result.stdout" } - when: current_append_privs == "no" - -- name: assert user has correct privileges - assert: { that: "'GRANT SELECT, {{current_privilege | replace(',', ', ')}} ON *.*' in result.stdout" } - when: current_append_privs == "yes" - -- name: create database using user current privileges - mysql_db: - name: '{{ db_name }}' - state: present - login_user: '{{ user_name_2 }}' - login_password: '{{ user_password_2 }}' - ignore_errors: true - -- name: run command to test that database was not created - command: mysql "-e show databases like '{{ db_name }}';" - register: result - -- name: assert database was not created - assert: { that: "'{{ db_name }}' not in result.stdout" } - -# ============================================================ -- name: Add privs to a specific table (expect changed) - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - priv: 'jmainguy.jmainguy:ALL' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: Assert that priv changed - assert: { that: "result.changed == true" } - -- name: Add privs to a specific table (expect ok) - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - priv: 'jmainguy.jmainguy:ALL' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: Assert that priv did not change - assert: { that: "result.changed == false" } - -# ============================================================ -- name: update user with all privileges - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - priv: '*.*:ALL' - state: present - login_unix_socket: '{{ mysql_socket }}' - -- include: assert_user.yml user_name={{user_name_2}} priv='ALL PRIVILEGES' - -- name: create database using user - mysql_db: - name: '{{ db_name }}' - state: present - login_user: '{{ user_name_2 }}' - login_password: '{{ user_password_2 }}' - -- name: run command to test database was created using user new privileges - command: mysql "-e SHOW CREATE DATABASE {{ db_name }};" - -- name: drop database using user - mysql_db: - name: '{{ db_name }}' - state: absent - login_user: '{{ user_name_2 }}' - login_password: '{{ user_password_2 }}' - -# ============================================================ -- name: update user with a long privileges list (mysql has a special multiline grant output) - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - priv: '*.*:CREATE USER,FILE,PROCESS,RELOAD,REPLICATION CLIENT,REPLICATION SLAVE,SHOW DATABASES,SHUTDOWN,SUPER,CREATE,DROP,EVENT,LOCK TABLES,INSERT,UPDATE,DELETE,SELECT,SHOW VIEW,GRANT' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: Assert that priv changed - assert: { that: "result.changed == true" } - -- name: Test idempotency (expect ok) - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - priv: '*.*:CREATE USER,FILE,PROCESS,RELOAD,REPLICATION CLIENT,REPLICATION SLAVE,SHOW DATABASES,SHUTDOWN,SUPER,CREATE,DROP,EVENT,LOCK TABLES,INSERT,UPDATE,DELETE,SELECT,SHOW VIEW,GRANT' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: Assert that priv did not change - assert: { that: "result.changed == false" } - -- name: remove username - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' diff --git a/tests/integration/targets/mysql_user/tasks/user_password_update_test.yml b/tests/integration/targets/mysql_user/tasks/user_password_update_test.yml deleted file mode 100644 index a85e4edf04..0000000000 --- a/tests/integration/targets/mysql_user/tasks/user_password_update_test.yml +++ /dev/null @@ -1,155 +0,0 @@ -# test code update password for the mysql_user module -# (c) 2014, Wayne Rosario - -# 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 dof 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 . - -# ============================================================ -# Update user password for a user. -# Assert the user password is updated and old password can no longer be used. -# -- name: create user1 state=present with a password - mysql_user: - name: '{{ user_name_1 }}' - password: '{{ user_password_1 }}' - priv: '*.*:ALL' - state: present - login_unix_socket: '{{ mysql_socket }}' - -- name: create user2 state=present with a password - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - priv: '*.*:ALL' - state: present - login_unix_socket: '{{ mysql_socket }}' - -- name: store user2 grants with old password (mysql 5.7.6 and newer) - command: mysql "-e SHOW CREATE USER '{{ user_name_2 }}'@'localhost';" - register: user_password_old_create - ignore_errors: yes - -- name: store user2 grants with old password (mysql 5.7.5 and older) - command: mysql "-e SHOW GRANTS FOR '{{ user_name_2 }}'@'localhost';" - register: user_password_old - when: user_password_old_create is failed - -- name: update user2 state=present with same password (expect changed=false) - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - priv: '*.*:ALL' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- name: assert output user2 was not updated - assert: { that: "result.changed == false" } - -- include: assert_user.yml user_name={{user_name_2}} priv='ALL PRIVILEGES' - -- name: update user2 state=present with a new password (expect changed=true) - mysql_user: - name: '{{ user_name_2 }}' - password: '{{ user_password_1 }}' - state: present - login_unix_socket: '{{ mysql_socket }}' - register: result - -- include: assert_user.yml user_name={{user_name_2}} priv='ALL PRIVILEGES' - -- name: store user2 grants with old password (mysql 5.7.6 and newer) - command: mysql "-e SHOW CREATE USER '{{ user_name_2 }}'@'localhost';" - register: user_password_new_create - ignore_errors: yes - -- name: store user2 grants with new password - command: mysql "-e SHOW GRANTS FOR '{{ user_name_2 }}'@'localhost';" - register: user_password_new - when: user_password_new_create is failed - -- name: assert output message password was update for user2 (mysql 5.7.6 and newer) - assert: { that: "user_password_old_create.stdout != user_password_new_create.stdout" } - when: user_password_new_create is not failed - -- name: assert output message password was update for user2 (mysql 5.7.5 and older) - assert: { that: "user_password_old.stdout != user_password_new.stdout" } - when: user_password_new_create is failed - -- name: create database using user2 and old password - mysql_db: - name: '{{ db_name }}' - state: present - login_user: '{{ user_name_2 }}' - login_password: '{{ user_password_2 }}' - ignore_errors: true - register: result - -- debug: var=result.msg -- name: assert output message that database not create with old password - assert: - that: - - "result.failed == true" - -- name: create database using user2 and new password - mysql_db: - name: '{{ db_name }}' - state: present - login_user: '{{ user_name_2 }}' - login_password: '{{ user_password_1 }}' - register: result - -- name: assert output message that database is created with new password - assert: { that: "result.changed == true" } - -- name: remove database - mysql_db: - name: '{{ db_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - -- include: remove_user.yml user_name={{user_name_1}} user_password={{ user_password_1 }} - -- include: remove_user.yml user_name={{user_name_2}} user_password={{ user_password_1 }} - -- name: Create user with Fdt8fd^34ds using hash. (expect changed=true) - mysql_user: - name: jmainguy - password: '*0cb5b86f23fdc24db19a29b8854eb860cbc47793' - encrypted: yes - login_unix_socket: '{{ mysql_socket }}' - register: encrypt_result - -- name: Check that the module made a change - assert: - that: - - "encrypt_result.changed == True" - -- name: See if the password needs to be updated. (expect changed=false) - mysql_user: - name: jmainguy - password: 'Fdt8fd^34ds' - login_unix_socket: '{{ mysql_socket }}' - register: plain_result - -- name: Check that the module did not change the password - assert: - that: - - "plain_result.changed == False" - -- name: Remove user (cleanup) - mysql_user: - name: jmainguy - state: absent diff --git a/tests/integration/targets/mysql_variables/aliases b/tests/integration/targets/mysql_variables/aliases deleted file mode 100644 index c72bb40e18..0000000000 --- a/tests/integration/targets/mysql_variables/aliases +++ /dev/null @@ -1,6 +0,0 @@ -destructive -shippable/posix/group3 -skip/aix -skip/osx -skip/freebsd -skip/rhel diff --git a/tests/integration/targets/mysql_variables/defaults/main.yml b/tests/integration/targets/mysql_variables/defaults/main.yml deleted file mode 100644 index e7860ac026..0000000000 --- a/tests/integration/targets/mysql_variables/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -# defaults file for test_mysql_variables -user: 'user1' -password: 'khH&DYigjg1#' diff --git a/tests/integration/targets/mysql_variables/meta/main.yml b/tests/integration/targets/mysql_variables/meta/main.yml deleted file mode 100644 index e7631b066f..0000000000 --- a/tests/integration/targets/mysql_variables/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - setup_mysql8 diff --git a/tests/integration/targets/mysql_variables/tasks/assert_fail_msg.yml b/tests/integration/targets/mysql_variables/tasks/assert_fail_msg.yml deleted file mode 100644 index ba51b9d67c..0000000000 --- a/tests/integration/targets/mysql_variables/tasks/assert_fail_msg.yml +++ /dev/null @@ -1,25 +0,0 @@ -# test code to assert message in mysql_variables module -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ -# Assert message failure and confirm failed=true -# -- name: assert message failure (expect failed=true) - assert: - that: - - "output.failed == true" diff --git a/tests/integration/targets/mysql_variables/tasks/assert_var.yml b/tests/integration/targets/mysql_variables/tasks/assert_var.yml deleted file mode 100644 index 1f4d2736b4..0000000000 --- a/tests/integration/targets/mysql_variables/tasks/assert_var.yml +++ /dev/null @@ -1,34 +0,0 @@ -# test code to assert variables in mysql_variables module -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ -# Assert mysql variable name and value from mysql database -# -- name: assert output message changed value - assert: { that: "output.changed == {{changed}}" } - -- name: run mysql command to show variable - command: "mysql -uroot -p{{ root_pass }} \"-e show variables like '{{var_name}}';\"" - register: result - -- name: assert output mysql variable name and value - assert: - that: - - "result.changed == true" - - "'{{var_name}}' in result.stdout" - - "'{{var_value}}' in result.stdout" diff --git a/tests/integration/targets/mysql_variables/tasks/assert_var_output.yml b/tests/integration/targets/mysql_variables/tasks/assert_var_output.yml deleted file mode 100644 index 869381679a..0000000000 --- a/tests/integration/targets/mysql_variables/tasks/assert_var_output.yml +++ /dev/null @@ -1,38 +0,0 @@ -# test code to assert variables in mysql_variables module -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ -# Assert output variable name/value match mysql variable name/value -# -- name: assert output message changed value - assert: { that: "output.changed == {{changed}}" } - -- set_fact: - key_name: "{{var_name}}" - key_value: "{{output.msg[0][0]}}" - -- name: run mysql command to show variable - command: "mysql -uroot -p{{ root_pass }} \"-e show variables like '{{var_name}}';\"" - register: result - -- name: assert output variable info match mysql variable info - assert: - that: - - "result.changed == true" - - "key_name in result.stdout" - - "key_value in result.stdout" diff --git a/tests/integration/targets/mysql_variables/tasks/main.yml b/tests/integration/targets/mysql_variables/tasks/main.yml deleted file mode 100644 index 801fa7733b..0000000000 --- a/tests/integration/targets/mysql_variables/tasks/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -- import_tasks: mysql_variables.yml - when: ansible_distribution == 'CentOS' and ansible_distribution_major_version >= '7' diff --git a/tests/integration/targets/mysql_variables/tasks/mysql_variables.yml b/tests/integration/targets/mysql_variables/tasks/mysql_variables.yml deleted file mode 100644 index be42bcee71..0000000000 --- a/tests/integration/targets/mysql_variables/tasks/mysql_variables.yml +++ /dev/null @@ -1,412 +0,0 @@ -# test code for the mysql_variables module -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ -# Verify mysql_variable successfully queries a variable -# -- set_fact: set_name='version' - -- name: read mysql variables (expect changed=false) - mysql_variables: - variable: '{{set_name}}' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - register: result - -- include: assert_var_output.yml changed=false output={{result}} var_name={{set_name}} - -# ============================================================ -# Verify mysql_variable successfully updates a variable (issue:4568) -# -- set_fact: - set_name: 'delay_key_write' - set_value: 'ON' - -- name: set mysql variable - mysql_variables: - variable: '{{set_name}}' - value: '{{set_value}}' - login_user: root - login_password: '{{ root_pass }}' - login_unix_socket: '{{ mysql_socket }}' - -- name: update mysql variable to same value (expect changed=false) - mysql_variables: - variable: '{{set_name}}' - value: '{{set_value}}' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - register: result - -- include: assert_var.yml changed=false output={{result}} var_name={{set_name}} var_value={{set_value}} - -# ============================================================ -# Verify mysql_variable successfully updates a variable using single quotes -# -- set_fact: - set_name: 'wait_timeout' - set_value: '300' - -- name: set mysql variable to a temp value - mysql_variables: - variable: '{{set_name}}' - value: '200' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - -- name: update mysql variable value (expect changed=true) - mysql_variables: - variable: '{{set_name}}' - value: '{{set_value}}' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - register: result - -- assert: - that: - - result.queries == ["SET GLOBAL `{{ set_name }}` = {{ set_value }}"] - -- include: assert_var.yml changed=true output={{result}} var_name={{set_name}} var_value='{{set_value}}' - -# ============================================================ -# Verify mysql_variable successfully updates a variable using double quotes -# -- set_fact: - set_name: "wait_timeout" - set_value: "400" - -- name: set mysql variable to a temp value - mysql_variables: - variable: '{{set_name}}' - value: "200" - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - -- name: update mysql variable value (expect changed=true) - mysql_variables: - variable: '{{set_name}}' - value: '{{set_value}}' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - register: result - -- include: assert_var.yml changed=true output={{result}} var_name={{set_name}} var_value='{{set_value}}' - -# ============================================================ -# Verify mysql_variable successfully updates a variable using no quotes -# -- set_fact: - set_name: wait_timeout - set_value: 500 - -- name: set mysql variable to a temp value - mysql_variables: - variable: '{{set_name}}' - value: 200 - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - -- name: update mysql variable value (expect changed=true) - mysql_variables: - variable: '{{set_name}}' - value: '{{set_value}}' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - register: result - -- include: assert_var.yml changed=true output={{result}} var_name={{set_name}} var_value='{{set_value}}' - -# ============================================================ -# Verify mysql_variable successfully updates a variable using an expression (e.g. 1024*4) -# -- name: set mysql variable value to an expression - mysql_variables: - variable: max_tmp_tables - value: "1024*4" - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - register: result - ignore_errors: true - -- include: assert_fail_msg.yml output={{result}} msg='Incorrect argument type to variable' - -# ============================================================ -# Verify mysql_variable fails when setting an incorrect value (out of range) -# -- name: set mysql variable value to a number out of range - mysql_variables: - variable: max_tmp_tables - value: -1 - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - register: result - ignore_errors: true - -- include: assert_fail_msg.yml output={{result}} msg='Truncated incorrect' - -# ============================================================ -# Verify mysql_variable fails when setting an incorrect value (incorrect type) -# -- name: set mysql variable value to a non-valid value number - mysql_variables: - variable: max_tmp_tables - value: TEST - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - register: result - ignore_errors: true - -- include: assert_fail_msg.yml output={{result}} msg='Incorrect argument type to variable' - -# ============================================================ -# Verify mysql_variable fails when setting an unknown variable -# -- name: set a non mysql variable - mysql_variables: - variable: my_sql_variable - value: ON - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - register: result - ignore_errors: true - -- include: assert_fail_msg.yml output={{result}} msg='Variable not available' - -# ============================================================ -# Verify mysql_variable fails when setting a read-only variable -# -- name: set value of a read only mysql variable - mysql_variables: - variable: character_set_system - value: utf16 - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - register: result - ignore_errors: true - -- include: assert_fail_msg.yml output={{result}} msg='read only variable' - -#============================================================= -# Verify mysql_variable works with the login_user and login_password parameters -# -- name: create mysql user - mysql_user: - name: '{{user}}' - password: '{{password}}' - state: present - priv: '*.*:ALL' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - -- set_fact: - set_name: wait_timeout - set_value: 77 - -- name: query mysql_variable using login_user and password_password - mysql_variables: - variable: '{{set_name}}' - login_user: '{{user}}' - login_password: '{{password}}' - register: result - -- include: assert_var_output.yml changed=false output={{result}} var_name={{set_name}} - -- name: set mysql variable to temp value using user login and password (expect changed=true) - mysql_variables: - variable: '{{set_name}}' - value: 20 - login_user: '{{user}}' - login_password: '{{password}}' - register: result - -- name: update mysql variable value using user login and password (expect changed=true) - mysql_variables: - variable: '{{set_name}}' - value: '{{set_value}}' - login_user: '{{user}}' - login_password: '{{password}}' - register: result - -- include: assert_var.yml changed=true output={{result}} var_name={{set_name}} var_value='{{set_value}}' - -#============================================================ -# Verify mysql_variable fails with an incorrect login_password parameter -# -- set_fact: - set_name: connect_timeout - set_value: 10 - -- name: query mysql_variable using incorrect login_password - mysql_variables: - variable: '{{set_name}}' - login_user: '{{user}}' - login_password: 'wrongpassword' - register: result - ignore_errors: true - -- include: assert_fail_msg.yml output={{result}} msg='unable to connect to database' - -- name: update mysql variable value using incorrect login_password (expect failed=true) - mysql_variables: - variable: '{{set_name}}' - value: '{{set_value}}' - login_user: '{{user}}' - login_password: 'this is an incorrect password' - register: result - ignore_errors: true - -- include: assert_fail_msg.yml output={{result}} msg='unable to connect to database' - -#============================================================ -# Verify mysql_variable fails with an incorrect login_host parameter -# -- name: query mysql_variable using incorrect login_host - mysql_variables: - variable: wait_timeout - login_host: '12.0.0.9' - login_user: '{{user}}' - login_password: '{{password}}' - connect_timeout: 5 - register: result - ignore_errors: true - -- include: assert_fail_msg.yml output={{result}} msg='unable to connect to database' - -- name: remove mysql_user {{user}} - mysql_user: - name: '{{user}}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - -#========================================= -# Check mode 'persist' and 'persist_only': -# -- name: update mysql variable value (expect changed=true) in persist mode - mysql_variables: - variable: '{{ set_name }}' - value: '{{ set_value }}' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - mode: persist - register: result - -- assert: - that: - - result.queries == ["SET PERSIST `{{ set_name }}` = {{ set_value }}"] - -- include: assert_var.yml changed=true output={{result}} var_name={{set_name}} var_value='{{set_value}}' - -- name: try to update mysql variable value (expect changed=false) in persist mode again - mysql_variables: - variable: '{{ set_name }}' - value: '{{ set_value }}' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - mode: persist - register: result - -- include: assert_var.yml changed=false output={{result}} var_name={{set_name}} var_value='{{set_value}}' - -- name: set mysql variable to a temp value - mysql_variables: - variable: '{{ set_name }}' - value: '200' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - mode: persist - -- name: update mysql variable value (expect changed=true) in persist_only mode - mysql_variables: - variable: '{{ set_name }}' - value: '{{ set_value }}' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - mode: persist_only - register: result - -- assert: - that: - - result is changed - - result.queries == ["SET PERSIST_ONLY `{{ set_name }}` = {{ set_value }}"] - -- name: try to update mysql variable value (expect changed=false) in persist_only mode again - mysql_variables: - variable: '{{ set_name }}' - value: '{{ set_value }}' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - mode: persist_only - register: result - -- assert: - that: - - result is not changed - -- set_fact: - set_name: max_connections - set_value: 105 - def_val: 151 - -- name: update mysql variable value (expect changed=true) in persist_only mode - mysql_variables: - variable: '{{ set_name }}' - value: '{{ set_value }}' - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - mode: persist_only - register: result - -- include: assert_var.yml changed=true output={{result}} var_name={{set_name}} var_value='{{def_val}}' - -# Bugfix of https://github.com/ansible/ansible/issues/54239 -- name: set variable containing dot - mysql_variables: - login_unix_socket: '{{ mysql_socket }}' - login_user: root - login_password: '{{ root_pass }}' - variable: validate_password.policy - value: LOW - mode: persist_only - register: result - -- assert: - that: - - result is changed - - result.queries == ["SET PERSIST_ONLY `validate_password`.`policy` = LOW"] diff --git a/tests/integration/targets/setup_mysql8/defaults/main.yml b/tests/integration/targets/setup_mysql8/defaults/main.yml deleted file mode 100644 index 66b75a11eb..0000000000 --- a/tests/integration/targets/setup_mysql8/defaults/main.yml +++ /dev/null @@ -1,21 +0,0 @@ -repo_link: https://repo.mysql.com/mysql80-community-release-el{{ ansible_facts.distribution_major_version }}.rpm -my_cnf: /etc/my.cnf - -mysql_data_dirs: - - /var/lib/mysql - - /usr/mysql - -mysql_support_packages: - - MySQL-python - -mysql_server_packages: - - mysql-community-server - -mysql_cleanup_packages: - - mysql-community-client - - mysql-community-common - - mysql-community-libs - - mysql-community-libs-compat - - mysql-community-server - - mysql80-community-release - - python3-PyMySQL diff --git a/tests/integration/targets/setup_mysql8/files/my.cnf b/tests/integration/targets/setup_mysql8/files/my.cnf deleted file mode 100644 index 7fdc2afc26..0000000000 --- a/tests/integration/targets/setup_mysql8/files/my.cnf +++ /dev/null @@ -1,7 +0,0 @@ -[mysqld] -datadir=/var/lib/mysql -socket=/var/lib/mysql/mysql.sock -log-error=/var/log/mysqld.log -pid-file=/var/run/mysqld/mysqld.pid -default_authentication_plugin=mysql_native_password -skip-grant-tables diff --git a/tests/integration/targets/setup_mysql8/handlers/main.yml b/tests/integration/targets/setup_mysql8/handlers/main.yml deleted file mode 100644 index 6d30b5725c..0000000000 --- a/tests/integration/targets/setup_mysql8/handlers/main.yml +++ /dev/null @@ -1,29 +0,0 @@ -- name: stop mysql service - service: - name: mysqld - state: stopped - listen: cleanup mysql8 - -- name: remove repo - # yum: - # name: mysql80-community-release - # state: absent - # Work around for a bug in the dnf module. Use the module once that gets fixed. - # https://github.com/ansible/ansible/issues/64294 - command: "{{ ansible_facts.pkg_mgr}} -y erase mysql80-community-release" - args: - warn: no - listen: cleanup mysql8 - -- name: remove mysql packages - yum: - name: '{{ mysql_support_packages | union(mysql_server_packages) | union(mysql_cleanup_packages) }}' - state: absent - listen: cleanup mysql8 - -- name: remove mysql data - file: - path: "{{ item }}" - state: absent - loop: "{{ mysql_data_dirs }}" - listen: cleanup mysql8 diff --git a/tests/integration/targets/setup_mysql8/tasks/main.yml b/tests/integration/targets/setup_mysql8/tasks/main.yml deleted file mode 100644 index 86ea1f8e0f..0000000000 --- a/tests/integration/targets/setup_mysql8/tasks/main.yml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Setup MySQL 8: -- name: Include distribution specific variables - include_vars: "{{ lookup('first_found', params) }}" - vars: - params: - files: - - '{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml' - - '{{ ansible_facts.os_family }}.yml' - - 'default.yml' - paths: vars - -- import_tasks: setup_mysql8.yml - when: - - ansible_facts.distribution == 'CentOS' - - ansible_facts.distribution_major_version is version_compare('7', '>=') diff --git a/tests/integration/targets/setup_mysql8/tasks/setup_mysql8.yml b/tests/integration/targets/setup_mysql8/tasks/setup_mysql8.yml deleted file mode 100644 index 29f4d9dcd8..0000000000 --- a/tests/integration/targets/setup_mysql8/tasks/setup_mysql8.yml +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Install PyMySQL package via pip - pip: - name: PyMySQL - state: present - -- name: Install MySQL repo - yum: - name: '{{ repo_link }}' - notify: cleanup mysql8 - -# These packages come from AppStream in RHEL 8, so they need to be done in a separate task -- name: Install MySQL support packages - yum: - name: "{{ mysql_support_packages }}" - notify: cleanup mysql8 - -- name: Install MySQL community server - yum: - name: '{{ mysql_server_packages }}' - disablerepo: '{{ mysql_disablerepo | default(omit) }}' - notify: cleanup mysql8 - -- name: Copy my.cnf - copy: - src: my.cnf - dest: '{{ my_cnf }}' - -- name: Start MySQL - service: - name: mysqld - state: started - -### Debug ####################### -#- name: Debug -# shell: cat /var/log/mysqld.log -################################# - -- name: Check connection to the server - shell: 'echo "SHOW DATABASES;" | mysql' - -- name: Check connection to the server - shell: "echo \"SHOW VARIABLES LIKE '%version%';\" | mysql" - -- name: Detect socket path - shell: 'echo "show variables like ''socket''\G" | mysql | grep ''Value: '' | sed ''s/[ ]\+Value: //''' - register: _socket_path - -- name: Set socket path - set_fact: - mysql_socket: '{{ _socket_path["stdout"] }}' - -- name: Set root pass - set_fact: - root_pass: "dlsafjlkjdsaK1#" - -- name: Set root password - shell: 'echo "flush privileges; ALTER USER ''root''@''localhost'' IDENTIFIED WITH mysql_native_password BY ''{{ root_pass }}'';" | mysql' - -- name: Change configuration - lineinfile: - path: '{{ my_cnf }}' - line: skip-grant-tables - state: absent - -- name: Restart MySQL - service: - name: mysqld - state: restarted diff --git a/tests/integration/targets/setup_mysql8/vars/CentOS-8.yml b/tests/integration/targets/setup_mysql8/vars/CentOS-8.yml deleted file mode 100644 index 3d61bda742..0000000000 --- a/tests/integration/targets/setup_mysql8/vars/CentOS-8.yml +++ /dev/null @@ -1,4 +0,0 @@ -mysql_support_packages: - - python3-PyMySQL - -mysql_disablerepo: AppStream diff --git a/tests/integration/targets/setup_mysql8/vars/Debian.yml b/tests/integration/targets/setup_mysql8/vars/Debian.yml deleted file mode 100644 index 78323264f6..0000000000 --- a/tests/integration/targets/setup_mysql8/vars/Debian.yml +++ /dev/null @@ -1,3 +0,0 @@ -mysql_data_dirs: - - /var/lib/mysql - - /usr/share/mysql diff --git a/tests/integration/targets/setup_mysql8/vars/RedHat-8.yml b/tests/integration/targets/setup_mysql8/vars/RedHat-8.yml deleted file mode 100644 index f636617585..0000000000 --- a/tests/integration/targets/setup_mysql8/vars/RedHat-8.yml +++ /dev/null @@ -1,4 +0,0 @@ -mysql_support_packages: - - python3-PyMySQL - -mysql_disablerepo: rhel-8-for-x86_64-appstream-rpms diff --git a/tests/integration/targets/setup_mysql8/vars/default.yml b/tests/integration/targets/setup_mysql8/vars/default.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/integration/targets/setup_mysql_db/defaults/main.yml b/tests/integration/targets/setup_mysql_db/defaults/main.yml deleted file mode 100644 index 47712dc266..0000000000 --- a/tests/integration/targets/setup_mysql_db/defaults/main.yml +++ /dev/null @@ -1,18 +0,0 @@ -mysql_service: mysqld - -mysql_packages: - - mysql-server - - MySQL-python - - bzip2 - -mysql_cleanup_packages: - - mysql-community-client - - mysql-community-common - - mysql-community-libs - - mysql-community-libs-compat - - mysql-community-server - - mysql80-community-release - -mysql_data_dirs: - - /var/lib/mysql - - /usr/mysql diff --git a/tests/integration/targets/setup_mysql_db/handlers/main.yml b/tests/integration/targets/setup_mysql_db/handlers/main.yml deleted file mode 100644 index 5b54ea2729..0000000000 --- a/tests/integration/targets/setup_mysql_db/handlers/main.yml +++ /dev/null @@ -1,25 +0,0 @@ -- name: stop mysql service - service: - name: "{{ mysql_service }}" - state: stopped - listen: cleanup mysql - -- name: remove mysql packages - action: '{{ ansible_facts.pkg_mgr }}' - args: - name: "{{ item }}" - state: absent - loop: "{{ mysql_packages | union(mysql_cleanup_packages) }}" - listen: cleanup mysql - -- name: remove mysql data - file: - path: "{{ item }}" - state: absent - loop: "{{ mysql_data_dirs }}" - listen: cleanup mysql - -- name: remove pip packages - pip: - name: mysql-python - state: absent diff --git a/tests/integration/targets/setup_mysql_db/meta/main.yml b/tests/integration/targets/setup_mysql_db/meta/main.yml deleted file mode 100644 index 5438ced5c3..0000000000 --- a/tests/integration/targets/setup_mysql_db/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - setup_pkg_mgr diff --git a/tests/integration/targets/setup_mysql_db/tasks/main.yml b/tests/integration/targets/setup_mysql_db/tasks/main.yml deleted file mode 100644 index b7c5e06b78..0000000000 --- a/tests/integration/targets/setup_mysql_db/tasks/main.yml +++ /dev/null @@ -1,112 +0,0 @@ -# setup code for the mysql_db module -# (c) 2014, Wayne Rosario - -# 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 . - -# ============================================================ -- name: python 2 - set_fact: - python_suffix: "" - when: ansible_python_version is version('3', '<') - -- name: python 3 - set_fact: - python_suffix: "-py3" - when: ansible_python_version is version('3', '>=') - -- name: Include distribution specific variables - include_vars: "{{ lookup('first_found', params) }}" - vars: - params: - files: - - '{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}{{ python_suffix }}.yml' - - '{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml' - - '{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}{{ python_suffix }}.yml' - - '{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml' - - '{{ ansible_facts.distribution }}{{ python_suffix }}.yml' - - '{{ ansible_facts.os_family }}{{ python_suffix }}.yml' - - 'default{{ python_suffix }}.yml' - paths: "{{ role_path }}/vars" - -- name: install mysqldb_test rpm dependencies - yum: - name: "{{ mysql_packages }}" - state: latest - when: ansible_facts.pkg_mgr == 'yum' - notify: cleanup mysql - -- name: install mysqldb_test rpm dependencies - dnf: - name: '{{ mysql_packages }}' - state: latest - install_weak_deps: False # mariadb-server has a weak dep on python2 which break Python 3 test environments - when: ansible_facts.pkg_mgr == 'dnf' - notify: cleanup mysql - -- name: install mysqldb_test debian dependencies - apt: - name: "{{ mysql_packages }}" - state: latest - when: ansible_facts.pkg_mgr == 'apt' - notify: cleanup mysql - -- name: install mysqldb_test opensuse dependencies - zypper: - name: "{{ mysql_packages }}" - state: latest - when: ansible_facts.pkg_mgr in ['zypper', 'community.general.zypper'] - notify: cleanup mysql - -- name: install mysqldb_test FreeBSD dependencies - package: - name: "{{ mysql_packages }}" - state: present - when: ansible_os_family == "FreeBSD" - notify: cleanup mysql - -- name: install mysql-python package via pip (FreeBSD) - pip: - name: mysql-python - state: present - when: ansible_os_family == "FreeBSD" - notify: - - cleanup mysql - - remove pip packages - -- name: enable mysql-server service (FreeBSD) - lineinfile: - path: /etc/rc.conf - line: 'mysql_server_enable="YES"' - when: ansible_os_family == "FreeBSD" - -- name: apply work-around for OverlayFS issue - # https://github.com/docker/for-linux/issues/72#issuecomment-319904698 - command: find {{ mysql_data_dirs[0] }} -type f -exec touch {} ; - # find will fail if mysql has never been started, as the directory won't exist - ignore_errors: yes - -- name: restart mysql_db service - service: - name: "{{ mysql_service }}" - state: restarted - -- name: Detect socket path - shell: 'echo "show variables like ''socket''\G" | mysql | grep ''Value: '' | sed ''s/[ ]\+Value: //''' - register: _socket_path - -- name: Set socket path - set_fact: - mysql_socket: '{{ _socket_path["stdout"] }}' diff --git a/tests/integration/targets/setup_mysql_db/vars/Debian.yml b/tests/integration/targets/setup_mysql_db/vars/Debian.yml deleted file mode 100644 index 52062c703d..0000000000 --- a/tests/integration/targets/setup_mysql_db/vars/Debian.yml +++ /dev/null @@ -1,16 +0,0 @@ -mysql_service: 'mysql' - -mysql_packages: - - mysql-server - - python-mysqldb - - bzip2 - -mysql_cleanup_packages: - - mysql-client* - - mysql-server* - - mysql-common - - mysql-sandbox - -mysql_data_dirs: - - /var/lib/mysql - - /usr/share/mysql diff --git a/tests/integration/targets/setup_mysql_db/vars/Fedora-py3.yml b/tests/integration/targets/setup_mysql_db/vars/Fedora-py3.yml deleted file mode 100644 index fa7d06e52a..0000000000 --- a/tests/integration/targets/setup_mysql_db/vars/Fedora-py3.yml +++ /dev/null @@ -1,6 +0,0 @@ -mysql_service: 'mariadb' - -mysql_packages: - - mariadb-server - - python3-PyMySQL - - bzip2 diff --git a/tests/integration/targets/setup_mysql_db/vars/Fedora.yml b/tests/integration/targets/setup_mysql_db/vars/Fedora.yml deleted file mode 100644 index 718326ae08..0000000000 --- a/tests/integration/targets/setup_mysql_db/vars/Fedora.yml +++ /dev/null @@ -1,6 +0,0 @@ -mysql_service: 'mariadb' - -mysql_packages: - - mariadb-server - - python-PyMySQL - - bzip2 diff --git a/tests/integration/targets/setup_mysql_db/vars/FreeBSD.yml b/tests/integration/targets/setup_mysql_db/vars/FreeBSD.yml deleted file mode 100644 index af45ebfd40..0000000000 --- a/tests/integration/targets/setup_mysql_db/vars/FreeBSD.yml +++ /dev/null @@ -1,5 +0,0 @@ -mysql_service: 'mysql-server' - -mysql_packages: - - mariadb101-server - - py-pymysql diff --git a/tests/integration/targets/setup_mysql_db/vars/RedHat-7.yml b/tests/integration/targets/setup_mysql_db/vars/RedHat-7.yml deleted file mode 100644 index f8b29fd7a1..0000000000 --- a/tests/integration/targets/setup_mysql_db/vars/RedHat-7.yml +++ /dev/null @@ -1,6 +0,0 @@ -mysql_service: 'mariadb' - -mysql_packages: - - mariadb-server - - MySQL-python - - bzip2 diff --git a/tests/integration/targets/setup_mysql_db/vars/RedHat-8.yml b/tests/integration/targets/setup_mysql_db/vars/RedHat-8.yml deleted file mode 100644 index fa7d06e52a..0000000000 --- a/tests/integration/targets/setup_mysql_db/vars/RedHat-8.yml +++ /dev/null @@ -1,6 +0,0 @@ -mysql_service: 'mariadb' - -mysql_packages: - - mariadb-server - - python3-PyMySQL - - bzip2 diff --git a/tests/integration/targets/setup_mysql_db/vars/RedHat.yml b/tests/integration/targets/setup_mysql_db/vars/RedHat.yml deleted file mode 100644 index 742c35225b..0000000000 --- a/tests/integration/targets/setup_mysql_db/vars/RedHat.yml +++ /dev/null @@ -1,6 +0,0 @@ -mysql_service: 'mysqld' - -mysql_packages: - - mysql-server - - MySQL-python - - bzip2 diff --git a/tests/integration/targets/setup_mysql_db/vars/Suse-py3.yml b/tests/integration/targets/setup_mysql_db/vars/Suse-py3.yml deleted file mode 100644 index adf2754d75..0000000000 --- a/tests/integration/targets/setup_mysql_db/vars/Suse-py3.yml +++ /dev/null @@ -1,6 +0,0 @@ -mysql_service: 'mysql' - -mysql_packages: - - mariadb - - python3-PyMySQL - - bzip2 diff --git a/tests/integration/targets/setup_mysql_db/vars/Suse.yml b/tests/integration/targets/setup_mysql_db/vars/Suse.yml deleted file mode 100644 index a48a2e1330..0000000000 --- a/tests/integration/targets/setup_mysql_db/vars/Suse.yml +++ /dev/null @@ -1,6 +0,0 @@ -mysql_service: 'mysql' - -mysql_packages: - - mariadb - - python-PyMySQL - - bzip2 diff --git a/tests/integration/targets/setup_mysql_db/vars/Ubuntu-py3.yml b/tests/integration/targets/setup_mysql_db/vars/Ubuntu-py3.yml deleted file mode 100644 index 7728244252..0000000000 --- a/tests/integration/targets/setup_mysql_db/vars/Ubuntu-py3.yml +++ /dev/null @@ -1,16 +0,0 @@ -mysql_service: 'mysql' - -mysql_packages: - - mysql-server - - python3-pymysql - - bzip2 - -mysql_cleanup_packages: - - mysql-client* - - mysql-server* - - mysql-common - - mysql-sandbox - -mysql_data_dirs: - - /var/lib/mysql - - /usr/share/mysql diff --git a/tests/integration/targets/setup_mysql_db/vars/default-py3.yml b/tests/integration/targets/setup_mysql_db/vars/default-py3.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/integration/targets/setup_mysql_db/vars/default.yml b/tests/integration/targets/setup_mysql_db/vars/default.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/integration/targets/setup_mysql_replication/defaults/main.yml b/tests/integration/targets/setup_mysql_replication/defaults/main.yml deleted file mode 100644 index ad06a0ad19..0000000000 --- a/tests/integration/targets/setup_mysql_replication/defaults/main.yml +++ /dev/null @@ -1,14 +0,0 @@ -# There is no MySQL 5.7 for RHEL 8. This will need to be retooled to use 8.0 for RHEL 8 or use the setup_mysql8 role for everything -repo_link: https://repo.mysql.com/mysql57-community-release-el{{ ansible_facts.distribution_major_version }}.rpm -repo_name: mysql-community -mysql_package_name: mysql-community-server - -master_port: 3306 -standby_port: 3307 -master_datadir: /var/lib/mysql_master -master_cnf: /etc/my-1.cnf -standby_cnf: /etc/my-2.cnf -standby_datadir: /var/lib/mysql_standby -standby_logdir: /var/log/mysql_standby -default_logdir: /var/log/mysql -mysqld_err_log: '{{ default_logdir }}/mysql-err.log' diff --git a/tests/integration/targets/setup_mysql_replication/tasks/main.yml b/tests/integration/targets/setup_mysql_replication/tasks/main.yml deleted file mode 100644 index 0f507f74f1..0000000000 --- a/tests/integration/targets/setup_mysql_replication/tasks/main.yml +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Setup MySQL master-standby replication into one container: -- import_tasks: setup_mysql_cluster.yml - when: - - ansible_facts.distribution == 'CentOS' - - ansible_facts.distribution_major_version is version('7', '==') diff --git a/tests/integration/targets/setup_mysql_replication/tasks/setup_mysql_cluster.yml b/tests/integration/targets/setup_mysql_replication/tasks/setup_mysql_cluster.yml deleted file mode 100644 index 62bf6dd39b..0000000000 --- a/tests/integration/targets/setup_mysql_replication/tasks/setup_mysql_cluster.yml +++ /dev/null @@ -1,65 +0,0 @@ -# We run two servers listening different ports -# to be able to check replication (one server for master, another for standby). - -- name: Install PyMySQL package via pip - pip: - name: PyMySQL - state: present - -- name: Install Repo - yum: - name: '{{ repo_link }}' - -- name: Install MySQL community server - yum: - name: '{{ mysql_package_name }}' - -- name: Create directories - file: - state: directory - path: "{{ item }}" - owner: mysql - group: mysql - loop: - - "{{ master_datadir }}" - - "{{ standby_datadir }}" - - "{{ standby_logdir }}" - - "{{ default_logdir }}" - -- name: Copy cnf templates - template: - src: '{{ item.conf_templ }}' - dest: '{{ item.conf_dest }}' - owner: mysql - group: mysql - force: yes - loop: - - { conf_templ: my-1.cnf.j2, conf_dest: '{{ master_cnf }}' } - - { conf_templ: my-2.cnf.j2, conf_dest: '{{ standby_cnf }}' } - -- name: Initialize DBs - shell: 'mysqld --user=mysql --initialize-insecure --datadir={{ item }}' - loop: - - '{{ master_datadir }}' - - '{{ standby_datadir }}' - -- name: Start master services - shell: 'mysqld --defaults-file={{ master_cnf }} --user=mysql --datadir={{ master_datadir }} --log-error={{ mysqld_err_log }} &' - -- name: Start standby services - shell: 'mysqld --defaults-file={{ standby_cnf }} --user=mysql --datadir={{ standby_datadir }} --log-error={{ mysqld_err_log }} &' - -- name: Pause - pause: seconds=3 - -########### For painful debug uncomment the lines below ## -#- name: DEBUG Check log -# shell: 'cat {{ mysqld_err_log }}' -# ignore_errors: yes -########################################################## - -- name: Check connection to the master - shell: 'echo "SHOW DATABASES;" | mysql -P {{ master_port }} -h 127.0.0.1' - -- name: Check connection to the standby - shell: "echo \"SHOW VARIABLES LIKE '%version%';\" | mysql -P {{ standby_port }} -h 127.0.0.1" diff --git a/tests/integration/targets/setup_mysql_replication/templates/my-1.cnf.j2 b/tests/integration/targets/setup_mysql_replication/templates/my-1.cnf.j2 deleted file mode 100644 index 7e8787afc0..0000000000 --- a/tests/integration/targets/setup_mysql_replication/templates/my-1.cnf.j2 +++ /dev/null @@ -1,11 +0,0 @@ -[mysqld] -server_id = 1 -port = {{ master_port }} -datadir = {{ master_datadir }} -socket = {{ master_datadir }}/mysql.sock -pid-file = {{ master_datadir }}/mysql.pid -#mysqladmin = /usr/bin/mysqladmin -log_bin = /var/log/mysql/mysql-bin.log -sync_binlog = 1 -binlog-format = ROW -innodb_flush_log_at_trx_commit = 1 diff --git a/tests/integration/targets/setup_mysql_replication/templates/my-2.cnf.j2 b/tests/integration/targets/setup_mysql_replication/templates/my-2.cnf.j2 deleted file mode 100644 index 2d7550b8e5..0000000000 --- a/tests/integration/targets/setup_mysql_replication/templates/my-2.cnf.j2 +++ /dev/null @@ -1,13 +0,0 @@ -[mysqld] -server_id = 2 -port = {{ standby_port }} -socket = /var/run/mysqld/mysqld_slave.sock -pid-file = /var/run/mysqld/mysqld_slave.pid -datadir = {{ standby_datadir }} -log_bin = {{ standby_logdir }}/mysql-bin.log -relay-log = {{ standby_logdir }}/relay-bin -relay-log-index = {{ standby_logdir }}/relay-bin.index -master-info-file = {{ standby_logdir }}/master.info -relay-log-info-file = {{ standby_logdir }}/relay-log.info -master-info-repository = TABLE -relay-log-info-repository = TABLE diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index b865e42c86..d8319c2588 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -631,14 +631,6 @@ plugins/modules/database/misc/riak.py validate-modules:doc-missing-type plugins/modules/database/misc/riak.py validate-modules:parameter-type-not-in-doc plugins/modules/database/mssql/mssql_db.py validate-modules:doc-missing-type plugins/modules/database/mssql/mssql_db.py validate-modules:doc-required-mismatch -plugins/modules/database/mysql/mysql_db.py validate-modules:doc-elements-mismatch -plugins/modules/database/mysql/mysql_db.py validate-modules:parameter-list-no-elements -plugins/modules/database/mysql/mysql_db.py validate-modules:use-run-command-not-popen -plugins/modules/database/mysql/mysql_info.py validate-modules:doc-elements-mismatch -plugins/modules/database/mysql/mysql_info.py validate-modules:parameter-list-no-elements -plugins/modules/database/mysql/mysql_query.py validate-modules:parameter-list-no-elements -plugins/modules/database/mysql/mysql_user.py validate-modules:undocumented-parameter -plugins/modules/database/mysql/mysql_variables.py validate-modules:doc-required-mismatch plugins/modules/database/postgresql/postgresql_db.py use-argspec-type-path plugins/modules/database/postgresql/postgresql_db.py validate-modules:use-run-command-not-popen plugins/modules/database/postgresql/postgresql_privs.py validate-modules:parameter-documented-multiple-times diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index b865e42c86..d8319c2588 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -631,14 +631,6 @@ plugins/modules/database/misc/riak.py validate-modules:doc-missing-type plugins/modules/database/misc/riak.py validate-modules:parameter-type-not-in-doc plugins/modules/database/mssql/mssql_db.py validate-modules:doc-missing-type plugins/modules/database/mssql/mssql_db.py validate-modules:doc-required-mismatch -plugins/modules/database/mysql/mysql_db.py validate-modules:doc-elements-mismatch -plugins/modules/database/mysql/mysql_db.py validate-modules:parameter-list-no-elements -plugins/modules/database/mysql/mysql_db.py validate-modules:use-run-command-not-popen -plugins/modules/database/mysql/mysql_info.py validate-modules:doc-elements-mismatch -plugins/modules/database/mysql/mysql_info.py validate-modules:parameter-list-no-elements -plugins/modules/database/mysql/mysql_query.py validate-modules:parameter-list-no-elements -plugins/modules/database/mysql/mysql_user.py validate-modules:undocumented-parameter -plugins/modules/database/mysql/mysql_variables.py validate-modules:doc-required-mismatch plugins/modules/database/postgresql/postgresql_db.py use-argspec-type-path plugins/modules/database/postgresql/postgresql_db.py validate-modules:use-run-command-not-popen plugins/modules/database/postgresql/postgresql_privs.py validate-modules:parameter-documented-multiple-times diff --git a/tests/sanity/ignore-2.9.txt b/tests/sanity/ignore-2.9.txt index 28603a0d31..6cafa1d182 100644 --- a/tests/sanity/ignore-2.9.txt +++ b/tests/sanity/ignore-2.9.txt @@ -500,9 +500,6 @@ plugins/modules/database/misc/riak.py validate-modules:doc-default-does-not-matc plugins/modules/database/misc/riak.py validate-modules:doc-missing-type plugins/modules/database/misc/riak.py validate-modules:parameter-type-not-in-doc plugins/modules/database/mssql/mssql_db.py validate-modules:doc-missing-type -plugins/modules/database/mysql/mysql_db.py validate-modules:use-run-command-not-popen -plugins/modules/database/mysql/mysql_user.py validate-modules:parameter-type-not-in-doc -plugins/modules/database/mysql/mysql_user.py validate-modules:undocumented-parameter plugins/modules/database/postgresql/postgresql_db.py use-argspec-type-path plugins/modules/database/postgresql/postgresql_db.py validate-modules:parameter-type-not-in-doc plugins/modules/database/postgresql/postgresql_db.py validate-modules:use-run-command-not-popen