@liflig/cdk 3.17.0 → 3.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -17,6 +17,7 @@ import boto3
|
|
|
17
17
|
logger = logging.getLogger()
|
|
18
18
|
logger.setLevel(logging.INFO)
|
|
19
19
|
|
|
20
|
+
|
|
20
21
|
def augment_strings_with_friendly_names(strings, friendly_names):
|
|
21
22
|
"""A helper method for augmenting various values (e.g., AWS account ID) in
|
|
22
23
|
a list of strings with a more friendly name"""
|
|
@@ -25,8 +26,15 @@ def augment_strings_with_friendly_names(strings, friendly_names):
|
|
|
25
26
|
# inside ARNs as this would look messy.This is a quite basic heuristic, but it should allow
|
|
26
27
|
# us to easily replace most relevant values (e.g., principal ID, account ID, etc.) with
|
|
27
28
|
# friendly names without a complicated regex.
|
|
28
|
-
pattern = re.compile(
|
|
29
|
-
|
|
29
|
+
pattern = re.compile(
|
|
30
|
+
"|".join([f"(?<!:)({re.escape(key)})(?!:)" for key in friendly_names])
|
|
31
|
+
)
|
|
32
|
+
return [
|
|
33
|
+
pattern.sub(
|
|
34
|
+
lambda m: m[0] + f" ({friendly_names[m.string[m.start() : m.end()]]})", s
|
|
35
|
+
)
|
|
36
|
+
for s in strings
|
|
37
|
+
]
|
|
30
38
|
|
|
31
39
|
|
|
32
40
|
def get_slack_payload_for_assume_role_event(event, friendly_names):
|
|
@@ -45,7 +53,9 @@ def get_slack_payload_for_assume_role_event(event, friendly_names):
|
|
|
45
53
|
role_arn = request_parameters.get("roleArn", "")
|
|
46
54
|
|
|
47
55
|
fallback = f"Sensitive role accessed in '{recipient_account_id}'"
|
|
48
|
-
pretext_messages = [
|
|
56
|
+
pretext_messages = [
|
|
57
|
+
f":warning: Sensitive role in `{recipient_account_id}` assumed by"
|
|
58
|
+
]
|
|
49
59
|
if principal_id.startswith("AIDA"):
|
|
50
60
|
pretext_messages.append("IAM user")
|
|
51
61
|
elif principal_id.startswith("AROA"):
|
|
@@ -68,7 +78,9 @@ def get_slack_payload_for_assume_role_event(event, friendly_names):
|
|
|
68
78
|
text = "\n".join(line for line in text if line)
|
|
69
79
|
|
|
70
80
|
try:
|
|
71
|
-
pretext, fallback, text = augment_strings_with_friendly_names(
|
|
81
|
+
pretext, fallback, text = augment_strings_with_friendly_names(
|
|
82
|
+
[pretext, fallback, text], friendly_names
|
|
83
|
+
)
|
|
72
84
|
except:
|
|
73
85
|
logger.exception("Failed to augment strings with friendly names")
|
|
74
86
|
return {
|
|
@@ -134,7 +146,9 @@ def get_fallback_slack_payload_for_event(
|
|
|
134
146
|
text = "\n".join(line for line in text if line)
|
|
135
147
|
|
|
136
148
|
try:
|
|
137
|
-
pretext, fallback, text = augment_strings_with_friendly_names(
|
|
149
|
+
pretext, fallback, text = augment_strings_with_friendly_names(
|
|
150
|
+
[pretext, fallback, text], friendly_names
|
|
151
|
+
)
|
|
138
152
|
except:
|
|
139
153
|
logger.exception("Failed to augment strings with friendly names")
|
|
140
154
|
|
|
@@ -203,9 +217,7 @@ def handler_event_transformer(event, context):
|
|
|
203
217
|
fallback_parse_behavior = os.environ.get("FALLBACK_PARSE_BEHAVIOR", "")
|
|
204
218
|
deduplicate_events = os.environ.get("DEDUPLICATE_EVENTS", "false") == "true"
|
|
205
219
|
|
|
206
|
-
friendly_names = get_augmented_friendly_names(
|
|
207
|
-
event, friendly_names
|
|
208
|
-
)
|
|
220
|
+
friendly_names = get_augmented_friendly_names(event, friendly_names)
|
|
209
221
|
|
|
210
222
|
if not event["detail-type"].endswith("via CloudTrail"):
|
|
211
223
|
logger.warn("Invalid event received")
|
|
@@ -19,26 +19,26 @@ def get_variables_from_parameters(namespace):
|
|
|
19
19
|
next_token = None
|
|
20
20
|
result = {}
|
|
21
21
|
|
|
22
|
-
prefix = f
|
|
22
|
+
prefix = f"/liflig-cdk/{namespace}/pipeline-variables/"
|
|
23
23
|
params = {
|
|
24
|
-
|
|
24
|
+
"Path": prefix,
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
while True:
|
|
28
28
|
if next_token is not None:
|
|
29
|
-
params[
|
|
29
|
+
params["NextToken"] = next_token
|
|
30
30
|
response = ssm.get_parameters_by_path(**params)
|
|
31
31
|
|
|
32
|
-
parameters = response[
|
|
32
|
+
parameters = response["Parameters"]
|
|
33
33
|
if len(parameters) == 0:
|
|
34
34
|
break
|
|
35
35
|
|
|
36
36
|
for parameter in parameters:
|
|
37
|
-
result[parameter[
|
|
37
|
+
result[parameter["Name"][len(prefix) :]] = parameter["Value"]
|
|
38
38
|
|
|
39
|
-
if
|
|
39
|
+
if "NextToken" not in response:
|
|
40
40
|
break
|
|
41
|
-
next_token = response[
|
|
41
|
+
next_token = response["NextToken"]
|
|
42
42
|
|
|
43
43
|
return result
|
|
44
44
|
|
|
@@ -67,7 +67,7 @@ def handler(event, context):
|
|
|
67
67
|
# Special variable that can be used when reading variables
|
|
68
68
|
# to ensure it is not stale. In the pipeline, variables
|
|
69
69
|
# will never be stale, but locally it can be.
|
|
70
|
-
|
|
70
|
+
"variablesTimestamp": now.isoformat(),
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
for file in files.get("Contents", []):
|
|
@@ -25,11 +25,15 @@ def handler(event, context):
|
|
|
25
25
|
|
|
26
26
|
def list_all_active_alarms(topic_arn: str) -> list[str]:
|
|
27
27
|
try:
|
|
28
|
-
response: dict = cloudwatch.describe_alarms(
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
response: dict = cloudwatch.describe_alarms(
|
|
29
|
+
AlarmTypes=["CompositeAlarm", "MetricAlarm"],
|
|
30
|
+
StateValue="ALARM",
|
|
31
|
+
ActionPrefix=topic_arn,
|
|
32
|
+
)
|
|
31
33
|
all_alarms = response["CompositeAlarms"] + response["MetricAlarms"]
|
|
32
|
-
names: list[str] = [
|
|
34
|
+
names: list[str] = [
|
|
35
|
+
alarm["AlarmName"] for alarm in all_alarms if alarm["ActionsEnabled"]
|
|
36
|
+
]
|
|
33
37
|
return names
|
|
34
38
|
except Exception as e:
|
|
35
39
|
print(f"Failed to list alarms: {e}")
|
|
@@ -68,9 +72,9 @@ def send_slack_notification(message: str, region: str, active_alarms: list[str])
|
|
|
68
72
|
{
|
|
69
73
|
"color": color,
|
|
70
74
|
"title_link": "https://console.aws.amazon.com/cloudwatch/home?region="
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
+ region
|
|
76
|
+
+ "#alarm:alarmFilter=ANY;name="
|
|
77
|
+
+ message["AlarmName"],
|
|
74
78
|
"fallback": f"{alarm_emojis.get(message['NewStateValue'], '')} {message['AlarmName']}: {alarm_description}",
|
|
75
79
|
"fields": [
|
|
76
80
|
{"title": "Alarm Name", "value": message["AlarmName"], "short": False},
|
|
@@ -86,23 +90,26 @@ def send_slack_notification(message: str, region: str, active_alarms: list[str])
|
|
|
86
90
|
{
|
|
87
91
|
"title": "State Transition",
|
|
88
92
|
"value": message.get("OldStateValue", "Unknown")
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
+ " -> "
|
|
94
|
+
+ message["NewStateValue"],
|
|
91
95
|
"short": False,
|
|
92
96
|
},
|
|
93
97
|
{
|
|
94
98
|
"title": "Link to Alarm",
|
|
95
99
|
"value": "https://console.aws.amazon.com/cloudwatch/home?region="
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
+ region
|
|
101
|
+
+ "#alarm:alarmFilter=ANY;name="
|
|
102
|
+
+ message["AlarmName"],
|
|
99
103
|
"short": False,
|
|
100
104
|
},
|
|
101
105
|
{
|
|
102
|
-
"title": "All active alarms "
|
|
103
|
-
|
|
106
|
+
"title": "All active alarms "
|
|
107
|
+
+ (alarm_emojis["ALARM"] if len(active_alarms) else ""),
|
|
108
|
+
"value": "\n".join(["- " + alarm for alarm in active_alarms])
|
|
109
|
+
if len(active_alarms)
|
|
110
|
+
else "None",
|
|
104
111
|
"short": False,
|
|
105
|
-
}
|
|
112
|
+
},
|
|
106
113
|
],
|
|
107
114
|
}
|
|
108
115
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liflig/cdk",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.18.1",
|
|
4
4
|
"description": "CDK library for Liflig",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
12
|
"watch": "tsc -w",
|
|
13
|
-
"test": "NODE_OPTIONS
|
|
13
|
+
"test": "NODE_OPTIONS='--experimental-vm-modules --enable-source-maps' jest --runInBand",
|
|
14
14
|
"lint": "biome check",
|
|
15
15
|
"lint:fix": "biome check --fix",
|
|
16
16
|
"format": "biome format --write",
|
|
17
|
+
"format:check": "biome format",
|
|
17
18
|
"semantic-release": "semantic-release",
|
|
18
19
|
"snapshots": "./scripts/create-snapshots.sh",
|
|
19
20
|
"docs": "typedoc src --out docs",
|
|
@@ -39,41 +40,40 @@
|
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
42
|
"@aws-cdk/assert": "2.68.0",
|
|
42
|
-
"@aws-sdk/client-cloudwatch-logs": "3.
|
|
43
|
-
"@aws-sdk/client-codebuild": "3.
|
|
44
|
-
"@aws-sdk/client-codepipeline": "3.
|
|
45
|
-
"@aws-sdk/client-ecs": "3.
|
|
46
|
-
"@aws-sdk/client-s3": "3.
|
|
47
|
-
"@aws-sdk/client-secrets-manager": "3.
|
|
48
|
-
"@aws-sdk/client-ses": "3.
|
|
49
|
-
"@aws-sdk/client-sesv2": "3.
|
|
50
|
-
"@aws-sdk/client-sfn": "3.
|
|
51
|
-
"@aws-sdk/client-ssm": "3.
|
|
52
|
-
"@aws-sdk/lib-storage": "3.
|
|
43
|
+
"@aws-sdk/client-cloudwatch-logs": "3.948.0",
|
|
44
|
+
"@aws-sdk/client-codebuild": "3.948.0",
|
|
45
|
+
"@aws-sdk/client-codepipeline": "3.948.0",
|
|
46
|
+
"@aws-sdk/client-ecs": "3.948.0",
|
|
47
|
+
"@aws-sdk/client-s3": "3.948.0",
|
|
48
|
+
"@aws-sdk/client-secrets-manager": "3.950.0",
|
|
49
|
+
"@aws-sdk/client-ses": "3.948.0",
|
|
50
|
+
"@aws-sdk/client-sesv2": "3.950.0",
|
|
51
|
+
"@aws-sdk/client-sfn": "3.948.0",
|
|
52
|
+
"@aws-sdk/client-ssm": "3.948.0",
|
|
53
|
+
"@aws-sdk/lib-storage": "3.948.0",
|
|
53
54
|
"@biomejs/biome": "2.3.8",
|
|
54
|
-
"@commitlint/cli": "20.
|
|
55
|
-
"@commitlint/config-conventional": "20.
|
|
55
|
+
"@commitlint/cli": "20.2.0",
|
|
56
|
+
"@commitlint/config-conventional": "20.2.0",
|
|
56
57
|
"@types/aws-lambda": "8.10.159",
|
|
57
58
|
"@types/jest": "30.0.0",
|
|
58
|
-
"@types/node": "24.10.
|
|
59
|
-
"aws-cdk": "2.
|
|
60
|
-
"aws-cdk-lib": "2.
|
|
61
|
-
"constructs": "10.4.
|
|
62
|
-
"esbuild": "0.27.
|
|
59
|
+
"@types/node": "24.10.2",
|
|
60
|
+
"aws-cdk": "2.1034.0",
|
|
61
|
+
"aws-cdk-lib": "2.232.1",
|
|
62
|
+
"constructs": "10.4.4",
|
|
63
|
+
"esbuild": "0.27.1",
|
|
63
64
|
"jest": "30.2.0",
|
|
64
65
|
"jest-cdk-snapshot": "2.3.6",
|
|
65
|
-
"lefthook": "2.0.
|
|
66
|
-
"npm-check-updates": "19.
|
|
66
|
+
"lefthook": "2.0.11",
|
|
67
|
+
"npm-check-updates": "19.2.0",
|
|
67
68
|
"semantic-release": "25.0.2",
|
|
68
|
-
"ts-jest": "29.4.
|
|
69
|
+
"ts-jest": "29.4.6",
|
|
69
70
|
"tsx": "4.21.0",
|
|
70
71
|
"typedoc": "0.28.15",
|
|
71
72
|
"typescript": "5.9.3"
|
|
72
73
|
},
|
|
73
74
|
"dependencies": {
|
|
74
|
-
"@capraconsulting/webapp-deploy-lambda": "2.5.
|
|
75
|
-
"aws-jwt-verify": "5.1.1"
|
|
76
|
-
"source-map-support": "0.5.21"
|
|
75
|
+
"@capraconsulting/webapp-deploy-lambda": "2.5.3",
|
|
76
|
+
"aws-jwt-verify": "5.1.1"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|
|
79
79
|
"aws-cdk-lib": "^2.0.0",
|