1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

mysql_db: add restrict_config_file parameter (#468)

* mysql_db: add restrict_config_file parameter

* add CI tests

* add changelog fragment
This commit is contained in:
Andrew Klychkov 2020-06-09 09:10:06 +03:00 committed by GitHub
parent 42c3d3aac7
commit 8d6d292358
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 7 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- mysql_db - add the ``restrict_config_file`` parameter (https://github.com/ansible/ansible/issues/34488).

View file

@ -120,6 +120,15 @@ options:
- Used only when I(state) is C(import) or C(dump) and I(login_password) is passed, ignored otherwise. - Used only when I(state) is C(import) or C(dump) and I(login_password) is passed, ignored otherwise.
type: bool type: bool
default: no default: no
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
seealso: seealso:
- module: mysql_info - module: mysql_info
@ -308,11 +317,14 @@ 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, config_file, socket=None, ssl_cert=None, ssl_key=None, ssl_ca=None,
single_transaction=None, quick=None, ignore_tables=None, hex_blob=None, single_transaction=None, quick=None, ignore_tables=None, hex_blob=None,
encoding=None, force=False, master_data=0, skip_lock_tables=False, encoding=None, force=False, master_data=0, skip_lock_tables=False,
dump_extra_args=None, unsafe_password=False): dump_extra_args=None, unsafe_password=False, restrict_config_file=False):
cmd = module.get_bin_path('mysqldump', True) cmd = module.get_bin_path('mysqldump', True)
# If defined, mysqldump demands --defaults-extra-file be the first option # If defined, mysqldump demands --defaults-extra-file be the first option
if config_file: if config_file:
cmd += " --defaults-extra-file=%s" % shlex_quote(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 user is not None: if user is not None:
cmd += " --user=%s" % shlex_quote(user) cmd += " --user=%s" % shlex_quote(user)
if password is not None: if password is not None:
@ -378,14 +390,17 @@ def db_dump(module, host, user, password, db_name, target, all_databases, port,
def db_import(module, host, user, password, db_name, target, all_databases, port, config_file, 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, socket=None, ssl_cert=None, ssl_key=None, ssl_ca=None, encoding=None, force=False,
use_shell=False, unsafe_password=False): use_shell=False, unsafe_password=False, restrict_config_file=False):
if not os.path.exists(target): if not os.path.exists(target):
return module.fail_json(msg="target %s does not exist on the host" % target) return module.fail_json(msg="target %s does not exist on the host" % target)
cmd = [module.get_bin_path('mysql', True)] cmd = [module.get_bin_path('mysql', True)]
# --defaults-file must go first, or errors out # --defaults-file must go first, or errors out
if config_file: if config_file:
cmd.append("--defaults-extra-file=%s" % shlex_quote(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 user: if user:
cmd.append("--user=%s" % shlex_quote(user)) cmd.append("--user=%s" % shlex_quote(user))
if password: if password:
@ -508,6 +523,7 @@ def main():
dump_extra_args=dict(type='str'), dump_extra_args=dict(type='str'),
use_shell=dict(type='bool', default=False), use_shell=dict(type='bool', default=False),
unsafe_login_password=dict(type='bool', default=False), unsafe_login_password=dict(type='bool', default=False),
restrict_config_file=dict(type='bool', default=False),
), ),
supports_check_mode=True, supports_check_mode=True,
) )
@ -549,6 +565,7 @@ def main():
skip_lock_tables = module.params["skip_lock_tables"] skip_lock_tables = module.params["skip_lock_tables"]
dump_extra_args = module.params["dump_extra_args"] dump_extra_args = module.params["dump_extra_args"]
use_shell = module.params["use_shell"] use_shell = module.params["use_shell"]
restrict_config_file = module.params["restrict_config_file"]
if len(db) > 1 and state == 'import': if len(db) > 1 and state == 'import':
module.fail_json(msg="Multiple databases are not supported with state=import") module.fail_json(msg="Multiple databases are not supported with state=import")
@ -616,7 +633,7 @@ def main():
login_port, config_file, socket, ssl_cert, ssl_key, login_port, config_file, socket, ssl_cert, ssl_key,
ssl_ca, single_transaction, quick, ignore_tables, ssl_ca, single_transaction, quick, ignore_tables,
hex_blob, encoding, force, master_data, skip_lock_tables, hex_blob, encoding, force, master_data, skip_lock_tables,
dump_extra_args, unsafe_login_password) dump_extra_args, unsafe_login_password, restrict_config_file)
if rc != 0: if rc != 0:
module.fail_json(msg="%s" % stderr) module.fail_json(msg="%s" % stderr)
module.exit_json(changed=True, db=db_name, db_list=db, msg=stdout, module.exit_json(changed=True, db=db_name, db_list=db, msg=stdout,
@ -635,7 +652,8 @@ def main():
all_databases, all_databases,
login_port, config_file, login_port, config_file,
socket, ssl_cert, ssl_key, ssl_ca, socket, ssl_cert, ssl_key, ssl_ca,
encoding, force, use_shell, unsafe_login_password) encoding, force, use_shell, unsafe_login_password,
restrict_config_file)
if rc != 0: if rc != 0:
module.fail_json(msg="%s" % stderr) module.fail_json(msg="%s" % stderr)
module.exit_json(changed=True, db=db_name, db_list=db, msg=stdout, module.exit_json(changed=True, db=db_name, db_list=db, msg=stdout,

View file

@ -24,6 +24,10 @@
dump_file2="{{tmp_dir}}/{{file3}}" dump_file2="{{tmp_dir}}/{{file3}}"
db_user="test" db_user="test"
db_user_unsafe_password="pass!word" 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 - name: create user for test unsafe_login_password parameter
mysql_user: mysql_user:
@ -81,13 +85,15 @@
master_data: 1 master_data: 1
skip_lock_tables: yes skip_lock_tables: yes
dump_extra_args: --skip-triggers dump_extra_args: --skip-triggers
config_file: '{{ config_file }}'
restrict_config_file: yes
register: result register: result
- name: assert successful completion of dump operation - name: assert successful completion of dump operation
assert: assert:
that: that:
- result is changed - result is changed
- result.executed_commands[0] is search("mysqldump --user={{ db_user }} --password=\*\*\*\*\*\*\*\* --force --socket={{ mysql_socket }} {{ db_name }} --skip-lock-tables --quick --ignore-table={{ db_name }}.department --master-data=1 --skip-triggers") - 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 - name: state dump/import - file name should exist
file: name={{ db_file_name }} state=file file: name={{ db_file_name }} state=file