From 4ae4e80cc3ef3c0995bb255f28c286d96d3c22e6 Mon Sep 17 00:00:00 2001 From: cosmix Date: Mon, 28 May 2018 15:01:55 +0300 Subject: [PATCH] Add support for mysqldump --ignore-table switch (#33065) * Add support for `mysqldump`'s `--ignore_table` switch. * Fix documentation and default linter warning re: default parameter * Add number to replacement field in cmd string * Bump version_added to 2.7 --- .../modules/database/mysql/mysql_db.py | 18 +++++++- .../mysql_db/tasks/state_dump_import.yml | 41 ++++++++++++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/lib/ansible/modules/database/mysql/mysql_db.py b/lib/ansible/modules/database/mysql/mysql_db.py index cd2e4240a8..7d8e91c647 100644 --- a/lib/ansible/modules/database/mysql/mysql_db.py +++ b/lib/ansible/modules/database/mysql/mysql_db.py @@ -56,6 +56,12 @@ options: type: bool default: 'yes' version_added: "2.1" + ignore_tables: + description: + - A list of table names that will be ignored in the dump of the form database_name.table_name + required: false + default: [] + version_added: "2.7" author: "Ansible Core Team" requirements: - mysql (command line binary) @@ -130,7 +136,7 @@ def db_delete(cursor, db): 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): + single_transaction=None, quick=None, ignore_tables=None): cmd = module.get_bin_path('mysqldump', True) # If defined, mysqldump demands --defaults-extra-file be the first option if config_file: @@ -157,6 +163,9 @@ def db_dump(module, host, user, password, db_name, target, all_databases, port, 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) path = None if os.path.splitext(target)[-1] == '.gz': @@ -264,6 +273,7 @@ def main(): config_file=dict(default="~/.my.cnf", type='path'), single_transaction=dict(default=False, type='bool'), quick=dict(default=True, type='bool'), + ignore_tables=dict(default=[], type='list') ), supports_check_mode=True ) @@ -288,6 +298,10 @@ def main(): login_password = module.params["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"] @@ -333,7 +347,7 @@ def main(): 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) + ssl_ca, single_transaction, quick, ignore_tables) if rc != 0: module.fail_json(msg="%s" % stderr) else: diff --git a/test/integration/targets/mysql_db/tasks/state_dump_import.yml b/test/integration/targets/mysql_db/tasks/state_dump_import.yml index a17e91b569..224032a74d 100644 --- a/test/integration/targets/mysql_db/tasks/state_dump_import.yml +++ b/test/integration/targets/mysql_db/tasks/state_dump_import.yml @@ -22,15 +22,54 @@ - name: state dump/import - create database mysql_db: name={{ db_name }} state=present +- 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: state dump without department table. + mysql_db: + name: "{{ db_name }}" + state: dump + target: "{{ db_file_name }}" + ignore_tables: + - "{{ db_name }}.department" + register: result + +- name: assert successful completion of dump operation + assert: + that: + - "result.changed == true" + +- name: state dump/import - file name should exist + file: name={{ db_file_name }} state=file + +- name: state dump/import - remove database + mysql_db: name={{ db_name }} state=absent + +- 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 }} + 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=dump to backup the database of type {{ format_type }} (expect changed=true) mysql_db: name={{ db_name }} state=dump target={{ db_file_name }} register: result @@ -41,7 +80,7 @@ - "result.changed == true" - "result.db =='{{ db_name }}'" -- name: assert database was backup successfully +- name: assert database was backed up successfully command: file {{ db_file_name }} register: result