diff --git a/plugins/module_utils/mysql.py b/plugins/module_utils/mysql.py index b5beb02..2358eac 100644 --- a/plugins/module_utils/mysql.py +++ b/plugins/module_utils/mysql.py @@ -10,6 +10,7 @@ # 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 functools import reduce __metaclass__ = type import os @@ -37,8 +38,8 @@ def parse_from_mysql_config_file(cnf): def mysql_connect(module, login_user=None, login_password=None, config_file='', ssl_cert=None, - ssl_key=None, ssl_ca=None, db=None, cursor_class=None, - connect_timeout=30, autocommit=False, config_overrides_defaults=False): + ssl_key=None, ssl_ca=None, db=None, cursor_class=None, connect_timeout=30, + autocommit=False, config_overrides_defaults=False, check_hostname=None): config = {} if config_file and os.path.exists(config_file): @@ -51,10 +52,10 @@ def mysql_connect(module, login_user=None, login_password=None, config_file='', module.params['login_port'] = cp.getint('client', 'port', fallback=module.params['login_port']) except Exception as e: if "got an unexpected keyword argument 'fallback'" in e.message: - module.fail_json('To use config_overrides_defaults, ' + module.fail_json(msg='To use config_overrides_defaults, ' 'it needs Python 3.5+ as the default interpreter on a target host') - if ssl_ca is not None or ssl_key is not None or ssl_cert is not None: + if ssl_ca is not None or ssl_key is not None or ssl_cert is not None or check_hostname is not None: config['ssl'] = {} if module.params['login_unix_socket']: @@ -79,6 +80,15 @@ def mysql_connect(module, login_user=None, login_password=None, config_file='', config['db'] = db if connect_timeout is not None: config['connect_timeout'] = connect_timeout + if check_hostname is not None: + if mysql_driver.__name__ == "pymysql": + version_tuple = (n for n in mysql_driver.__version__.split('.') if n != 'None') + if reduce(lambda x, y: int(x)*100 + int(y), version_tuple) >= 711: + config['ssl']['check_hostname'] = check_hostname + else: + module.fail_json(msg='To use check_hostname, pymysql >= 0.7.11 is required on the target host') + else: + module.fail_json(msg='Connector %s does not support the check_hostname option' % mysql_driver.__name__) if _mysql_cursor_param == 'cursor': # In case of PyMySQL driver: @@ -107,4 +117,5 @@ def mysql_common_argument_spec(): client_cert=dict(type='path', aliases=['ssl_cert']), client_key=dict(type='path', aliases=['ssl_key']), ca_cert=dict(type='path', aliases=['ssl_ca']), + check_hostname=dict(type='bool', default=None), ) diff --git a/tests/integration/targets/setup_mysql/tasks/install.yml b/tests/integration/targets/setup_mysql/tasks/install.yml index f84086d..aacdddc 100644 --- a/tests/integration/targets/setup_mysql/tasks/install.yml +++ b/tests/integration/targets/setup_mysql/tasks/install.yml @@ -18,6 +18,13 @@ environment: DEBIAN_FRONTEND: noninteractive +- name: "{{ role_name }} | install | install packages required by mysql connector" + apt: + name: "{{ install_python_prereqs }}" + state: present + environment: + DEBIAN_FRONTEND: noninteractive + - name: "{{ role_name }} | install | install python packages" pip: name: "{{ python_packages }}" diff --git a/tests/integration/targets/setup_mysql/vars/main.yml b/tests/integration/targets/setup_mysql/vars/main.yml index edc6ff4..c71545d 100644 --- a/tests/integration/targets/setup_mysql/vars/main.yml +++ b/tests/integration/targets/setup_mysql/vars/main.yml @@ -14,13 +14,18 @@ percona_mysql_repos: percona_mysql_packages: - percona-server-client-{{ percona_client_version }} -python_packages: - - pymysql==0.9.3 # temporary fix pinning to 0.9.3 to ensure warnings are handled (https://github.com/ansible-collections/community.mysql/pull/9#issuecomment-663040948) +python_packages: [pymysql == 0.9.3] + # - mysqlclient == 2.0.1 # temporary fix pinning to 0.9.3 to ensure warnings are handled (https://github.com/ansible-collections/community.mysql/pull/9#issuecomment-663040948) install_prereqs: - libaio1 - libnuma1 +install_python_prereqs: + - python3-dev + - default-libmysqlclient-dev + - build-essential + mysql_tarball: "mysql-{{ mysql_version }}-linux-glibc2.12-x86_64.tar.{{ mysql_compression_extension }}" mysql_src: "https://dev.mysql.com/get/Downloads/MySQL-{{ mysql_major_version }}/{{ mysql_tarball }}" mariadb_tarball: "mariadb-{{ mariadb_version }}-linux-x86_64.tar.gz" diff --git a/tests/integration/targets/test_mysql_user/tasks/issue-28.yml b/tests/integration/targets/test_mysql_user/tasks/issue-28.yml new file mode 100644 index 0000000..6d36721 --- /dev/null +++ b/tests/integration/targets/test_mysql_user/tasks/issue-28.yml @@ -0,0 +1,88 @@ +--- +- 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: get server certificate + copy: + content: "{{ lookup('pipe', \"openssl s_client -starttls mysql -connect localhost:3307 -showcerts 2>/dev/null = 0.7.11 is required' in result.msg or 'MySQLdb does not support' in result.msg + + - name: Drop mysql user + mysql_user: + <<: *mysql_params + name: '{{ item }}' + host: 127.0.0.1 + state: absent + with_items: + - "{{ user_name_1 }}" + - "{{ user_name_2 }}" diff --git a/tests/integration/targets/test_mysql_user/tasks/main.yml b/tests/integration/targets/test_mysql_user/tasks/main.yml index 0e9f7b4..3e50608 100644 --- a/tests/integration/targets/test_mysql_user/tasks/main.yml +++ b/tests/integration/targets/test_mysql_user/tasks/main.yml @@ -37,6 +37,8 @@ block: + - include: issue-28.yml + - include: create_user.yml user_name={{user_name_1}} user_password={{ user_password_1 }} - include: resource_limits.yml