Skip to content

Commit

Permalink
aws - cloud watch alarm - add a filter for determining if part of a c…
Browse files Browse the repository at this point in the history
…omposite alarm (#9300)
  • Loading branch information
timmygrable committed Feb 23, 2024
1 parent 7952c6c commit ea06851
Show file tree
Hide file tree
Showing 10 changed files with 386 additions and 1 deletion.
33 changes: 32 additions & 1 deletion c7n/resources/cw.py
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)

child_alarm_names = set()
# Loop through, find child alarm names
for rule in composite_alarm_rules:
names = self.extract_alarm_names_from_rule(rule)
child_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'] in child_alarm_names]

return [r for r in resources if r['AlarmName'] not in child_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
@@ -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": {}
}
}
@@ -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": {}
}
}
@@ -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": {}
}
}
@@ -0,0 +1,13 @@
{
"status_code": 200,
"data": {
"PaginationToken": "",
"ResourceTagMappingList": [
{
"ResourceARN": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:ExampleCompositeAlarm",
"Tags": []
}
],
"ResponseMetadata": {}
}
}
@@ -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": {}
}
}
@@ -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": {}
}
}
@@ -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": {}
}
}
@@ -0,0 +1,13 @@
{
"status_code": 200,
"data": {
"PaginationToken": "",
"ResourceTagMappingList": [
{
"ResourceARN": "arn:aws:cloudwatch:us-east-1:644160558196:alarm:ExampleCompositeAlarm",
"Tags": []
}
],
"ResponseMetadata": {}
}
}

0 comments on commit ea06851

Please sign in to comment.