Add check_hostname option

This commit is contained in:
Jorge-Rodriguez 2020-09-29 16:36:51 +03:00
parent e554cb56cd
commit 01f5e120e4
No known key found for this signature in database
GPG key ID: 43153D1EFD8F7D90
5 changed files with 119 additions and 6 deletions

View file

@ -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),
)

View file

@ -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 }}"

View file

@ -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"

View file

@ -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 </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'\") }}"
dest: /tmp/cert.pem
delegate_to: localhost
- name: Drop mysql user if exists
mysql_user:
<<: *mysql_params
name: '{{ user_name_1 }}'
state: absent
ignore_errors: yes
- name: create user with ssl requirement
mysql_user:
<<: *mysql_params
name: "{{ user_name_1 }}"
password: "{{ user_password_1 }}"
tls_requires:
SSL:
- mysql_info:
login_user: '{{ user_name_1 }}'
login_password: '{{ user_password_1 }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
ca_cert: /tmp/cert.pem
filter: version
ignore_errors: yes
- name: attempt connection with newly created user (expect failure)
mysql_user:
name: "{{ user_name_2 }}"
password: "{{ user_password_2 }}"
host: 127.0.0.1
login_user: '{{ user_name_1 }}'
login_password: '{{ user_password_1 }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
ca_cert: /tmp/cert.pem
register: result
ignore_errors: yes
- pause:
seconds: 600
- assert:
that:
- result is failed
- name: attempt connection with newly created user ignoring hostname
mysql_user:
name: "{{ user_name_2 }}"
password: "{{ user_password_2 }}"
host: 127.0.0.1
login_user: '{{ user_name_1 }}'
login_password: '{{ user_password_1 }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
ca_cert: /tmp/cert.pem
check_hostname: no
register: result
ignore_errors: yes
- assert:
that:
- result is succeeded or 'pymysql >= 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 }}"

View file

@ -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