Skip to content
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

aws - add cwa filter for alarms that have a parent composite alarm #9300

Merged
33 changes: 32 additions & 1 deletion c7n/resources/cw.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
from c7n.resources import load_resources
from c7n.resources.aws import ArnResolver
from c7n.tags import universal_augment
from c7n.utils import type_schema, local_session, chunks, get_retry
from c7n.utils import type_schema, local_session, chunks, get_retry, jmespath_search
from botocore.config import Config
import re


class DescribeAlarm(DescribeSource):
Expand Down Expand Up @@ -89,6 +90,36 @@ def process(self, resources):
AlarmNames=[r['AlarmName'] for r in resource_set])


@Alarm.filter_registry.register('is-composite-child')
class IsCompositeChild(Filter):
schema = type_schema('is-composite-child', state={"type": "boolean"})
permissions = ('cloudwatch:DescribeAlarms',)

def process(self, resources, event=None):
state = self.data.get("state", True)
# Get the composite alarms since filtered out in enum_spec
composite_alarms = self.manager.get_resource_manager("composite-alarm").resources()
composite_alarm_rules = jmespath_search('[].AlarmRule', composite_alarms)

parent_alarm_names = set()
# Loop through, find child alarm names
for rule in composite_alarm_rules:
names = self.extract_alarm_names_from_rule(rule)
parent_alarm_names.update(names)

if state:
# If we want to filter out alarms that are a child of a composite alarm
return [r for r in resources if r['AlarmName'] not in parent_alarm_names]
timmygrable marked this conversation as resolved.
Show resolved Hide resolved

return [r for r in resources if r['AlarmName'] in parent_alarm_names]


def extract_alarm_names_from_rule(self, rule):
# Check alarm references (OK/ALARM/INSUFFICIENT_DATA)
pattern = r"\b(?:ALARM|OK|INSUFFICIENT_DATA)\s*\(\s*([^\)]+)\s*\)"
matches = re.findall(pattern, rule)
return set(matches)

