1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

influxdb_retention_policy: ensure duration parameters are idempotent (#2281) (#2284)

* influxdb_retention_policy: ensure duration parameters are idempotent (#2281)

* add changelog for pr #2284
This commit is contained in:
Xabier Napal 2021-04-26 07:03:36 +02:00 committed by GitHub
parent 1b79440896
commit aea12899cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 105 additions and 30 deletions

View file

@ -0,0 +1,4 @@
bugfixes:
- influxdb_retention_policy - ensure idempotent module execution with different
duration and shard duration parameter values
(https://github.com/ansible-collections/community.general/issues/2281).

View file

@ -31,7 +31,9 @@ options:
type: str type: str
duration: duration:
description: description:
- Determines how long InfluxDB should keep the data. - Determines how long InfluxDB should keep the data. If specified, it
should be C(INF) or at least one hour. If not specified, C(INF) is
assumed. Supports complex duration expressions with multiple units.
required: true required: true
type: str type: str
replication: replication:
@ -46,9 +48,10 @@ options:
default: false default: false
shard_group_duration: shard_group_duration:
description: description:
- Determines the size of a shard group. - Determines the time range covered by a shard group. If specified it
- Value needs to be integer literal followed immediately (with no spaces) by a duration unit. must be at least one hour. If none, it's determined by InfluxDB by
Supported duration units are C(h) for hours, C(d) for days, and C(w) for weeks. For example C(10d), C(1h), C(2w). the rentention policy's duration. Supports complex duration expressions
with multiple units.
type: str type: str
version_added: '2.0.0' version_added: '2.0.0'
extends_documentation_fragment: extends_documentation_fragment:
@ -96,6 +99,17 @@ EXAMPLES = r'''
ssl: no ssl: no
validate_certs: no validate_certs: no
shard_group_duration: 1w shard_group_duration: 1w
- name: Create retention policy with complex durations
community.general.influxdb_retention_policy:
hostname: "{{influxdb_ip_address}}"
database_name: "{{influxdb_database_name}}"
policy_name: test
duration: 5d1h30m
replication: 1
ssl: no
validate_certs: no
shard_group_duration: 1d10h30m
''' '''
RETURN = r''' RETURN = r'''
@ -115,6 +129,51 @@ from ansible_collections.community.general.plugins.module_utils.influxdb import
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_native
VALID_DURATION_REGEX = re.compile(r'^(\d+(ns|u|µ|ms|s|m|h|d|w))+$')
DURATION_REGEX = re.compile(r'(\d+)(ns|u|µ|ms|s|m|h|d|w)')
EXTENDED_DURATION_REGEX = re.compile(r'(?:(\d+)(ns|u|µ|ms|m|h|d|w)|(\d+(?:\.\d+)?)(s))')
def check_duration_literal(value):
return VALID_DURATION_REGEX.search(value) is not None
def parse_duration_literal(value, extended=False):
duration = 0.0
if value == "INF":
return duration
lookup = (EXTENDED_DURATION_REGEX if extended else DURATION_REGEX).findall(value)
for duration_literal in lookup:
if extended and duration_literal[3] == 's':
duration_val = float(duration_literal[2])
duration += duration_val * 1000 * 1000 * 1000
else:
duration_val = int(duration_literal[0])
if duration_literal[1] == 'ns':
duration += duration_val
elif duration_literal[1] == 'u' or duration_literal[1] == 'µ':
duration += duration_val * 1000
elif duration_literal[1] == 'ms':
duration += duration_val * 1000 * 1000
elif duration_literal[1] == 's':
duration += duration_val * 1000 * 1000 * 1000
elif duration_literal[1] == 'm':
duration += duration_val * 1000 * 1000 * 1000 * 60
elif duration_literal[1] == 'h':
duration += duration_val * 1000 * 1000 * 1000 * 60 * 60
elif duration_literal[1] == 'd':
duration += duration_val * 1000 * 1000 * 1000 * 60 * 60 * 24
elif duration_literal[1] == 'w':
duration += duration_val * 1000 * 1000 * 1000 * 60 * 60 * 24 * 7
return duration
def find_retention_policy(module, client): def find_retention_policy(module, client):
database_name = module.params['database_name'] database_name = module.params['database_name']
policy_name = module.params['policy_name'] policy_name = module.params['policy_name']
@ -129,6 +188,11 @@ def find_retention_policy(module, client):
break break
except requests.exceptions.ConnectionError as e: except requests.exceptions.ConnectionError as e:
module.fail_json(msg="Cannot connect to database %s on %s : %s" % (database_name, hostname, to_native(e))) module.fail_json(msg="Cannot connect to database %s on %s : %s" % (database_name, hostname, to_native(e)))
if retention_policy is not None:
retention_policy["duration"] = parse_duration_literal(retention_policy["duration"], extended=True)
retention_policy["shardGroupDuration"] = parse_duration_literal(retention_policy["shardGroupDuration"], extended=True)
return retention_policy return retention_policy
@ -140,6 +204,21 @@ def create_retention_policy(module, client):
default = module.params['default'] default = module.params['default']
shard_group_duration = module.params['shard_group_duration'] shard_group_duration = module.params['shard_group_duration']
if not check_duration_literal(duration):
module.fail_json(msg="Failed to parse value of duration")
influxdb_duration_format = parse_duration_literal(duration)
if influxdb_duration_format != 0 and influxdb_duration_format < 3600000000000:
module.fail_json(msg="duration value must be at least 1h")
if shard_group_duration is not None:
if not check_duration_literal(shard_group_duration):
module.fail_json(msg="Failed to parse value of shard_group_duration")
influxdb_shard_group_duration_format = parse_duration_literal(shard_group_duration)
if influxdb_shard_group_duration_format < 3600000000000:
module.fail_json(msg="shard_group_duration value must be at least 1h")
if not module.check_mode: if not module.check_mode:
try: try:
if shard_group_duration: if shard_group_duration:
@ -159,38 +238,30 @@ def alter_retention_policy(module, client, retention_policy):
replication = module.params['replication'] replication = module.params['replication']
default = module.params['default'] default = module.params['default']
shard_group_duration = module.params['shard_group_duration'] shard_group_duration = module.params['shard_group_duration']
duration_regexp = re.compile(r'(\d+)([hdw]{1})|(^INF$){1}')
changed = False changed = False
duration_lookup = duration_regexp.search(duration) if not check_duration_literal(duration):
module.fail_json(msg="Failed to parse value of duration")
if duration_lookup.group(2) == 'h': influxdb_duration_format = parse_duration_literal(duration)
influxdb_duration_format = '%s0m0s' % duration if influxdb_duration_format != 0 and influxdb_duration_format < 3600000000000:
elif duration_lookup.group(2) == 'd': module.fail_json(msg="duration value must be at least 1h")
influxdb_duration_format = '%sh0m0s' % (int(duration_lookup.group(1)) * 24)
elif duration_lookup.group(2) == 'w':
influxdb_duration_format = '%sh0m0s' % (int(duration_lookup.group(1)) * 24 * 7)
elif duration == 'INF':
influxdb_duration_format = '0'
if shard_group_duration: if shard_group_duration is None:
shard_group_duration_lookup = duration_regexp.search(shard_group_duration) influxdb_shard_group_duration_format = retention_policy["shardGroupDuration"]
if not shard_group_duration_lookup:
module.fail_json(
msg="Failed to parse value of shard_group_duration. Please see the documentation for valid values")
if shard_group_duration_lookup.group(2) == 'h':
influxdb_shard_group_duration_format = '%s0m0s' % duration
elif shard_group_duration_lookup.group(2) == 'd':
influxdb_shard_group_duration_format = '%sh0m0s' % (int(shard_group_duration_lookup.group(1)) * 24)
elif shard_group_duration_lookup.group(2) == 'w':
influxdb_shard_group_duration_format = '%sh0m0s' % (int(shard_group_duration_lookup.group(1)) * 24 * 7)
else: else:
influxdb_shard_group_duration_format = retention_policy['shardGroupDuration'] if not check_duration_literal(shard_group_duration):
module.fail_json(msg="Failed to parse value of shard_group_duration")
if (not retention_policy['duration'] == influxdb_duration_format or influxdb_shard_group_duration_format = parse_duration_literal(shard_group_duration)
not retention_policy['replicaN'] == int(replication) or if influxdb_shard_group_duration_format < 3600000000000:
not retention_policy['shardGroupDuration'] == influxdb_shard_group_duration_format or module.fail_json(msg="shard_group_duration value must be at least 1h")
not retention_policy['default'] == default):
if (retention_policy['duration'] != influxdb_duration_format or
retention_policy['shardGroupDuration'] != influxdb_shard_group_duration_format or
retention_policy['replicaN'] != int(replication) or
retention_policy['default'] != default):
if not module.check_mode: if not module.check_mode:
try: try:
client.alter_retention_policy(policy_name, database_name, duration, replication, default, client.alter_retention_policy(policy_name, database_name, duration, replication, default,