mysql_user: fixed encrypted option for MySQL 8.0 and test coverage (#79)

* 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.

* Updated tests to cover a couple of missing branches

* Skip tests that rely on sha256_password if pymysql < 0.9

* Cover the case where pymysql isn't installed for plugin tests

* Added better plugin auth checking to tests and other minor changes

* Fixed version detection to explicitly handle MariaDB

* Removed unneeded import from previous change

* Remove whitespace that was introduced by change that was removed

* Added unit tests for missing coverage
This commit is contained in:
Steve Teahan 2021-01-14 00:27:05 -05:00 committed by GitHub
parent 2de3a57021
commit 06907715d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 781 additions and 200 deletions

View file

@ -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
@ -371,6 +373,19 @@ def use_old_user_mgmt(cursor):
return False
def supports_identified_by_password(cursor):
"""
Determines whether the 'CREATE USER %s@%s IDENTIFIED BY PASSWORD %s' syntax is supported. This was dropped in
MySQL 8.0.
"""
version_str = get_server_version(cursor)
if 'mariadb' in version_str.lower():
return True
else:
return LooseVersion(version_str) < LooseVersion('8')
def get_mode(cursor):
cursor.execute('SELECT @@GLOBAL.sql_mode')
result = cursor.fetchone()
@ -476,7 +491,16 @@ 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))
if supports_identified_by_password(cursor):
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))