@resources.register('composite-alarm')
class CompositeAlarm(QueryResourceManager):

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"status_code": 200,
"data": {
"CompositeAlarms": [],
"MetricAlarms": [
{
"AlarmName": "c7n-test-alarm-tags-filter",
"AlarmArn": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:c7n-test-alarm-tags-filter",
"AlarmConfigurationUpdatedTimestamp": {
"__class__": "datetime",
"year": 2021,
"month": 3,
"day": 24,
"hour": 18,
"minute": 1,
"second": 32,
"microsecond": 583000
},
"ActionsEnabled": true,
"OKActions": [],
"AlarmActions": [],
"InsufficientDataActions": [],
"StateValue": "INSUFFICIENT_DATA",
"StateReason": "Insufficient Data: 5 datapoints were unknown.",
"StateReasonData": "{\"version\":\"1.0\",\"queryDate\":\"2022-09-27T10:05:12.193+0000\",\"statistic\":\"Average\",\"period\":3600,\"recentDatapoints\":[],\"threshold\":10.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2022-09-27T09:05:00.000+0000\"},{\"timestamp\":\"2022-09-27T08:05:00.000+0000\"},{\"timestamp\":\"2022-09-27T07:05:00.000+0000\"},{\"timestamp\":\"2022-09-27T06:05:00.000+0000\"},{\"timestamp\":\"2022-09-27T05:05:00.000+0000\"}]}",
"StateUpdatedTimestamp": {
"__class__": "datetime",
"year": 2022,
"month": 9,
"day": 27,
"hour": 10,
"minute": 5,
"second": 12,
"microsecond": 198000
},
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Dimensions": [],
"Period": 3600,
"EvaluationPeriods": 5,
"Threshold": 10.0,
"ComparisonOperator": "GreaterThanThreshold",
"StateTransitionedTimestamp": {
"__class__": "datetime",
"year": 2022,
"month": 9,
"day": 27,
"hour": 10,
"minute": 5,
"second": 12,
"microsecond": 198000
}
}
],
"ResponseMetadata": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"status_code": 200,
"data": {
"CompositeAlarms": [
{
"ActionsEnabled": true,
"AlarmActions": [
"arn:aws:sns:us-east-1:644160558196:test-xyz"
],
"AlarmArn": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:ExampleCompositeAlarm",
"AlarmConfigurationUpdatedTimestamp": {
"__class__": "datetime",
"year": 2024,
"month": 2,
"day": 16,
"hour": 16,
"minute": 32,
"second": 54,
"microsecond": 256000
},
"AlarmDescription": "Composite alarm based on c7n-test-alarm-tags-filter",
"AlarmName": "ExampleCompositeAlarm",
"AlarmRule": "ALARM(c7n-test-alarm-tags-filter)",
"InsufficientDataActions": [
"arn:aws:sns:us-east-1:644160558196:test-zyx"
],
"OKActions": [
"arn:aws:sns:us-east-1:644160558196:test-xyz"
],
"StateReason": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:ExampleCompositeAlarm was created and its alarm rule evaluates to OK",
"StateReasonData": "{\"triggeringAlarms\":[{\"arn\":\"arn:aws:cloudwatch:us-east-1:644160558196:alarm:c7n-test-alarm-tags-filter\",\"state\":{\"value\":\"INSUFFICIENT_DATA\",\"timestamp\":\"2022-09-27T10:05:12.198+0000\"}}]}",
"StateUpdatedTimestamp": {
"__class__": "datetime",
"year": 2024,
"month": 2,
"day": 16,
"hour": 16,
"minute": 32,
"second": 54,
"microsecond": 256000
},
"StateValue": "OK",
"StateTransitionedTimestamp": {
"__class__": "datetime",
"year": 2024,
"month": 2,
"day": 16,
"hour": 16,
"minute": 32,
"second": 54,
"microsecond": 256000
}
}
],
"MetricAlarms": [],
"ResponseMetadata": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"status_code": 200,
"data": {
"PaginationToken": "",
"ResourceTagMappingList": [
{
"ResourceARN": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:c7n-test-alarm-tags-filter",
"Tags": [
{
"Key": "some-tag",
"Value": "some-value"
},
{
"Key": "OwnerName",
"Value": "SomeName"
},
{
"Key": "pratyush",
"Value": "test"
}
]
}
],
"ResponseMetadata": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"status_code": 200,
"data": {
"PaginationToken": "",
"ResourceTagMappingList": [
{
"ResourceARN": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:ExampleCompositeAlarm",
"Tags": []
}
],
"ResponseMetadata": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"status_code": 200,
"data": {
"CompositeAlarms": [],
"MetricAlarms": [
{
"AlarmName": "c7n-test-alarm-tags-filter",
"AlarmArn": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:c7n-test-alarm-tags-filter",
"AlarmConfigurationUpdatedTimestamp": {
"__class__": "datetime",
"year": 2021,
"month": 3,
"day": 24,
"hour": 18,
"minute": 1,
"second": 32,
"microsecond": 583000
},
"ActionsEnabled": true,
"OKActions": [],
"AlarmActions": [],
"InsufficientDataActions": [],
"StateValue": "INSUFFICIENT_DATA",
"StateReason": "Insufficient Data: 5 datapoints were unknown.",
"StateReasonData": "{\"version\":\"1.0\",\"queryDate\":\"2022-09-27T10:05:12.193+0000\",\"statistic\":\"Average\",\"period\":3600,\"recentDatapoints\":[],\"threshold\":10.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2022-09-27T09:05:00.000+0000\"},{\"timestamp\":\"2022-09-27T08:05:00.000+0000\"},{\"timestamp\":\"2022-09-27T07:05:00.000+0000\"},{\"timestamp\":\"2022-09-27T06:05:00.000+0000\"},{\"timestamp\":\"2022-09-27T05:05:00.000+0000\"}]}",
"StateUpdatedTimestamp": {
"__class__": "datetime",
"year": 2022,
"month": 9,
"day": 27,
"hour": 10,
"minute": 5,
"second": 12,
"microsecond": 198000
},
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Dimensions": [],
"Period": 3600,
"EvaluationPeriods": 5,
"Threshold": 10.0,
"ComparisonOperator": "GreaterThanThreshold",
"StateTransitionedTimestamp": {
"__class__": "datetime",
"year": 2022,
"month": 9,
"day": 27,
"hour": 10,
"minute": 5,
"second": 12,
"microsecond": 198000
}
}
],
"ResponseMetadata": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"status_code": 200,
"data": {
"CompositeAlarms": [
{
"ActionsEnabled": true,
"AlarmActions": [
"arn:aws:sns:us-east-1:644160558196:test-xyz"
],
"AlarmArn": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:ExampleCompositeAlarm",
"AlarmConfigurationUpdatedTimestamp": {
"__class__": "datetime",
"year": 2024,
"month": 2,
"day": 16,
"hour": 16,
"minute": 32,
"second": 54,
"microsecond": 256000
},
"AlarmDescription": "Composite alarm based on c7n-test-alarm-tags-filter",
"AlarmName": "ExampleCompositeAlarm",
"AlarmRule": "ALARM(c7n-test-alarm-tags-filter)",
"InsufficientDataActions": [
"arn:aws:sns:us-east-1:644160558196:test-zyx"
],
"OKActions": [
"arn:aws:sns:us-east-1:644160558196:test-xyz"
],
"StateReason": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:ExampleCompositeAlarm was created and its alarm rule evaluates to OK",
"StateReasonData": "{\"triggeringAlarms\":[{\"arn\":\"arn:aws:cloudwatch:us-east-1:644160558196:alarm:c7n-test-alarm-tags-filter\",\"state\":{\"value\":\"INSUFFICIENT_DATA\",\"timestamp\":\"2022-09-27T10:05:12.198+0000\"}}]}",
"StateUpdatedTimestamp": {
"__class__": "datetime",
"year": 2024,
"month": 2,
"day": 16,
"hour": 16,
"minute": 32,
"second": 54,
"microsecond": 256000
},
"StateValue": "OK",
"StateTransitionedTimestamp": {
"__class__": "datetime",
"year": 2024,
"month": 2,
"day": 16,
"hour": 16,
"minute": 32,
"second": 54,
"microsecond": 256000
}
}
],
"MetricAlarms": [],
"ResponseMetadata": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"status_code": 200,
"data": {
"PaginationToken": "",
"ResourceTagMappingList": [
{
"ResourceARN": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:c7n-test-alarm-tags-filter",
"Tags": [
{
"Key": "some-tag",
"Value": "some-value"
},
{
"Key": "OwnerName",
"Value": "SomeName"
},
{
"Key": "pratyush",
"Value": "test"
}
]
}
],
"ResponseMetadata": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"status_code": 200,
"data": {
"PaginationToken": "",
"ResourceTagMappingList": [
{
"ResourceARN": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:ExampleCompositeAlarm",
"Tags": []
}
],
"ResponseMetadata": {}
}
}