mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Add tls parameter to redis module (#4207)
* Add tls parameter to redis module * Rename changelog fragment to match PR * Apply suggestions from code review Co-authored-by: Felix Fontein <felix@fontein.de> * Port redis module to redis auth module util * Update changelogs/fragments/4207-add-redis-tls-support.yml Co-authored-by: Felix Fontein <felix@fontein.de> * Update plugins/modules/database/misc/redis.py Co-authored-by: Felix Fontein <felix@fontein.de> * Undo reuse of redis auth doc fragment * Use doc fragment. Co-authored-by: Julian Faude <julian.faude@zweiacht.de> Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
parent
10ca62905f
commit
9a74ace1e4
3 changed files with 64 additions and 60 deletions
2
changelogs/fragments/4207-add-redis-tls-support.yml
Normal file
2
changelogs/fragments/4207-add-redis-tls-support.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- redis - add authentication parameters ``login_user``, ``tls``, ``validate_certs``, and ``ca_certs`` (https://github.com/ansible-collections/community.general/pull/4207).
|
|
@ -27,20 +27,20 @@ except ImportError:
|
||||||
HAS_CERTIFI_PACKAGE = False
|
HAS_CERTIFI_PACKAGE = False
|
||||||
|
|
||||||
|
|
||||||
def fail_imports(module):
|
def fail_imports(module, needs_certifi=True):
|
||||||
errors = []
|
errors = []
|
||||||
traceback = []
|
traceback = []
|
||||||
if not HAS_REDIS_PACKAGE:
|
if not HAS_REDIS_PACKAGE:
|
||||||
errors.append(missing_required_lib('redis'))
|
errors.append(missing_required_lib('redis'))
|
||||||
traceback.append(REDIS_IMP_ERR)
|
traceback.append(REDIS_IMP_ERR)
|
||||||
if not HAS_CERTIFI_PACKAGE:
|
if not HAS_CERTIFI_PACKAGE and needs_certifi:
|
||||||
errors.append(missing_required_lib('certifi'))
|
errors.append(missing_required_lib('certifi'))
|
||||||
traceback.append(CERTIFI_IMPORT_ERROR)
|
traceback.append(CERTIFI_IMPORT_ERROR)
|
||||||
if errors:
|
if errors:
|
||||||
module.fail_json(errors=errors, traceback='\n'.join(traceback))
|
module.fail_json(errors=errors, traceback='\n'.join(traceback))
|
||||||
|
|
||||||
|
|
||||||
def redis_auth_argument_spec():
|
def redis_auth_argument_spec(tls_default=True):
|
||||||
return dict(
|
return dict(
|
||||||
login_host=dict(type='str',
|
login_host=dict(type='str',
|
||||||
default='localhost',),
|
default='localhost',),
|
||||||
|
@ -50,7 +50,7 @@ def redis_auth_argument_spec():
|
||||||
),
|
),
|
||||||
login_port=dict(type='int', default=6379),
|
login_port=dict(type='int', default=6379),
|
||||||
tls=dict(type='bool',
|
tls=dict(type='bool',
|
||||||
default=True),
|
default=tls_default),
|
||||||
validate_certs=dict(type='bool',
|
validate_certs=dict(type='bool',
|
||||||
default=True
|
default=True
|
||||||
),
|
),
|
||||||
|
@ -58,6 +58,30 @@ def redis_auth_argument_spec():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def redis_auth_params(module):
|
||||||
|
login_host = module.params['login_host']
|
||||||
|
login_user = module.params['login_user']
|
||||||
|
login_password = module.params['login_password']
|
||||||
|
login_port = module.params['login_port']
|
||||||
|
tls = module.params['tls']
|
||||||
|
validate_certs = 'required' if module.params['validate_certs'] else None
|
||||||
|
ca_certs = module.params['ca_certs']
|
||||||
|
if tls and ca_certs is None:
|
||||||
|
ca_certs = str(certifi.where())
|
||||||
|
if tuple(map(int, redis_version.split('.'))) < (3, 4, 0) and login_user is not None:
|
||||||
|
module.fail_json(
|
||||||
|
msg='The option `username` in only supported with redis >= 3.4.0.')
|
||||||
|
params = {'host': login_host,
|
||||||
|
'port': login_port,
|
||||||
|
'password': login_password,
|
||||||
|
'ssl_ca_certs': ca_certs,
|
||||||
|
'ssl_cert_reqs': validate_certs,
|
||||||
|
'ssl': tls}
|
||||||
|
if login_user is not None:
|
||||||
|
params['username'] = login_user
|
||||||
|
return params
|
||||||
|
|
||||||
|
|
||||||
class RedisAnsible(object):
|
class RedisAnsible(object):
|
||||||
'''Base class for Redis module'''
|
'''Base class for Redis module'''
|
||||||
|
|
||||||
|
@ -66,28 +90,8 @@ class RedisAnsible(object):
|
||||||
self.connection = self._connect()
|
self.connection = self._connect()
|
||||||
|
|
||||||
def _connect(self):
|
def _connect(self):
|
||||||
login_host = self.module.params['login_host']
|
|
||||||
login_user = self.module.params['login_user']
|
|
||||||
login_password = self.module.params['login_password']
|
|
||||||
login_port = self.module.params['login_port']
|
|
||||||
tls = self.module.params['tls']
|
|
||||||
validate_certs = 'required' if self.module.params['validate_certs'] else None
|
|
||||||
ca_certs = self.module.params['ca_certs']
|
|
||||||
if tls and ca_certs is None:
|
|
||||||
ca_certs = str(certifi.where())
|
|
||||||
if tuple(map(int, redis_version.split('.'))) < (3, 4, 0) and login_user is not None:
|
|
||||||
self.module.fail_json(
|
|
||||||
msg='The option `username` in only supported with redis >= 3.4.0.')
|
|
||||||
params = {'host': login_host,
|
|
||||||
'port': login_port,
|
|
||||||
'password': login_password,
|
|
||||||
'ssl_ca_certs': ca_certs,
|
|
||||||
'ssl_cert_reqs': validate_certs,
|
|
||||||
'ssl': tls}
|
|
||||||
if login_user is not None:
|
|
||||||
params['username'] = login_user
|
|
||||||
try:
|
try:
|
||||||
return Redis(**params)
|
return Redis(**redis_auth_params(self.module))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.module.fail_json(msg='{0}'.format(str(e)))
|
self.module.fail_json(msg='{0}'.format(str(e)))
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -13,6 +13,8 @@ module: redis
|
||||||
short_description: Various redis commands, replica and flush
|
short_description: Various redis commands, replica and flush
|
||||||
description:
|
description:
|
||||||
- Unified utility to interact with redis instances.
|
- Unified utility to interact with redis instances.
|
||||||
|
extends_documentation_fragment:
|
||||||
|
- community.general.redis
|
||||||
options:
|
options:
|
||||||
command:
|
command:
|
||||||
description:
|
description:
|
||||||
|
@ -22,20 +24,15 @@ options:
|
||||||
- C(replica) sets a redis instance in replica or master mode. (C(slave) is an alias for C(replica).)
|
- C(replica) sets a redis instance in replica or master mode. (C(slave) is an alias for C(replica).)
|
||||||
choices: [ config, flush, replica, slave ]
|
choices: [ config, flush, replica, slave ]
|
||||||
type: str
|
type: str
|
||||||
login_password:
|
tls:
|
||||||
description:
|
default: false
|
||||||
- The password used to authenticate with (usually not used)
|
version_added: 4.6.0
|
||||||
type: str
|
login_user:
|
||||||
login_host:
|
version_added: 4.6.0
|
||||||
description:
|
validate_certs:
|
||||||
- The host running the database
|
version_added: 4.6.0
|
||||||
default: localhost
|
ca_certs:
|
||||||
type: str
|
version_added: 4.6.0
|
||||||
login_port:
|
|
||||||
description:
|
|
||||||
- The port to connect to
|
|
||||||
default: 6379
|
|
||||||
type: int
|
|
||||||
master_host:
|
master_host:
|
||||||
description:
|
description:
|
||||||
- The host of the master instance [replica command]
|
- The host of the master instance [replica command]
|
||||||
|
@ -144,6 +141,8 @@ else:
|
||||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||||
from ansible.module_utils.common.text.formatters import human_to_bytes
|
from ansible.module_utils.common.text.formatters import human_to_bytes
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
|
from ansible_collections.community.general.plugins.module_utils.redis import (
|
||||||
|
fail_imports, redis_auth_argument_spec, redis_auth_params)
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,29 +174,28 @@ def flush(client, db=None):
|
||||||
|
|
||||||
# Module execution.
|
# Module execution.
|
||||||
def main():
|
def main():
|
||||||
|
redis_auth_args = redis_auth_argument_spec(tls_default=False)
|
||||||
|
module_args = dict(
|
||||||
|
command=dict(type='str', choices=['config', 'flush', 'replica', 'slave']),
|
||||||
|
master_host=dict(type='str'),
|
||||||
|
master_port=dict(type='int'),
|
||||||
|
replica_mode=dict(type='str', default='replica', choices=['master', 'replica', 'slave'],
|
||||||
|
aliases=["slave_mode"]),
|
||||||
|
db=dict(type='int'),
|
||||||
|
flush_mode=dict(type='str', default='all', choices=['all', 'db']),
|
||||||
|
name=dict(type='str'),
|
||||||
|
value=dict(type='str'),
|
||||||
|
)
|
||||||
|
module_args.update(redis_auth_args)
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=module_args,
|
||||||
command=dict(type='str', choices=['config', 'flush', 'replica', 'slave']),
|
|
||||||
login_password=dict(type='str', no_log=True),
|
|
||||||
login_host=dict(type='str', default='localhost'),
|
|
||||||
login_port=dict(type='int', default=6379),
|
|
||||||
master_host=dict(type='str'),
|
|
||||||
master_port=dict(type='int'),
|
|
||||||
replica_mode=dict(type='str', default='replica', choices=['master', 'replica', 'slave'], aliases=["slave_mode"]),
|
|
||||||
db=dict(type='int'),
|
|
||||||
flush_mode=dict(type='str', default='all', choices=['all', 'db']),
|
|
||||||
name=dict(type='str'),
|
|
||||||
value=dict(type='str')
|
|
||||||
),
|
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not redis_found:
|
fail_imports(module, module.params['tls'])
|
||||||
module.fail_json(msg=missing_required_lib('redis'), exception=REDIS_IMP_ERR)
|
|
||||||
|
redis_params = redis_auth_params(module)
|
||||||
|
|
||||||
login_password = module.params['login_password']
|
|
||||||
login_host = module.params['login_host']
|
|
||||||
login_port = module.params['login_port']
|
|
||||||
command = module.params['command']
|
command = module.params['command']
|
||||||
if command == "slave":
|
if command == "slave":
|
||||||
command = "replica"
|
command = "replica"
|
||||||
|
@ -219,7 +217,7 @@ def main():
|
||||||
module.fail_json(msg='In replica mode master port must be provided')
|
module.fail_json(msg='In replica mode master port must be provided')
|
||||||
|
|
||||||
# Connect and check
|
# Connect and check
|
||||||
r = redis.StrictRedis(host=login_host, port=login_port, password=login_password)
|
r = redis.StrictRedis(**redis_params)
|
||||||
try:
|
try:
|
||||||
r.ping()
|
r.ping()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -270,7 +268,7 @@ def main():
|
||||||
module.fail_json(msg="In db mode the db number must be provided")
|
module.fail_json(msg="In db mode the db number must be provided")
|
||||||
|
|
||||||
# Connect and check
|
# Connect and check
|
||||||
r = redis.StrictRedis(host=login_host, port=login_port, password=login_password, db=db)
|
r = redis.StrictRedis(db=db, **redis_params)
|
||||||
try:
|
try:
|
||||||
r.ping()
|
r.ping()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -301,7 +299,7 @@ def main():
|
||||||
except ValueError:
|
except ValueError:
|
||||||
value = module.params['value']
|
value = module.params['value']
|
||||||
|
|
||||||
r = redis.StrictRedis(host=login_host, port=login_port, password=login_password)
|
r = redis.StrictRedis(**redis_params)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r.ping()
|
r.ping()
|
||||||
|
|
Loading…
Reference in a new issue