-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Redis connection parameters full control #8578
base: main
Are you sure you want to change the base?
Add Redis connection parameters full control #8578
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
73ac680
to
be4651c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your contribution!
changelogs/fragments/8578-feat-add-redis-connection-parameters-full-control.yml
Outdated
Show resolved
Hide resolved
plugins/cache/redis.py
Outdated
- To specify advanced connection parameters (keep alive, etc ...), use the 3rd format. | ||
- This last format consists in a '&' separated string of redis connection parameters as <name>=<value> pairs. | ||
- For example V(host=localhost&port=6379&db=0&password=changeme&socket_keepalive=true). | ||
- See https://redis-py2.readthedocs.io/en/latest/ for Redis connection parameters name and accepted values. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not simply expose these extra parameters as proper options? That makes everything a lot more readable and thus simpler to use as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @felixfontein, i've suggested this because there are a lot of parameters in the Redis connection, and some complex ones like socket_keepalive_options
. And I don't wanted to add too much complexity to the module, for some options not that much commonly used. But ok, maybe you're right, it might be better to expose all parameters as options. I'll prepare this, and I'll push the updated code here in few hours/days. Thank you !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pierre-claranet if I may suggest, one possible way would be to have a parameter (either a simple string or a list) for the user to pass those extra parameters. If that option is used, then it gets '&'.join()
-ed with the URL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing to keep in mind is that if password=changeme
is used, as in the example, then this option should be marked no_log: true
, personally I find that an undesirable side-effect, but YMMV.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing to consider is also to consolidate the cache plugin's options with the module and/or lookup. Right now we have three separate pieces of code and options for handling Redis logins:
- The cache plugin (what this PR touches);
- The lookup plugin;
- The modules, which use the
redis
docs fragment and theredis
module utils.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello,
PR's code updated.
@russoz, thanks for your suggestions. I took care of obfuscating the Redis connection password in the verbose (-vvv) output. The password's value will be replaced with ****
. About your 1st suggestion, if I'm right, it's close to this PR's original code. The only difference would be to use an extra option, and not the _url
one, to pass the extra parameters. And as discussed with @felixfontein previously, exposing options separately seems to be better for simplicity and readability.
@felixfontein, about the options consolidation, I'm not sure to completely understand your point. Do you suggest we use the same names, allowed values and format, for the same parameters in all pieces of codes ? For some parameters, for example these in Redis cache plugin _uri
connection string (the host, port, db, password), I think we can't change them. The cache plugin documentation (https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html#cache-plugins) says New cache plugins should take the options _uri [...]
. Could you please add some precision, maybe one example, for you point ? Thanks.
This comment has been minimized.
This comment has been minimized.
0b4d87e
to
b606b85
Compare
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
048094e
to
dd339e0
Compare
bot_status |
Componentschangelogs/fragments/8578-feat-add-redis-connection-parameters-full-control.yml plugins/cache/redis.py Metadatawaiting_on: pierre-claranet |
dd339e0
to
4b1b1d3
Compare
4b1b1d3
to
00b3468
Compare
bot_status |
Componentschangelogs/fragments/8578-feat-add-redis-connection-parameters-full-control.yml plugins/cache/redis.py Metadatawaiting_on: ansible |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @pierre-claranet,
There are some adjustments needed, others up to you. Thanks once again for your contribution!
def _parse_socket_options(self, options): | ||
if not self.re_socket_keepalive_opts.match(options): | ||
raise AnsibleError("Unable to parse Redis cache socket keepalive options string") | ||
import socket |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import statement should be by the top of the file, after the docs.
@@ -132,6 +310,7 @@ def __init__(self, *args, **kwargs): | |||
self._db = StrictRedis(*connection, **kw) | |||
|
|||
display.vv('Redis connection: %s' % self._db) | |||
display.vvv("Redis connection kwargs: %s" % ({**self._db.get_connection_kwargs(), **{'password': '****'}})) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to find documentation related to this method get_connection_kwargs()
in the Redis lib, but could not find anything very straightforward. Code also seems to be referencing a dynamic connection class. I am concerned that some sensitive info might be leaked by printing the entire result.
from os.path import isfile | ||
import ssl | ||
|
||
if not self._ssl_cert_reqs.upper() in list(map(lambda x: x.name.split('_')[1], ssl.VerifyMode)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coercing to list
is redundant here:
if not self._ssl_cert_reqs.upper() in list(map(lambda x: x.name.split('_')[1], ssl.VerifyMode)): | |
if not self._ssl_cert_reqs.upper() in map(lambda x: x.name.split('_')[1], ssl.VerifyMode): |
- To use encryption in transit, prefix the connection with V(tls://), as in V(tls://localhost:6379:0:changeme). | ||
- To use redis sentinel, use separator V(;), for example V(localhost:26379;localhost:26379;0:changeme). Requires redis>=2.9.0. | ||
_decode_responses: | ||
description: If set to `true`, returned values from Redis commands get decoded automatically using the client's charset value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
description: If set to `true`, returned values from Redis commands get decoded automatically using the client's charset value. | |
description: If set to C(true), returned values from Redis commands get decoded automatically using the client's charset value. |
_encoding_errors: | ||
description: | ||
- The error handling scheme to use for encoding errors. | ||
- The default is `strict` meaning that encoding errors raise a `UnicodeEncodeError`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The default is `strict` meaning that encoding errors raise a `UnicodeEncodeError`. | |
- The default is V(strict) meaning that encoding errors raise a C(UnicodeEncodeError). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use (here and elsewhere) the semantic markup for Ansible.
See: https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_documenting.html#semantic-markup-within-module-documentation
@@ -0,0 +1,2 @@ | |||
minor_changes: | |||
- redis cache plugin - add Redis connection parameters full access in order to be able to set advanced socket options, like enabling keep alive (https://github.com/ansible-collections/community.general/pull/8578) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- redis cache plugin - add Redis connection parameters full access in order to be able to set advanced socket options, like enabling keep alive (https://github.com/ansible-collections/community.general/pull/8578) | |
- redis cache plugin - add Redis connection parameters full access in order to be able to set advanced socket options, like enabling keep alive (https://github.com/ansible-collections/community.general/pull/8578). | |
self._socket_connect_timeout = int(self.get_option('_socket_connect_timeout')) \ | ||
if self._socket_keepalive and self.get_option('_socket_connect_timeout') else None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a personal preference for style, I do like using the x = a if b else c
construct for smaller expressions. In this case, I think it might be more readable expanding this to a "normal" if
block.
@pierre-claranet ping needs_info |
SUMMARY
In Ansible Redis facts cache plugin, add Redis connection parameters full access in order to be able to set advanced socket options, like enabling keep alive for example.
ISSUE TYPE
COMPONENT NAME
redis cache
ADDITIONAL INFORMATION
The parameter Ansible facts cache parameter
fact_caching_connection
accepts (for Redis cache plugin) a new URI format (the 2 other formats are still accepted too): key=value pairs, separated by&
. Keys are Redis Python connection parameters name. See https://redis-py2.readthedocs.io/en/latest/ for parameters name and accepted values.