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
duration:
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
type: str
replication:
@ -46,9 +48,10 @@ options:
default: false
shard_group_duration:
description:
- Determines the size of a shard group.
- Value needs to be integer literal followed immediately (with no spaces) by a duration unit.
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).
- Determines the time range covered by a shard group. If specified it
must be at least one hour. If none, it's determined by InfluxDB by
the rentention policy's duration. Supports complex duration expressions
with multiple units.
type: str
version_added: '2.0.0'
extends_documentation_fragment:
@ -96,6 +99,17 @@ EXAMPLES = r'''
ssl: no
validate_certs: no
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'''
@ -115,6 +129,51 @@ from ansible_collections.community.general.plugins.module_utils.influxdb import
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):
database_name = module.params['database_name']
policy_name = module.params['policy_name']
@ -129,6 +188,11 @@ def find_retention_policy(module, client):
break
except requests.exceptions.ConnectionError as 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
@ -140,6 +204,21 @@ def create_retention_policy(module, client):
default = module.params['default']
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:
try:
if shard_group_duration:
@ -159,38 +238,30 @@ def alter_retention_policy(module, client, retention_policy):
replication = module.params['replication']
default = module.params['default']
shard_group_duration = module.params['shard_group_duration']
duration_regexp = re.compile(r'(\d+)([hdw]{1})|(^INF$){1}')
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 = '%s0m0s' % duration
elif duration_lookup.group(2) == 'd':
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'
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:
shard_group_duration_lookup = duration_regexp.search(shard_group_duration)
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)
if shard_group_duration is None:
influxdb_shard_group_duration_format = retention_policy["shardGroupDuration"]
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
not retention_policy['replicaN'] == int(replication) or
not retention_policy['shardGroupDuration'] == influxdb_shard_group_duration_format or
not retention_policy['default'] == default):
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 (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:
try:
client.alter_retention_policy(policy_name, database_name, duration, replication, default,