forked from ansible-collections/community.mysql
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add default database "mysql" to mysql_user (ansible-collections#266)
* Add default database "mysql" to mysql_user Since permissions are stored in the "mysql" database anyway this should not change the behaviour of the module. But replication / binlog filters which rely on the current database will be able to filter the statements correctly afterwards. Prior to this change they were not executed in any database context and could not be filtered in any way by the existing methods in MySQL. * Added changelog fragment * Update changelogs/fragments/266-default-database-for-mysql-user Thanks! Co-authored-by: Andrew Klychkov <[email protected]> * Update mysql_user.py Make the change a configureable boolean * Update 266-default-database-for-mysql-user update changelog fragment * Update 266-default-database-for-mysql-user it´s not a bugfix anymore * Update plugins/modules/mysql_user.py Co-authored-by: Andrew Klychkov <[email protected]> * Update plugins/modules/mysql_user.py Co-authored-by: Andrew Klychkov <[email protected]> * Update plugins/modules/mysql_user.py Co-authored-by: Andrew Klychkov <[email protected]> * Update plugins/modules/mysql_user.py Co-authored-by: Andrew Klychkov <[email protected]> * renamed new option to force_context enhanced description added tests * fixed changelog * Update plugins/modules/mysql_user.py Co-authored-by: Andrew Klychkov <[email protected]> * Update plugins/modules/mysql_user.py Co-authored-by: Andrew Klychkov <[email protected]> * added more tests * removed first test attempts again (from issue-28.yml) created new tests for testing with and without replication * added force_context: no testing * forgot to add the new part to main.yml * found a copy&paste issue * fix include naming * Made sure the tests work in local testing * MariaDB handles online replication filters differently * fix changelog * Update changelogs/fragments/266-default-database-for-mysql-user.yml Co-authored-by: Andrew Klychkov <[email protected]> * Update changelogs/fragments/266-default-database-for-mysql-user.yml Co-authored-by: Andrew Klychkov <[email protected]> Co-authored-by: Andrew Klychkov <[email protected]>
- Loading branch information
1 parent
9c575b4
commit f5e8fbb
Showing
6 changed files
with
358 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
minor_changes: | ||
- mysql_user - added the ``force_context`` boolean option to set the default database context for the queries to be the ``mysql`` database. This way replication/binlog filters can catch the statements (https://github.com/ansible-collections/community.mysql/issues/265). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
165 changes: 165 additions & 0 deletions
165
tests/integration/targets/test_mysql_replication/tasks/issue-265.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
--- | ||
- name: alias mysql command to include default options | ||
set_fact: | ||
mysql_command: "mysql -u{{ mysql_user }} -p{{ mysql_password }} --protocol=tcp" | ||
|
||
- 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: | ||
|
||
# start replica so it is available for testing | ||
|
||
- name: Start replica | ||
mysql_replication: | ||
<<: *mysql_params | ||
login_port: '{{ mysql_replica1_port }}' | ||
mode: startreplica | ||
register: result | ||
|
||
- assert: | ||
that: | ||
- result is changed | ||
- result.queries == ["START SLAVE"] or result.queries == ["START REPLICA"] | ||
|
||
- name: Drop {{ user_name_1 }} if exists | ||
mysql_user: | ||
<<: *mysql_params | ||
name: '{{ user_name_1 }}' | ||
state: absent | ||
ignore_errors: yes | ||
|
||
# First test | ||
# check if user creation works with force_context and is replicated | ||
- name: create user with force_context | ||
mysql_user: | ||
<<: *mysql_params | ||
name: "{{ user_name_1 }}" | ||
password: "{{ user_password_1 }}" | ||
priv: '*.*:ALL,GRANT' | ||
force_context: yes | ||
|
||
- name: attempt connection on replica1 with newly created user (expect success) | ||
mysql_replication: | ||
mode: getprimary | ||
login_user: '{{ user_name_1 }}' | ||
login_password: '{{ user_password_1 }}' | ||
login_host: 127.0.0.1 | ||
login_port: '{{ mysql_replica1_port }}' | ||
register: result | ||
ignore_errors: yes | ||
|
||
- assert: | ||
that: | ||
- result is succeeded | ||
|
||
- name: Drop user | ||
mysql_user: | ||
<<: *mysql_params | ||
name: '{{ user_name_1 }}' | ||
state: absent | ||
force_context: yes | ||
|
||
- name: attempt connection on replica with freshly removed user (expect failure) | ||
mysql_replication: | ||
mode: getprimary | ||
login_user: '{{ user_name_1 }}' | ||
login_password: '{{ user_password_1 }}' | ||
login_host: 127.0.0.1 | ||
login_port: '{{ mysql_replica1_port }}' | ||
register: result | ||
ignore_errors: yes | ||
|
||
- assert: | ||
that: | ||
- result is failed | ||
|
||
# Prepare replica1 for testing with a replication filter in place | ||
# Stop replication, create a filter and restart replication on replica1. | ||
- name: Stop replica | ||
mysql_replication: | ||
<<: *mysql_params | ||
login_port: '{{ mysql_replica1_port }}' | ||
mode: stopreplica | ||
register: result | ||
|
||
- assert: | ||
that: | ||
- result is changed | ||
- result.queries == ["STOP SLAVE"] or result.queries == ["STOP REPLICA"] | ||
|
||
- name: Create replication filter MySQL | ||
shell: "echo \"CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB = (mysql);\" | {{ mysql_command }} -P{{ mysql_replica1_port }}" | ||
when: install_type == 'mysql' | ||
|
||
- name: Create replication filter MariaDB | ||
shell: "echo \"SET GLOBAL replicate_ignore_db = 'mysql';\" | {{ mysql_command }} -P{{ mysql_replica1_port }}" | ||
when: install_type == 'mariadb' | ||
|
||
- name: Start replica | ||
mysql_replication: | ||
<<: *mysql_params | ||
login_port: '{{ mysql_replica1_port }}' | ||
mode: startreplica | ||
register: result | ||
|
||
- assert: | ||
that: | ||
- result is changed | ||
- result.queries == ["START SLAVE"] or result.queries == ["START REPLICA"] | ||
|
||
# Second test | ||
# Filter in place, ready to test if user creation is filtered with force_context | ||
- name: create user with force_context | ||
mysql_user: | ||
<<: *mysql_params | ||
name: "{{ user_name_1 }}" | ||
password: "{{ user_password_1 }}" | ||
priv: '*.*:ALL,GRANT' | ||
force_context: yes | ||
|
||
- name: attempt connection on replica with newly created user (expect failure) | ||
mysql_replication: | ||
mode: getprimary | ||
login_user: '{{ user_name_1 }}' | ||
login_password: '{{ user_password_1 }}' | ||
login_host: 127.0.0.1 | ||
login_port: '{{ mysql_replica1_port }}' | ||
register: result | ||
ignore_errors: yes | ||
|
||
- assert: | ||
that: | ||
- result is failed | ||
|
||
- name: Drop user | ||
mysql_user: | ||
<<: *mysql_params | ||
name: '{{ user_name_1 }}' | ||
state: absent | ||
force_context: yes | ||
|
||
# restore normal replica1 operation | ||
# Stop replication and remove the filter | ||
- name: Stop replica | ||
mysql_replication: | ||
<<: *mysql_params | ||
login_port: '{{ mysql_replica1_port }}' | ||
mode: stopreplica | ||
register: result | ||
|
||
- assert: | ||
that: | ||
- result is changed | ||
- result.queries == ["STOP SLAVE"] or result.queries == ["STOP REPLICA"] | ||
|
||
- name: Remove replication filter MySQL | ||
shell: "echo \"CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB = ();\" | {{ mysql_command }} -P{{ mysql_replica1_port }}" | ||
when: install_type == 'mysql' | ||
|
||
- name: Remove replication filter MariaDB | ||
shell: "echo \"SET GLOBAL replicate_ignore_db = '';\" | {{ mysql_command }} -P{{ mysql_replica1_port }}" | ||
when: install_type == 'mariadb' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
168 changes: 168 additions & 0 deletions
168
tests/integration/targets/test_mysql_user/tasks/issue-265.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
--- | ||
- 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: Drop mysql user if exists | ||
mysql_user: | ||
<<: *mysql_params | ||
name: '{{ user_name_1 }}' | ||
state: absent | ||
ignore_errors: yes | ||
|
||
# Tests with force_context: yes | ||
# Test user creation | ||
- name: create mysql user {{user_name_1}} | ||
mysql_user: | ||
<<: *mysql_params | ||
name: '{{ user_name_1 }}' | ||
password: '{{ user_password_1 }}' | ||
state: present | ||
force_context: yes | ||
register: result | ||
|
||
- name: assert output message mysql user was created | ||
assert: | ||
that: | ||
- "result.changed == true" | ||
|
||
- include: assert_user.yml user_name={{user_name_1}} | ||
|
||
# Test user removal | ||
- name: remove mysql user {{user_name_1}} | ||
mysql_user: | ||
<<: *mysql_params | ||
name: '{{user_name_1}}' | ||
password: '{{user_password_1}}' | ||
state: absent | ||
force_context: yes | ||
register: result | ||
|
||
- name: assert output message mysql user was removed | ||
assert: | ||
that: | ||
- "result.changed == true" | ||
|
||
# Test blank user removal | ||
- name: create blank mysql user to be removed later | ||
mysql_user: | ||
<<: *mysql_params | ||
name: "" | ||
state: present | ||
force_context: yes | ||
password: 'KJFDY&D*Sfuydsgf' | ||
|
||
- name: remove blank mysql user with hosts=all (expect changed) | ||
mysql_user: | ||
<<: *mysql_params | ||
user: "" | ||
host_all: true | ||
state: absent | ||
force_context: yes | ||
register: result | ||
|
||
- name: assert changed is true for removing all blank users | ||
assert: | ||
that: | ||
- "result.changed == true" | ||
|
||
- name: remove blank mysql user with hosts=all (expect ok) | ||
mysql_user: | ||
<<: *mysql_params | ||
user: "" | ||
host_all: true | ||
force_context: yes | ||
state: absent | ||
register: result | ||
|
||
- name: assert changed is true for removing all blank users | ||
assert: | ||
that: | ||
- "result.changed == false" | ||
|
||
- include: assert_no_user.yml user_name={{user_name_1}} | ||
|
||
# Tests with force_context: no | ||
# Test user creation | ||
- name: Drop mysql user if exists | ||
mysql_user: | ||
<<: *mysql_params | ||
name: '{{ user_name_1 }}' | ||
state: absent | ||
ignore_errors: yes | ||
|
||
# Tests with force_context: yes | ||
# Test user creation | ||
- name: create mysql user {{user_name_1}} | ||
mysql_user: | ||
<<: *mysql_params | ||
name: '{{ user_name_1 }}' | ||
password: '{{ user_password_1 }}' | ||
state: present | ||
force_context: yes | ||
register: result | ||
|
||
- name: assert output message mysql user was created | ||
assert: | ||
that: | ||
- "result.changed == true" | ||
|
||
- include: assert_user.yml user_name={{user_name_1}} | ||
|
||
# Test user removal | ||
- name: remove mysql user {{user_name_1}} | ||
mysql_user: | ||
<<: *mysql_params | ||
name: '{{user_name_1}}' | ||
password: '{{user_password_1}}' | ||
state: absent | ||
force_context: no | ||
register: result | ||
|
||
- name: assert output message mysql user was removed | ||
assert: | ||
that: | ||
- "result.changed == true" | ||
|
||
# Test blank user removal | ||
- name: create blank mysql user to be removed later | ||
mysql_user: | ||
<<: *mysql_params | ||
name: "" | ||
state: present | ||
force_context: no | ||
password: 'KJFDY&D*Sfuydsgf' | ||
|
||
- name: remove blank mysql user with hosts=all (expect changed) | ||
mysql_user: | ||
<<: *mysql_params | ||
user: "" | ||
host_all: true | ||
state: absent | ||
force_context: no | ||
register: result | ||
|
||
- name: assert changed is true for removing all blank users | ||
assert: | ||
that: | ||
- "result.changed == true" | ||
|
||
- name: remove blank mysql user with hosts=all (expect ok) | ||
mysql_user: | ||
<<: *mysql_params | ||
user: "" | ||
host_all: true | ||
force_context: no | ||
state: absent | ||
register: result | ||
|
||
- name: assert changed is true for removing all blank users | ||
assert: | ||
that: | ||
- "result.changed == false" | ||
|
||
- include: assert_no_user.yml user_name={{user_name_1}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters