From bf5086d19d377e6c2ad976aa43304bd34d1879ae Mon Sep 17 00:00:00 2001 From: betanummeric <40263343+betanummeric@users.noreply.github.com> Date: Fri, 27 May 2022 12:11:17 +0200 Subject: [PATCH] mysql_role: add argument "members_must_exist" (#369) * mysql_role: add argument "members_must_exist" (boolean, default true) The assertion that the users supplied in the "members" argument exist is only executed when the new argument "members_must_exist" is true, to allow opt-out. * mysql_role: add integration tests for argument members_must_exist * add changelog fragment * mysql_role: fix behavior of members_must_exist argument * Update plugins/modules/mysql_role.py Co-authored-by: Andrew Klychkov * Update changelogs/fragments/369_mysql_role-add-members_must_exist.yml Co-authored-by: Andrew Klychkov Co-authored-by: Felix Hamme Co-authored-by: Andrew Klychkov --- .../369_mysql_role-add-members_must_exist.yml | 4 ++ plugins/modules/mysql_role.py | 19 +++++- .../tasks/mysql_role_initial.yml | 65 +++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/369_mysql_role-add-members_must_exist.yml diff --git a/changelogs/fragments/369_mysql_role-add-members_must_exist.yml b/changelogs/fragments/369_mysql_role-add-members_must_exist.yml new file mode 100644 index 0000000..c2d420c --- /dev/null +++ b/changelogs/fragments/369_mysql_role-add-members_must_exist.yml @@ -0,0 +1,4 @@ +minor_changes: + - > + mysql_role - add the argument ``members_must_exist`` (boolean, default true). The assertion that the users supplied in + the ``members`` argument exist is only executed when the new argument ``members_must_exist`` is ``true``, to allow opt-out (https://github.com/ansible-collections/community.mysql/pull/369). diff --git a/plugins/modules/mysql_role.py b/plugins/modules/mysql_role.py index 8265f9a..97fabe8 100644 --- a/plugins/modules/mysql_role.py +++ b/plugins/modules/mysql_role.py @@ -114,6 +114,13 @@ options: type: bool default: no + members_must_exist: + description: + - When C(yes), the module fails if any user in I(members) does not exist. + - When C(no), users in I(members) which don't exist are simply skipped. + type: bool + default: yes + notes: - Pay attention that the module runs C(SET DEFAULT ROLE ALL TO) all the I(members) passed by default when the state has changed. @@ -382,6 +389,11 @@ class DbServer(): msg = 'User / role `%s` with host `%s` does not exist' % (user[0], user[1]) self.module.fail_json(msg=msg) + def filter_existing_users(self, users): + for user in users: + if user in self.users: + yield user + def __get_users(self): """Get users. @@ -918,6 +930,7 @@ def main(): detach_members=dict(type='bool', default=False), check_implicit_admin=dict(type='bool', default=False), set_default_role_all=dict(type='bool', default=True), + members_must_exist=dict(type='bool', default=True) ) module = AnsibleModule( argument_spec=argument_spec, @@ -951,6 +964,7 @@ def main(): check_hostname = module.params['check_hostname'] db = '' set_default_role_all = module.params['set_default_role_all'] + members_must_exist = module.params['members_must_exist'] if priv and not isinstance(priv, (str, dict)): msg = ('The "priv" parameter must be str or dict ' @@ -1019,7 +1033,10 @@ def main(): if members: members = normalize_users(module, members, server.is_mariadb()) - server.check_users_in_db(members) + if members_must_exist: + server.check_users_in_db(members) + else: + members = list(server.filter_existing_users(members)) # Main job starts here role = Role(module, cursor, name, server) diff --git a/tests/integration/targets/test_mysql_role/tasks/mysql_role_initial.yml b/tests/integration/targets/test_mysql_role/tasks/mysql_role_initial.yml index 95616df..8c81a75 100644 --- a/tests/integration/targets/test_mysql_role/tasks/mysql_role_initial.yml +++ b/tests/integration/targets/test_mysql_role/tasks/mysql_role_initial.yml @@ -1274,6 +1274,71 @@ that: - "'{{ role3 }}' not in result.query_result.0.0['Grants for {{ user1 }}@localhost']" + # test members_must_exist + - name: try failing on not-existing user in check-mode + <<: *task_params + mysql_role: + <<: *mysql_params + name: '{{ role0 }}' + state: present + members_must_exist: yes + append_members: yes + members: + - 'not_existent@localhost' + ignore_errors: yes + check_mode: yes + - name: assert failure + assert: + that: + - result is failed + + - name: try failing on not-existing user in check-mode + <<: *task_params + mysql_role: + <<: *mysql_params + name: '{{ role0 }}' + state: present + members_must_exist: no + append_members: yes + members: + - 'not_existent@localhost' + check_mode: yes + - name: Check for lack of change + assert: + that: + - result is not changed + + - name: try failing on not-existing user + <<: *task_params + mysql_role: + <<: *mysql_params + name: '{{ role0 }}' + state: present + members_must_exist: yes + append_members: yes + members: + - 'not_existent@localhost' + ignore_errors: yes + - name: assert failure + assert: + that: + - result is failed + + - name: try failing on not-existing user + <<: *task_params + mysql_role: + <<: *mysql_params + name: '{{ role0 }}' + state: present + members_must_exist: no + append_members: yes + members: + - 'not_existent@localhost' + - name: Check for lack of change + assert: + that: + - result is not changed + # ########## # Test privs # ##########