From 57e2a0817e0596c858a118e2ba4d97810ac34b80 Mon Sep 17 00:00:00 2001 From: jmisset-cb Date: Fri, 6 Sep 2024 14:27:21 +0200 Subject: [PATCH 1/8] cloudwatchlogs_log_group_metric_filter: add support for unit and dimensions --- ...atch-log-metric-filter-unit-dimensions.yml | 3 + .../cloudwatchlogs_log_group_metric_filter.py | 60 ++++++++++--- .../tasks/cloudwatchlogs_tests.yml | 89 +++++++++++++++++++ 3 files changed, 139 insertions(+), 13 deletions(-) create mode 100644 changelogs/fragments/20240906-cloudwatch-log-metric-filter-unit-dimensions.yml diff --git a/changelogs/fragments/20240906-cloudwatch-log-metric-filter-unit-dimensions.yml b/changelogs/fragments/20240906-cloudwatch-log-metric-filter-unit-dimensions.yml new file mode 100644 index 00000000000..b2b721f2888 --- /dev/null +++ b/changelogs/fragments/20240906-cloudwatch-log-metric-filter-unit-dimensions.yml @@ -0,0 +1,3 @@ +--- +minor_changes: + - cloudwatchlogs_log_group_metric_filter - Add support for ``unit`` and ``dimensions`` options (https://github.com/ansible-collections/amazon.aws/pull/XXX) diff --git a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py index 8eddb671bed..63a01bd24cb 100644 --- a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py +++ b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py @@ -56,7 +56,19 @@ default_value: description: - The value to emit when a filter pattern does not match a log event. + - The I(default_value) and I(dimensions) options are mutually exclusive. type: float + unit: + description: + - The unit of the value. The various options are available `here `. + type: str + dimensions: + description: + - A dimension is a name/value pair that is a part of the identity of a metric. + - You can assign up to 3 dimensions to a metric. + - Dimensions are only supported for JSON or space-delimited metric filters. + - The I(default_value) and I(dimensions) options are mutually exclusive. + type: dict extends_documentation_fragment: - amazon.aws.common.modules - amazon.aws.region.modules @@ -74,12 +86,26 @@ metric_name: box_free_space metric_namespace: fluentd_metrics metric_value: "$.value" + unit: Bytes - name: delete metric filter on log group /fluentd/testcase amazon.aws.cloudwatchlogs_log_group_metric_filter: log_group_name: /fluentd/testcase filter_name: BoxFreeStorage state: absent + +- name: set metric filter on log group /fluentd/testcase with dimensions + amazon.aws.cloudwatchlogs_log_group_metric_filter: + log_group_name: /fluentd/testcase + filter_name: BoxFreeStorage + filter_pattern: '{($.value = *) && ($.hostname = *)}' + state: present + metric_transformation: + metric_name: box_free_space + metric_namespace: fluentd_metrics + metric_value: "$.value" + dimensions: + hostname: $.hostname """ RETURN = r""" @@ -106,24 +132,13 @@ def metricTransformationHandler(metricTransformations, originMetricTransformatio if originMetricTransformations: change = False originMetricTransformations = camel_dict_to_snake_dict(originMetricTransformations) - for item in ["default_value", "metric_name", "metric_namespace", "metric_value"]: + for item in ["default_value", "metric_name", "metric_namespace", "metric_value", "unit", "dimensions"]: if metricTransformations.get(item) != originMetricTransformations.get(item): change = True else: change = True - defaultValue = metricTransformations.get("default_value") - if isinstance(defaultValue, int) or isinstance(defaultValue, float): - retval = [ - { - "metricName": metricTransformations.get("metric_name"), - "metricNamespace": metricTransformations.get("metric_namespace"), - "metricValue": metricTransformations.get("metric_value"), - "defaultValue": defaultValue, - } - ] - else: - retval = [ + retval = [ { "metricName": metricTransformations.get("metric_name"), "metricNamespace": metricTransformations.get("metric_namespace"), @@ -131,6 +146,19 @@ def metricTransformationHandler(metricTransformations, originMetricTransformatio } ] + # Add optional values + defaultValue = metricTransformations.get("default_value") + if defaultValue is not None: + retval[0]["defaultValue"] = defaultValue + + dimensions = metricTransformations.get("dimensions") + if dimensions is not None: + retval[0]["dimensions"] = dimensions + + unit = metricTransformations.get("unit") + if unit is not None: + retval[0]["unit"] = unit + return retval, change @@ -147,6 +175,8 @@ def main(): metric_namespace=dict(type="str"), metric_value=dict(type="str"), default_value=dict(type="float"), + unit=dict(type="str"), + dimensions=dict(type="dict"), ), ), ) @@ -184,6 +214,10 @@ def main(): metricTransformation = [camel_dict_to_snake_dict(item) for item in [originMetricTransformations]] elif state == "present": + + if metric_transformation.get('default_value') is not None and metric_transformation.get('dimensions') is not None: + module.fail_json(msg="default_value and dimensions are mutually exclusive.") + metricTransformation, change = metricTransformationHandler( metricTransformations=metric_transformation, originMetricTransformations=originMetricTransformations ) diff --git a/tests/integration/targets/cloudwatchlogs/tasks/cloudwatchlogs_tests.yml b/tests/integration/targets/cloudwatchlogs/tasks/cloudwatchlogs_tests.yml index 9efdcc81ac8..e127b76a130 100644 --- a/tests/integration/targets/cloudwatchlogs/tasks/cloudwatchlogs_tests.yml +++ b/tests/integration/targets/cloudwatchlogs/tasks/cloudwatchlogs_tests.yml @@ -100,6 +100,95 @@ - out is changed - out.metric_filters[0].metric_namespace == "made_with_ansible" + - name: Update metric transformation with dimensions on '{{ log_group_name }}' + amazon.aws.cloudwatchlogs_log_group_metric_filter: + log_group_name: "{{ log_group_name }}" + filter_name: "{{ filter_name }}" + filter_pattern: '{ ($.value = *) && ($.hostname = "box")}' + state: present + metric_transformation: + metric_name: box_free_space + metric_namespace: made_with_ansible + metric_value: $.value + dimensions: + hostname: $.hostname + register: out + + - name: Assert that metric_filter is configured with dimensions + ansible.builtin.assert: + that: + - out is changed + - out.metric_filters[0].metric_namespace == "made_with_ansible" + - out.metric_filters[0].dimensions.hostname == "$.hostname" + + - name: Update metric transformation with unit on '{{ log_group_name }}' + amazon.aws.cloudwatchlogs_log_group_metric_filter: + log_group_name: "{{ log_group_name }}" + filter_name: "{{ filter_name }}" + filter_pattern: '{ ($.value = *) && ($.hostname = "box")}' + state: present + metric_transformation: + metric_name: box_free_space + metric_namespace: made_with_ansible + metric_value: $.value + unit: Bytes + dimensions: + hostname: $.hostname + register: out + + - name: Assert that metric_filter is configured with dimensions and unit + ansible.builtin.assert: + that: + - out is changed + - out.metric_filters[0].metric_namespace == "made_with_ansible" + - out.metric_filters[0].dimensions.hostname == "$.hostname" + - out.metric_filters[0].unit == "Bytes" + + - name: Idempotency check on metric transformation on '{{ log_group_name }}' + amazon.aws.cloudwatchlogs_log_group_metric_filter: + log_group_name: "{{ log_group_name }}" + filter_name: "{{ filter_name }}" + filter_pattern: '{ ($.value = *) && ($.hostname = "box")}' + state: present + metric_transformation: + metric_name: box_free_space + metric_namespace: made_with_ansible + metric_value: $.value + unit: Bytes + dimensions: + hostname: $.hostname + register: out + + - name: Assert that idempotent action with unit and dimensions does not register as changed + ansible.builtin.assert: + that: + - out is not changed + - out.metric_filters[0].metric_namespace == "made_with_ansible" + - out.metric_filters[0].unit == "Bytes" + - out.metric_filters[0].dimensions.hostname == "$.hostname" + + - name: Update metric transformation with default_value and dimensions on '{{ log_group_name }}' + amazon.aws.cloudwatchlogs_log_group_metric_filter: + log_group_name: "{{ log_group_name }}" + filter_name: "{{ filter_name }}" + filter_pattern: '{ ($.value = *) && ($.hostname = "box")}' + state: present + metric_transformation: + metric_name: box_free_space + metric_namespace: made_with_ansible + metric_value: $.value + default_value: 3.1415 + dimensions: + hostname: $.hostname + register: out + ignore_errors: true + + - name: Update metric transformation with default_value and dimensions must fail + ansible.builtin.assert: + that: + - out is failed + - out.msg == "default_value and dimensions are mutually exclusive." + - name: checkmode delete metric filter on '{{ log_group_name }}' amazon.aws.cloudwatchlogs_log_group_metric_filter: log_group_name: "{{ log_group_name }}" From 88f0c034ef405cb93564b88dfcfeedf030fea2a2 Mon Sep 17 00:00:00 2001 From: jmisset-cb Date: Fri, 6 Sep 2024 14:46:23 +0200 Subject: [PATCH 2/8] cloudwatchlogs_log_group_metric_filter: add changelog entry for #2286 --- .../20240906-cloudwatch-log-metric-filter-unit-dimensions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/20240906-cloudwatch-log-metric-filter-unit-dimensions.yml b/changelogs/fragments/20240906-cloudwatch-log-metric-filter-unit-dimensions.yml index b2b721f2888..294f55752dc 100644 --- a/changelogs/fragments/20240906-cloudwatch-log-metric-filter-unit-dimensions.yml +++ b/changelogs/fragments/20240906-cloudwatch-log-metric-filter-unit-dimensions.yml @@ -1,3 +1,3 @@ --- minor_changes: - - cloudwatchlogs_log_group_metric_filter - Add support for ``unit`` and ``dimensions`` options (https://github.com/ansible-collections/amazon.aws/pull/XXX) + - cloudwatchlogs_log_group_metric_filter - Add support for ``unit`` and ``dimensions`` options (https://github.com/ansible-collections/amazon.aws/pull/2286) From cc1c4ab260a61a6655e278749d4e78009a929859 Mon Sep 17 00:00:00 2001 From: jmisset-cb Date: Fri, 6 Sep 2024 15:06:24 +0200 Subject: [PATCH 3/8] cloudwatchlogs_log_group_metric_filter: fix linting --- .../cloudwatchlogs_log_group_metric_filter.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py index 63a01bd24cb..f3843bfb0a2 100644 --- a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py +++ b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py @@ -60,7 +60,8 @@ type: float unit: description: - - The unit of the value. The various options are available `here `. + - The unit of the value. + - The various options are available `here `. type: str dimensions: description: @@ -139,22 +140,22 @@ def metricTransformationHandler(metricTransformations, originMetricTransformatio change = True retval = [ - { - "metricName": metricTransformations.get("metric_name"), - "metricNamespace": metricTransformations.get("metric_namespace"), - "metricValue": metricTransformations.get("metric_value"), - } - ] + { + "metricName": metricTransformations.get("metric_name"), + "metricNamespace": metricTransformations.get("metric_namespace"), + "metricValue": metricTransformations.get("metric_value"), + } + ] # Add optional values defaultValue = metricTransformations.get("default_value") if defaultValue is not None: retval[0]["defaultValue"] = defaultValue - + dimensions = metricTransformations.get("dimensions") if dimensions is not None: retval[0]["dimensions"] = dimensions - + unit = metricTransformations.get("unit") if unit is not None: retval[0]["unit"] = unit From 22fadff6a5f9935c26180242ca2073f5037533a3 Mon Sep 17 00:00:00 2001 From: jmisset-cb Date: Fri, 6 Sep 2024 15:11:23 +0200 Subject: [PATCH 4/8] cloudwatchlogs_log_group_metric_filter: fix linting --- plugins/modules/cloudwatchlogs_log_group_metric_filter.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py index f3843bfb0a2..69f487bd365 100644 --- a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py +++ b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py @@ -216,7 +216,10 @@ def main(): elif state == "present": - if metric_transformation.get('default_value') is not None and metric_transformation.get('dimensions') is not None: + if ( + metric_transformation.get('default_value') is not None + and metric_transformation.get('dimensions') is not None + ): module.fail_json(msg="default_value and dimensions are mutually exclusive.") metricTransformation, change = metricTransformationHandler( From 1249587f6264ae487eff8f273b0a0c41d821acf8 Mon Sep 17 00:00:00 2001 From: jmisset-cb Date: Fri, 6 Sep 2024 15:14:28 +0200 Subject: [PATCH 5/8] cloudwatchlogs_log_group_metric_filter: fix linting --- plugins/modules/cloudwatchlogs_log_group_metric_filter.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py index 69f487bd365..1a08b0392b5 100644 --- a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py +++ b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py @@ -215,10 +215,9 @@ def main(): metricTransformation = [camel_dict_to_snake_dict(item) for item in [originMetricTransformations]] elif state == "present": - if ( - metric_transformation.get('default_value') is not None - and metric_transformation.get('dimensions') is not None + metric_transformation.get("default_value") is not None + and metric_transformation.get("dimensions") is not None ): module.fail_json(msg="default_value and dimensions are mutually exclusive.") From 563c9e53a682b5e19025427f8c452fc90fe02f7b Mon Sep 17 00:00:00 2001 From: jmisset-cb Date: Fri, 6 Sep 2024 16:47:11 +0200 Subject: [PATCH 6/8] cloudwatchlogs_log_group_metric_filter: update return block --- plugins/modules/cloudwatchlogs_log_group_metric_filter.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py index 1a08b0392b5..7c35026ce8d 100644 --- a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py +++ b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py @@ -119,7 +119,10 @@ "default_value": 3.1415, "metric_name": "box_free_space", "metric_namespace": "made_with_ansible", - "metric_value": "$.value" + "metric_value": "$.value", + "unit": "Bytes", + "dimensions": + "hostname": "$.hostname" } ] """ From 27b079bf64eacd79ad630efc4a3e713a34d60111 Mon Sep 17 00:00:00 2001 From: jmisset-cb Date: Fri, 6 Sep 2024 16:52:19 +0200 Subject: [PATCH 7/8] cloudwatchlogs_log_group_metric_filter: update return block --- plugins/modules/cloudwatchlogs_log_group_metric_filter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py index 7c35026ce8d..60a284e6cf4 100644 --- a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py +++ b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py @@ -121,8 +121,9 @@ "metric_namespace": "made_with_ansible", "metric_value": "$.value", "unit": "Bytes", - "dimensions": + "dimensions": { "hostname": "$.hostname" + } } ] """ From 8f52905e7501cee9b3b21726ab63c1da25fc3308 Mon Sep 17 00:00:00 2001 From: jmisset-cb Date: Thu, 12 Sep 2024 15:06:42 +0200 Subject: [PATCH 8/8] cloudwatchlogs_log_group_metric_filter: add version_added to new options --- plugins/modules/cloudwatchlogs_log_group_metric_filter.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py index 60a284e6cf4..a375167da9e 100644 --- a/plugins/modules/cloudwatchlogs_log_group_metric_filter.py +++ b/plugins/modules/cloudwatchlogs_log_group_metric_filter.py @@ -63,6 +63,7 @@ - The unit of the value. - The various options are available `here `. type: str + version_added: 8.3.0 dimensions: description: - A dimension is a name/value pair that is a part of the identity of a metric. @@ -70,6 +71,7 @@ - Dimensions are only supported for JSON or space-delimited metric filters. - The I(default_value) and I(dimensions) options are mutually exclusive. type: dict + version_added: 8.3.0 extends_documentation_fragment: - amazon.aws.common.modules - amazon.aws.region.modules