diff --git a/changelogs/fragments/fix_user_module_for_default_roles.yml b/changelogs/fragments/fix_user_module_for_default_roles.yml new file mode 100644 index 0000000..920438b --- /dev/null +++ b/changelogs/fragments/fix_user_module_for_default_roles.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - "mysql_user - fix a crash (unable to parse the MySQL grant string: SET DEFAULT ROLE `somerole` FOR `someuser`@`%`) when using the ``mysql_user`` module with a DEFAULT role present in MariaDB. The DEFAULT role is now ignored by the parser (https://github.com/ansible-collections/community.mysql/issues/710)." diff --git a/plugins/module_utils/user.py b/plugins/module_utils/user.py index 337cc67..59f9b01 100644 --- a/plugins/module_utils/user.py +++ b/plugins/module_utils/user.py @@ -665,12 +665,19 @@ def privileges_get(cursor, user, host, maria_role=False): res = re.match("""GRANT (.+) ON (.+) TO .*""", grant[0]) if res is None: - # If a user has roles assigned, we'll have one of priv tuples looking like + # If a user has roles or a default role assigned, + # we'll have some of the priv tuples looking either like # GRANT `admin`@`%` TO `user1`@`localhost` + # or + # SET DEFAULT ROLE `admin`@`%` FOR `user1`@`localhost` # which will result None as res value. # As we use the mysql_role module to manipulate roles # we just ignore such privs below: - res = re.match("""GRANT (.+) TO (['`"]).*""", grant[0]) + res = re.match( + """GRANT (.+) TO (['`"]).*|SET DEFAULT ROLE (.+) FOR (['`"]).*""", + grant[0] + ) + if not maria_role and res: continue diff --git a/tests/integration/targets/test_mysql_user/tasks/issue-710.yml b/tests/integration/targets/test_mysql_user/tasks/issue-710.yml new file mode 100644 index 0000000..7090f43 --- /dev/null +++ b/tests/integration/targets/test_mysql_user/tasks/issue-710.yml @@ -0,0 +1,43 @@ +--- +- vars: + mysql_parameters: &mysql_params + login_user: '{{ mysql_user }}' + login_password: '{{ mysql_password }}' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + + block: + - name: Issue-710 | Create user with DEFAULT privileges + community.mysql.mysql_user: + <<: *mysql_params + name: "{{ user_name_1 }}" + password: "{{ user_password_1 }}" + state: present + + - name: Issue-710 | Create role to use as default + community.mysql.mysql_role: + <<: *mysql_params + name: developers + state: present + priv: '*.*:ALL' + members: + - "{{ user_name_1 }}@localhost" + + - name: Issue-710 | Set default role for db_user1 + community.mysql.mysql_query: + <<: *mysql_params + query: >- + SET DEFAULT ROLE developers {{ (db_engine == 'mysql') | ternary('TO', 'FOR') }} {{ user_name_1 }}@localhost + + - name: Issue-710 | Ensure db_user1 can still be altered + community.mysql.mysql_user: + <<: *mysql_params + name: "{{ user_name_1 }}" + password: "{{ user_password_1 }}" + priv: '*.*:ALL' + state: present + + - name: Issue-710 | Ensure mysql_info can still be executed + community.mysql.mysql_info: + <<: *mysql_params + filter: users_info diff --git a/tests/integration/targets/test_mysql_user/tasks/main.yml b/tests/integration/targets/test_mysql_user/tasks/main.yml index 7212886..c69aea3 100644 --- a/tests/integration/targets/test_mysql_user/tasks/main.yml +++ b/tests/integration/targets/test_mysql_user/tasks/main.yml @@ -309,3 +309,7 @@ - name: Mysql_user - test user_locking ansible.builtin.import_tasks: file: test_user_locking.yml + + # Test that mysql_user still works with default role set + # (https://github.com/ansible-collections/community.mysql/issues/710) + - include_tasks: issue-710.yml