From 4100f4ba0ed5292b036a769b173118329ab256f1 Mon Sep 17 00:00:00 2001 From: Steve Teahan <75569952+steveteahan@users.noreply.github.com> Date: Tue, 29 Dec 2020 08:29:35 -0500 Subject: [PATCH] mysql_user: fixed encrypted option for MySQL 8.0 and test coverage The purpose of this change was originally to expand test coverage to unblock #76, but an issue was detected with the encrypted parameter on MySQL 8.0 in the process of writing the tests. Additionally, user_password_update_test.yml had been disabled at some point, so I opted to replace it with two new files that will focus on the password and plugin auth paths. --- .../79-mysql-user-tests-and-fixes.yml | 2 + plugins/module_utils/mysql.py | 8 + plugins/modules/mysql_user.py | 20 +- .../targets/test_mysql_user/tasks/main.yml | 10 +- .../tasks/test_user_password.yml | 269 ++++++++++++++++++ .../tasks/test_user_plugin_auth.yml | 242 ++++++++++++++++ .../tasks/user_password_update_test.yml | 178 ------------ 7 files changed, 545 insertions(+), 184 deletions(-) create mode 100644 changelogs/fragments/79-mysql-user-tests-and-fixes.yml create mode 100644 tests/integration/targets/test_mysql_user/tasks/test_user_password.yml create mode 100644 tests/integration/targets/test_mysql_user/tasks/test_user_plugin_auth.yml delete mode 100644 tests/integration/targets/test_mysql_user/tasks/user_password_update_test.yml diff --git a/changelogs/fragments/79-mysql-user-tests-and-fixes.yml b/changelogs/fragments/79-mysql-user-tests-and-fixes.yml new file mode 100644 index 0000000..c9871f8 --- /dev/null +++ b/changelogs/fragments/79-mysql-user-tests-and-fixes.yml @@ -0,0 +1,2 @@ +bugfixes: +- mysql_user - fixed creating user with encrypted password in MySQL 8.0 (https://github.com/ansible-collections/community.mysql/pull/79). diff --git a/plugins/module_utils/mysql.py b/plugins/module_utils/mysql.py index 09e0338..8c59904 100644 --- a/plugins/module_utils/mysql.py +++ b/plugins/module_utils/mysql.py @@ -10,6 +10,8 @@ # Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) from __future__ import (absolute_import, division, print_function) + +from distutils.version import LooseVersion from functools import reduce __metaclass__ = type @@ -133,3 +135,9 @@ def mysql_common_argument_spec(): ca_cert=dict(type='path', aliases=['ssl_ca']), check_hostname=dict(type='bool', default=None), ) + + +def get_server_version(cursor): + cursor.execute("SELECT VERSION()") + version_str = cursor.fetchone()[0] + return LooseVersion(version_str) diff --git a/plugins/modules/mysql_user.py b/plugins/modules/mysql_user.py index 3f1f941..53e60a1 100644 --- a/plugins/modules/mysql_user.py +++ b/plugins/modules/mysql_user.py @@ -8,7 +8,6 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type - DOCUMENTATION = r''' --- module: mysql_user @@ -299,10 +298,13 @@ RETURN = '''#''' import re import string +from distutils.version import LooseVersion from ansible.module_utils.basic import AnsibleModule from ansible_collections.community.mysql.plugins.module_utils.database import SQLParseError -from ansible_collections.community.mysql.plugins.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg, mysql_common_argument_spec +from ansible_collections.community.mysql.plugins.module_utils.mysql import ( + mysql_connect, mysql_driver, mysql_driver_fail_msg, mysql_common_argument_spec, get_server_version +) from ansible.module_utils.six import iteritems from ansible.module_utils._text import to_native @@ -475,7 +477,19 @@ def user_add(cursor, user, host, host_all, password, encrypted, mogrify = do_not_mogrify_requires if old_user_mgmt else mogrify_requires if password and encrypted: - cursor.execute(*mogrify("CREATE USER %s@%s IDENTIFIED BY PASSWORD %s", (user, host, password), tls_requires)) + server_version = get_server_version(cursor) + + # The IDENTIFIED BY PASSWORD syntax was dropped in MySQL 8.0, but appears to be supported by MariaDB 10.x. + if server_version < LooseVersion("8") or server_version > LooseVersion("10"): + cursor.execute(*mogrify("CREATE USER %s@%s IDENTIFIED BY PASSWORD %s", (user, host, password), tls_requires)) + else: + cursor.execute( + *mogrify( + "CREATE USER %s@%s IDENTIFIED WITH mysql_native_password AS %s", (user, host, password), + tls_requires + ) + ) + elif password and not encrypted: if old_user_mgmt: cursor.execute(*mogrify("CREATE USER %s@%s IDENTIFIED BY %s", (user, host, password), tls_requires)) diff --git a/tests/integration/targets/test_mysql_user/tasks/main.yml b/tests/integration/targets/test_mysql_user/tasks/main.yml index 4e1aa71..a744050 100644 --- a/tests/integration/targets/test_mysql_user/tasks/main.yml +++ b/tests/integration/targets/test_mysql_user/tasks/main.yml @@ -233,10 +233,14 @@ - include: remove_user.yml user_name={{user_name_1}} user_password={{ user_password_1 }} # ============================================================ - # Update user password for a user. - # Assert the user password is updated and old password can no longer be used. + # Test plaintext and encrypted password scenarios. # - #- include: user_password_update_test.yml + - include: test_user_password.yml + + # ============================================================ + # Test plugin authentication scenarios. + # + - include: test_user_plugin_auth.yml # ============================================================ # Assert create user with SELECT privileges, attempt to create database and update privileges to create database diff --git a/tests/integration/targets/test_mysql_user/tasks/test_user_password.yml b/tests/integration/targets/test_mysql_user/tasks/test_user_password.yml new file mode 100644 index 0000000..f3b0e06 --- /dev/null +++ b/tests/integration/targets/test_mysql_user/tasks/test_user_password.yml @@ -0,0 +1,269 @@ +# Tests scenarios for both plaintext and encrypted user passwords. + +- vars: + mysql_parameters: &mysql_params + login_user: '{{ mysql_user }}' + login_password: '{{ mysql_password }}' + login_host: 127.0.0.1 + login_port: '{{ mysql_primary_port }}' + test_user_name: 'test_user_password' + initial_password: 'a5C8SN*DBa0%a75sGz' + initial_password_encrypted: '*0A12D4DF68C2A50716111674E565CA3D7D68B048' + new_password: 'NkN&qECv33vuQzf3bJg' + new_password_encrypted: '*B6559186FAD0953589F54383AD8EE9E9172296DA' + test_default_priv_type: 'SELECT' + test_default_priv: '*.*:{{ test_default_priv_type }}' + + block: + + # ============================================================ + # Test setting plaintext password and changing it. + # + + - name: Create user with initial password + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + password: '{{ initial_password }}' + priv: '{{ test_default_priv }}' + state: present + register: result + + - name: Assert that a change occurred because the user was added + assert: + that: + - "result.changed == true" + + - include: assert_user.yml user_name={{ test_user_name }} priv={{ test_default_priv_type }} + + - name: Get the MySQL version using the newly created used creds + mysql_info: + login_user: '{{ test_user_name }}' + login_password: '{{ initial_password }}' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + ignore_errors: true + + - name: Assert that mysql_info was successful + assert: + that: + - "result.failed == false" + + - name: Run mysql_user again without any changes + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + password: '{{ initial_password }}' + priv: '{{ test_default_priv }}' + state: present + register: result + + - name: Assert that there weren't any changes because username/password didn't change + assert: + that: + - "result.changed == false" + + - include: assert_user.yml user_name={{ test_user_name }} priv={{ test_default_priv_type }} + + - name: Update the user password + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + password: '{{ new_password }}' + state: present + register: result + + - name: Assert that a change occurred because the password was updated + assert: + that: + - "result.changed == true" + + - include: assert_user.yml user_name={{ test_user_name }} priv={{ test_default_priv_type }} + + - name: Get the MySQL version data using the original password (should fail) + mysql_info: + login_user: '{{ test_user_name }}' + login_password: '{{ initial_password }}' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + ignore_errors: true + + - name: Assert that the mysql_info module failed because we used the old password + assert: + that: + - "result.failed == true" + + - name: Get the MySQL version data using the new password (should work) + mysql_info: + login_user: '{{ test_user_name }}' + login_password: '{{ new_password }}' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + ignore_errors: true + + - name: Assert that the mysql_info module succeeded because we used the new password + assert: + that: + - "result.failed == false" + + # Cleanup + - include: remove_user.yml user_name={{ test_user_name }} user_password={{ new_password }} + + # ============================================================ + # Test setting a plaintext password and then the same password encrypted to ensure there isn't a change detected. + # + + - name: Create user with initial password + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + password: '{{ initial_password }}' + priv: '{{ test_default_priv }}' + state: present + register: result + + - name: Assert that a change occurred because the user was added + assert: + that: + - "result.changed == true" + + - include: assert_user.yml user_name={{ test_user_name }} priv={{ test_default_priv_type }} + + - name: Pass in the same password as before, but in the encrypted form (no change expected) + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + password: '{{ initial_password_encrypted }}' + encrypted: yes + priv: '{{ test_default_priv }}' + state: present + register: result + + - name: Assert that there weren't any changes because username/password didn't change + assert: + that: + - "result.changed == false" + + # Cleanup + - include: remove_user.yml user_name={{ test_user_name }} user_password={{ new_password }} + + # ============================================================ + # Test setting an encrypted password and then the same password in plaintext to ensure there isn't a change. + # + + - name: Create user with initial password + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + password: '{{ initial_password_encrypted }}' + encrypted: yes + priv: '{{ test_default_priv }}' + state: present + register: result + + - name: Assert that a change occurred because the user was added + assert: + that: + - "result.changed == true" + + - include: assert_user.yml user_name={{ test_user_name }} priv={{ test_default_priv_type }} + + - name: Get the MySQL version data using the new creds + mysql_info: + login_user: '{{ test_user_name }}' + login_password: '{{ initial_password }}' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + ignore_errors: true + + - name: Assert that the mysql_info module succeeded because we used the new password + assert: + that: + - "result.failed == false" + + - name: Pass in the same password as before, but in the encrypted form (no change expected) + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + password: '{{ initial_password }}' + state: present + register: result + + - name: Assert that there weren't any changes because username/password didn't change + assert: + that: + - "result.changed == false" + + # Cleanup + - include: remove_user.yml user_name={{ test_user_name }} user_password={{ new_password }} + + # ============================================================ + # Test setting an empty password. + # + + - name: Create user with empty password + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + priv: '{{ test_default_priv }}' + state: present + register: result + + - name: Assert that a change occurred because the user was added + assert: + that: + - "result.changed == true" + + - name: Get the MySQL version using an empty password for the newly created user + mysql_info: + login_user: '{{ test_user_name }}' + login_password: '' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + ignore_errors: true + + - name: Assert that mysql_info was successful + assert: + that: + - "result.failed == false" + + - name: Get the MySQL version using an non-empty password (should fail) + mysql_info: + login_user: '{{ test_user_name }}' + login_password: 'some_password' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + ignore_errors: true + + - name: Assert that mysql_info failed + assert: + that: + - "result.failed == true" + + - name: Update the user without changing the password + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + priv: '{{ test_default_priv }}' + state: present + register: result + + - name: Assert that the user wasn't changed because the password is still empty + assert: + that: + - "result.changed == false" + + # Cleanup + - include: remove_user.yml user_name={{ test_user_name }} user_password='' diff --git a/tests/integration/targets/test_mysql_user/tasks/test_user_plugin_auth.yml b/tests/integration/targets/test_mysql_user/tasks/test_user_plugin_auth.yml new file mode 100644 index 0000000..da99c11 --- /dev/null +++ b/tests/integration/targets/test_mysql_user/tasks/test_user_plugin_auth.yml @@ -0,0 +1,242 @@ +# Test user plugin auth scenarios. + +- vars: + mysql_parameters: &mysql_params + login_user: '{{ mysql_user }}' + login_password: '{{ mysql_password }}' + login_host: 127.0.0.1 + login_port: '{{ mysql_primary_port }}' + test_user_name: 'test_user_plugin_auth' + test_plugin_type: 'mysql_native_password' + test_plugin_hash: '*0CB5B86F23FDC24DB19A29B8854EB860CBC47793' + test_plugin_auth_string: 'Fdt8fd^34ds' + test_default_priv_type: 'SELECT' + test_default_priv: '*.*:{{ test_default_priv_type }}' + + block: + + # ============================================================ + # Test plugin auth initially setting a hash and then switching to a plaintext auth string. + # + + - name: Create user with plugin auth (with hash string) + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + plugin: '{{ test_plugin_type }}' + plugin_hash_string: '{{ test_plugin_hash }}' + priv: '{{ test_default_priv }}' + register: result + + - name: Check that the module made a change + assert: + that: + - "result.changed == true" + + - include: assert_user.yml user_name={{ test_user_name }} priv={{ test_default_priv_type }} + + - name: Get the MySQL version using the newly created creds + mysql_info: + login_user: '{{ test_user_name }}' + login_password: '{{ test_plugin_auth_string }}' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + + - name: Assert that mysql_info was successful + assert: + that: + - "result.failed == false" + + - name: Update the user with the same hash (no change expected) + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + plugin: '{{ test_plugin_type }}' + plugin_hash_string: '{{ test_plugin_hash }}' + register: result + + - name: Check that the module doesn't make a change when the same hash is passed in + assert: + that: + - "result.changed == false" + + - include: assert_user.yml user_name={{ test_user_name }} priv={{ test_default_priv_type }} + + - name: Change the user using the same plugin, but switch to the same auth string in plaintext form + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + plugin: '{{ test_plugin_type }}' + plugin_auth_string: '{{ test_plugin_auth_string }}' + register: result + + # Expecting a change is currently by design (see comment in source). + - name: Check that the module did not change the password + assert: + that: + - "result.changed == true" + + - name: Getting the MySQL info should still work + mysql_info: + login_user: '{{ test_user_name }}' + login_password: '{{ test_plugin_auth_string }}' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + + - name: Assert that mysql_info was successful + assert: + that: + - "result.failed == false" + + # Cleanup + - include: remove_user.yml user_name={{ test_user_name }} user_password={{ test_plugin_auth_string }} + + # ============================================================ + # Test plugin auth initially setting a plaintext auth string and then switching to a plaintext auth string. + # + + - name: Create user with plugin auth (with auth string) + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + plugin: '{{ test_plugin_type }}' + plugin_auth_string: '{{ test_plugin_auth_string }}' + priv: '{{ test_default_priv }}' + register: result + + - name: Check that the module made a change + assert: + that: + - "result.changed == true" + + - include: assert_user.yml user_name={{ test_user_name }} priv={{ test_default_priv_type }} + + - name: Get the MySQL version using the newly created creds + mysql_info: + login_user: '{{ test_user_name }}' + login_password: '{{ test_plugin_auth_string }}' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + + - name: Assert that mysql_info was successful + assert: + that: + - "result.failed == false" + + - name: Update the user with the same auth string + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + plugin: '{{ test_plugin_type }}' + plugin_auth_string: '{{ test_plugin_auth_string }}' + register: result + + # This is the current expected behavior because there isn't a reliable way to hash the password in the mysql_user + # module in order to be able to compare this password with the stored hash. See the source for more info. + - name: The module should detect a change even though the password is the same + assert: + that: + - "result.changed == true" + + - include: assert_user.yml user_name={{ test_user_name }} priv={{ test_default_priv_type }} + + - name: Change the user using the same plugin, but switch to the same auth string in hash form + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + plugin: '{{ test_plugin_type }}' + plugin_hash_string: '{{ test_plugin_hash }}' + register: result + + - name: Check that the module did not change the password + assert: + that: + - "result.changed == false" + + - name: Get the MySQL version using the newly created creds + mysql_info: + login_user: '{{ test_user_name }}' + login_password: '{{ test_plugin_auth_string }}' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + + - name: Assert that mysql_info was successful + assert: + that: + - "result.failed == false" + + # Cleanup + - include: remove_user.yml user_name={{ test_user_name }} user_password={{ test_plugin_auth_string }} + + # ============================================================ + # Test plugin auth with an empty auth string. + # + + - name: Create user with plugin auth (empty auth string) + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + plugin: '{{ test_plugin_type }}' + priv: '{{ test_default_priv }}' + register: result + + - name: Check that the module made a change + assert: + that: + - "result.changed == true" + + - include: assert_user.yml user_name={{ test_user_name }} priv={{ test_default_priv_type }} + + - name: Get the MySQL version using an empty password for the newly created user + mysql_info: + login_user: '{{ test_user_name }}' + login_password: '' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + ignore_errors: true + + - name: Assert that mysql_info was successful + assert: + that: + - "result.failed == false" + + - name: Get the MySQL version using an non-empty password (should fail) + mysql_info: + login_user: '{{ test_user_name }}' + login_password: 'some_password' + login_host: '{{ mysql_host }}' + login_port: '{{ mysql_primary_port }}' + filter: version + register: result + ignore_errors: true + + - name: Assert that mysql_info failed + assert: + that: + - "result.failed == true" + + - name: Update the user without changing the auth mechanism + mysql_user: + <<: *mysql_params + name: '{{ test_user_name }}' + plugin: '{{ test_plugin_type }}' + state: present + register: result + + - name: Assert that the user wasn't changed because the auth string is still empty + assert: + that: + - "result.changed == false" + + # Cleanup + - include: remove_user.yml user_name={{ test_user_name }} user_password={{ test_plugin_auth_string }} diff --git a/tests/integration/targets/test_mysql_user/tasks/user_password_update_test.yml b/tests/integration/targets/test_mysql_user/tasks/user_password_update_test.yml deleted file mode 100644 index d893924..0000000 --- a/tests/integration/targets/test_mysql_user/tasks/user_password_update_test.yml +++ /dev/null @@ -1,178 +0,0 @@ -# test code update password for the mysql_user module -# (c) 2014, Wayne Rosario - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 dof the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -- 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: - - # ============================================================ - # Update user password for a user. - # Assert the user password is updated and old password can no longer be used. - # - - name: create user1 state=present with a password - mysql_user: - <<: *mysql_params - name: '{{ user_name_1 }}' - password: '{{ user_password_1 }}' - priv: '*.*:ALL' - state: present - - - name: create user2 state=present with a password - mysql_user: - <<: *mysql_params - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - priv: '*.*:ALL' - state: present - - - name: store user2 grants with old password (mysql 5.7.6 and newer) - command: "{{ mysql_command }} -e \"SHOW CREATE USER '{{ user_name_2 }}'@'localhost'\"" - register: user_password_old_create - ignore_errors: yes - - - name: store user2 grants with old password (mysql 5.7.5 and older) - command: "{{ mysql_command }} -e \"SHOW GRANTS FOR '{{ user_name_2 }}'@'localhost'\"" - register: user_password_old - when: user_password_old_create is failed - - - name: update user2 state=present with same password (expect changed=false) - mysql_user: - <<: *mysql_params - name: '{{ user_name_2 }}' - password: '{{ user_password_2 }}' - priv: '*.*:ALL' - state: present - register: result - - - name: assert output user2 was not updated - assert: - that: - - "result.changed == false" - - - include: assert_user.yml user_name={{user_name_2}} priv='ALL PRIVILEGES' - - - name: update user2 state=present with a new password (expect changed=true) - mysql_user: - <<: *mysql_params - name: '{{ user_name_2 }}' - password: '{{ user_password_1 }}' - state: present - register: result - - - include: assert_user.yml user_name={{user_name_2}} priv='ALL PRIVILEGES' - - - name: store user2 grants with old password (mysql 5.7.6 and newer) - command: "{{ mysql_command }} -e \"SHOW CREATE USER '{{ user_name_2 }}'@'localhost'\"" - register: user_password_new_create - ignore_errors: yes - - - name: store user2 grants with new password - command: "{{ mysql_command }} -e SHOW GRANTS FOR '{{ user_name_2 }}'@'localhost'\"" - register: user_password_new - when: user_password_new_create is failed - - - name: assert output message password was update for user2 (mysql 5.7.6 and newer) - assert: - that: - - "user_password_old_create.stdout != user_password_new_create.stdout" - when: user_password_new_create is not failed - - - name: assert output message password was update for user2 (mysql 5.7.5 and older) - assert: - that: - - "user_password_old.stdout != user_password_new.stdout" - when: user_password_new_create is failed - - - name: create database using user2 and old password - mysql_db: - login_user: '{{ user_name_2 }}' - login_password: '{{ user_password_2 }}' - login_host: '{{ mysql_host }}' - login_port: '{{ mysql_primary_port }}' - name: '{{ db_name }}' - state: present - ignore_errors: true - register: result - - - debug: var=result.msg - - name: assert output message that database not create with old password - assert: - that: - - "result.failed == true" - - - name: create database using user2 and new password - mysql_db: - login_user: '{{ user_name_2 }}' - login_password: '{{ user_password_1 }}' - login_host: '{{ mysql_host }}' - login_port: '{{ mysql_primary_port }}' - name: '{{ db_name }}' - state: present - register: result - - - name: assert output message that database is created with new password - assert: - that: - - "result.changed == true" - - - name: remove database - mysql_db: - <<: *mysql_params - name: '{{ db_name }}' - state: absent - login_unix_socket: '{{ mysql_socket }}' - - - include: remove_user.yml user_name={{user_name_1}} user_password={{ user_password_1 }} - - - include: remove_user.yml user_name={{user_name_2}} user_password={{ user_password_1 }} - - - name: Create user with Fdt8fd^34ds using hash. (expect changed=true) - mysql_user: - <<: *mysql_params - name: jmainguy - password: '*0cb5b86f23fdc24db19a29b8854eb860cbc47793' - encrypted: yes - register: encrypt_result - - - name: Check that the module made a change - assert: - that: - - "encrypt_result.changed == True" - - - name: See if the password needs to be updated. (expect changed=false) - mysql_user: - <<: *mysql_params - name: jmainguy - password: 'Fdt8fd^34ds' - register: plain_result - - - name: Check that the module did not change the password - assert: - that: - - "plain_result.changed == False" - - - name: Remove user (cleanup) - mysql_user: - <<: *mysql_params - name: jmainguy - state: absent