diff --git a/tests/integration/targets/test_mysql_role/defaults/main.yml b/tests/integration/targets/test_mysql_role/defaults/main.yml index 744ba34..53544bf 100644 --- a/tests/integration/targets/test_mysql_role/defaults/main.yml +++ b/tests/integration/targets/test_mysql_role/defaults/main.yml @@ -14,3 +14,4 @@ nonexistent: user3 role0: role0 role1: role1 +role2: role2 diff --git a/tests/integration/targets/test_mysql_role/tasks/main.yml b/tests/integration/targets/test_mysql_role/tasks/main.yml index 5bcd5ec..cf33276 100644 --- a/tests/integration/targets/test_mysql_role/tasks/main.yml +++ b/tests/integration/targets/test_mysql_role/tasks/main.yml @@ -5,3 +5,8 @@ # mysql_role module initial CI tests - import_tasks: mysql_role_initial.yml + +# Test that subtract_privs will only revoke the grants given by priv +# (https://github.com/ansible-collections/community.mysql/issues/331) +- include: test_priv_subtract.yml enable_check_mode=no +- include: test_priv_subtract.yml enable_check_mode=yes diff --git a/tests/integration/targets/test_mysql_role/tasks/test_priv_subtract.yml b/tests/integration/targets/test_mysql_role/tasks/test_priv_subtract.yml new file mode 100644 index 0000000..5152bdf --- /dev/null +++ b/tests/integration/targets/test_mysql_role/tasks/test_priv_subtract.yml @@ -0,0 +1,148 @@ +# Test code to ensure that subtracting privileges will not result in unnecessary changes. +- vars: + mysql_parameters: &mysql_params + login_user: '{{ mysql_user }}' + login_password: '{{ mysql_password }}' + login_host: 127.0.0.1 + login_port: '{{ mysql_primary_port }}' + + block: + + - name: Create test databases + mysql_db: + <<: *mysql_params + name: '{{ item }}' + state: present + loop: + - data1 + + - name: Create a role with an initial set of privileges + mysql_role: + <<: *mysql_params + name: '{{ role2 }}' + priv: 'data1.*:SELECT,INSERT' + state: present + + - name: Run command to show privileges for role (expect privileges in stdout) + command: "{{ mysql_command }} -e \"SHOW GRANTS FOR '{{ role2 }}'\"" + register: result + + - name: Assert that the initial set of privileges matches what is expected + assert: + that: + - "'GRANT SELECT, INSERT ON `data1`.*' in result.stdout" + + - name: Subtract privileges that are not in the current privileges, which should be a no-op + mysql_role: + <<: *mysql_params + name: '{{ role2 }}' + priv: 'data1.*:DELETE' + subtract_privs: yes + state: present + check_mode: '{{ enable_check_mode }}' + register: result + + - name: Assert that there wasn't a change in permissions + assert: + that: + - "result.changed == false" + + - name: Run command to show privileges for role (expect privileges in stdout) + command: "{{ mysql_command }} -e \"SHOW GRANTS FOR '{{ role2 }}'\"" + register: result + + - name: Assert that the permissions still match what was originally granted + assert: + that: + - "'GRANT SELECT, INSERT ON `data1`.*' in result.stdout" + + - name: Subtract existing and not-existing privileges, but not all + mysql_role: + <<: *mysql_params + name: '{{ role2 }}' + priv: 'data1.*:INSERT,DELETE' + subtract_privs: yes + state: present + check_mode: '{{ enable_check_mode }}' + register: result + + - name: Assert that there was a change because permissions were/would be revoked on data1.* + assert: + that: + - "result.changed == true" + + - name: Run command to show privileges for role (expect privileges in stdout) + command: "{{ mysql_command }} -e \"SHOW GRANTS FOR '{{ role2 }}'\"" + register: result + + - name: Assert that the permissions were not changed if check_mode is set to 'no' + assert: + that: + - "'GRANT SELECT, INSERT ON `data1`.*' in result.stdout" + when: enable_check_mode == 'no' + + - name: Assert that only DELETE was revoked if check_mode is set to 'yes' + assert: + that: + - "'GRANT SELECT ON `data1`.*' in result.stdout" + when: enable_check_mode == 'yes' + + - name: Try to subtract invalid privileges + mysql_role: + <<: *mysql_params + name: '{{ role2 }}' + priv: 'data1.*:INVALID' + subtract_privs: yes + state: present + check_mode: '{{ enable_check_mode }}' + register: result + ignore_errors: true + + - name: Assert that there wasn't a change in privileges if check_mode is set to 'no' + assert: + that: + - result is failed + - "'Error granting privileges' in result.msg" + when: enable_check_mode == 'no' + + - name: trigger failure by trying to subtract and append privileges at the same time + mysql_role: + <<: *mysql_params + name: '{{ role2 }}' + priv: 'data1.*:SELECT' + subtract_privs: yes + append_privs: yes + state: present + check_mode: '{{ enable_check_mode }}' + register: result + ignore_errors: true + + - name: Assert the previous execution failed + assert: + that: + - result is failed + + - name: Run command to show privileges for role (expect privileges in stdout) + command: "{{ mysql_command }} -e \"SHOW GRANTS FOR '{{ role2 }}'\"" + register: result + + - name: Assert that the permissions stayed the same + assert: + that: + - "'GRANT SELECT ON `data1`.*' in result.stdout" + + ########## + # Clean up + - name: Drop test databases + mysql_db: + <<: *mysql_params + name: '{{ item }}' + state: present + loop: + - data1 + + - name: Drop test role + mysql_role: + <<: *mysql_params + name: '{{ role2 }}' + state: absent diff --git a/tests/integration/targets/test_mysql_user/tasks/main.yml b/tests/integration/targets/test_mysql_user/tasks/main.yml index e949fe6..645ea6c 100644 --- a/tests/integration/targets/test_mysql_user/tasks/main.yml +++ b/tests/integration/targets/test_mysql_user/tasks/main.yml @@ -274,6 +274,11 @@ - include: test_priv_append.yml enable_check_mode=no - include: test_priv_append.yml enable_check_mode=yes + # Test that subtract_privs will only revoke the grants given by priv + # (https://github.com/ansible-collections/community.mysql/issues/331) + - include: test_priv_subtract.yml enable_check_mode=no + - include: test_priv_subtract.yml enable_check_mode=yes + # Tests for the TLS requires dictionary - include: tls_requirements.yml diff --git a/tests/integration/targets/test_mysql_user/tasks/test_priv_subtract.yml b/tests/integration/targets/test_mysql_user/tasks/test_priv_subtract.yml new file mode 100644 index 0000000..ee959c1 --- /dev/null +++ b/tests/integration/targets/test_mysql_user/tasks/test_priv_subtract.yml @@ -0,0 +1,153 @@ +# Test code to ensure that subtracting privileges will not result in unnecessary changes. +- vars: + mysql_parameters: &mysql_params + login_user: '{{ mysql_user }}' + login_password: '{{ mysql_password }}' + login_host: 127.0.0.1 + login_port: '{{ mysql_primary_port }}' + + block: + + - name: Create test databases + mysql_db: + <<: *mysql_params + name: '{{ item }}' + state: present + loop: + - data1 + + - name: Create a user with an initial set of privileges + mysql_user: + <<: *mysql_params + name: '{{ user_name_4 }}' + password: '{{ user_password_4 }}' + priv: 'data1.*:SELECT,INSERT' + state: present + + - name: Run command to show privileges for user (expect privileges in stdout) + command: "{{ mysql_command }} -e \"SHOW GRANTS FOR '{{ user_name_4 }}'@'localhost'\"" + register: result + + - name: Assert that the initial set of privileges matches what is expected + assert: + that: + - "'GRANT SELECT, INSERT ON `data1`.*' in result.stdout" + + - name: Subtract privileges that are not in the current privileges, which should be a no-op + mysql_user: + <<: *mysql_params + name: '{{ user_name_4 }}' + password: '{{ user_password_4 }}' + priv: 'data1.*:DELETE' + subtract_privs: yes + state: present + check_mode: '{{ enable_check_mode }}' + register: result + + - name: Assert that there wasn't a change in permissions + assert: + that: + - "result.changed == false" + + - name: Run command to show privileges for user (expect privileges in stdout) + command: "{{ mysql_command }} -e \"SHOW GRANTS FOR '{{ user_name_4 }}'@'localhost'\"" + register: result + + - name: Assert that the permissions still match what was originally granted + assert: + that: + - "'GRANT SELECT, INSERT ON `data1`.*' in result.stdout" + + - name: Subtract existing and not-existing privileges, but not all + mysql_user: + <<: *mysql_params + name: '{{ user_name_4 }}' + password: '{{ user_password_4 }}' + priv: 'data1.*:INSERT,DELETE' + subtract_privs: yes + state: present + check_mode: '{{ enable_check_mode }}' + register: result + + - name: Assert that there was a change because permissions were/would be revoked on data1.* + assert: + that: + - "result.changed == true" + + - name: Run command to show privileges for user (expect privileges in stdout) + command: "{{ mysql_command }} -e \"SHOW GRANTS FOR '{{ user_name_4 }}'@'localhost'\"" + register: result + + - name: Assert that the permissions were not changed if check_mode is set to 'no' + assert: + that: + - "'GRANT SELECT, INSERT ON `data1`.*' in result.stdout" + when: enable_check_mode == 'no' + + - name: Assert that only DELETE was revoked if check_mode is set to 'yes' + assert: + that: + - "'GRANT SELECT ON `data1`.*' in result.stdout" + when: enable_check_mode == 'yes' + + - name: Try to subtract invalid privileges + mysql_user: + <<: *mysql_params + name: '{{ user_name_4 }}' + password: '{{ user_password_4 }}' + priv: 'data1.*:INVALID' + subtract_privs: yes + state: present + check_mode: '{{ enable_check_mode }}' + register: result + ignore_errors: true + + - name: Assert that there wasn't a change in privileges if check_mode is set to 'no' + assert: + that: + - result is failed + - "'Error granting privileges' in result.msg" + when: enable_check_mode == 'no' + + - name: trigger failure by trying to subtract and append privileges at the same time + mysql_user: + <<: *mysql_params + name: '{{ user_name_4 }}' + password: '{{ user_password_4 }}' + priv: 'data1.*:SELECT' + subtract_privs: yes + append_privs: yes + state: present + check_mode: '{{ enable_check_mode }}' + register: result + ignore_errors: true + + - name: Assert the previous execution failed + assert: + that: + - result is failed + + - name: Run command to show privileges for user (expect privileges in stdout) + command: "{{ mysql_command }} -e \"SHOW GRANTS FOR '{{ user_name_4 }}'@'localhost'\"" + register: result + + - name: Assert that the permissions stayed the same + assert: + that: + - "'GRANT SELECT ON `data1`.*' in result.stdout" + + ########## + # Clean up + - name: Drop test databases + mysql_db: + <<: *mysql_params + name: '{{ item }}' + state: present + loop: + - data1 + + - name: Drop test user + mysql_user: + <<: *mysql_params + name: '{{ user_name_4 }}' + state: absent