Skip to content

Commit 3e43c6e

Browse files
committed
Adding MSK/Kafka functions and ARN
1 parent fb29c61 commit 3e43c6e

File tree

10 files changed

+476
-0
lines changed

10 files changed

+476
-0
lines changed

src/compose_x_common/aws/application_autoscaling.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
from compose_x_common.aws import get_session
88
from compose_x_common.compose_x_common import keyisset, set_else_none
99

10+
SCHEDULED_ACTION_ARN_RE = (
11+
r"arn:aws(?:[a-z\-]+)?:autoscaling:(?P<region>[\w-]+):"
12+
r"(?P<accountid>\d{12}):scheduledAction:(?P<id>[\S]+)"
13+
)
14+
1015

1116
def list_all_scalable_targets(
1217
namespace=None, targets=None, next_token=None, session=None, **kwargs

src/compose_x_common/aws/arns.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from compose_x_common.aws.iam import IAM_ROLE_ARN_RE, IAM_USER_ARN_RE
1313
from compose_x_common.aws.kinesis import KINESIS_FIREHOSE_ARN_RE, KINESIS_STREAM_ARN_RE
1414
from compose_x_common.aws.kms import KMS_ALIAS_ARN_RE, KMS_KEY_ARN_RE
15+
from compose_x_common.aws.msk import MSK_CLUSTER_ARN_RE, MSK_CONFIGURATION_ARN_RE
1516
from compose_x_common.aws.neptune import NEPTUNE_DB_CLUSTER_ARN_RE
1617
from compose_x_common.aws.opensearch import OS_DOMAIN_ARN_RE
1718
from compose_x_common.aws.rds import RDS_DB_CLUSTER_ARN_RE, RDS_DB_INSTANCE_ARN_RE
@@ -53,6 +54,9 @@
5354
"AWS::ECS::Cluster": CLUSTER_ID_ARN_RE,
5455
"AWS::Route53::HostedZone": ZONE_ARN_NE,
5556
"AWS::ECS::Service": SERVICE_ARN_RE,
57+
"AWS::MSK::Cluster": MSK_CLUSTER_ARN_RE,
58+
"AWS::MSK::Configuration": MSK_CONFIGURATION_ARN_RE,
59+
"AWS::MSK::ServerlessCluster": MSK_CLUSTER_ARN_RE,
5660
}
5761

5862
ARNS_PER_TAGGINGAPI_TYPE = {
@@ -76,4 +80,5 @@
7680
"elasticache:cluster": CACHE_CLUSTER_ARN_RE,
7781
"firehose:deliverystream": KINESIS_FIREHOSE_ARN_RE,
7882
"ecs:service": SERVICE_ARN_RE,
83+
"kafka:cluster": MSK_CLUSTER_ARN_RE,
7984
}

src/compose_x_common/aws/kafka.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# SPDX-License-Identifier: MPL-2.0
2+
# Copyright 2020-2022 John Mille <[email protected]>
3+
4+
from .msk import *

src/compose_x_common/aws/msk.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# SPDX-License-Identifier: MPL-2.0
2+
# Copyright 2020-2022 John Mille <[email protected]>
3+
4+
"""AWS MSK Management"""
5+
6+
from __future__ import annotations
7+
8+
from typing import TYPE_CHECKING
9+
10+
if TYPE_CHECKING:
11+
from boto3.session import Session
12+
13+
import re
14+
15+
from compose_x_common.aws import get_session
16+
from compose_x_common.compose_x_common import keyisset
17+
18+
MSK_CLUSTER_ARN_RE = re.compile(
19+
r"arn:(?P<partition>[a-z\d\-]+):kafka:(?P<region>[a-z\d\-]+):(?P<account>[\d]{12})"
20+
r":cluster/(?P<id>(?P<name>[\w\-_]+)/(?P<uuid>[a-z0-9\-]+))$"
21+
)
22+
23+
MSK_CONFIGURATION_ARN_RE = re.compile(
24+
r"arn:(?P<partition>[a-z\d\-]+):kafka:(?P<region>[a-z\d\-]+):(?P<account>[\d]{12})"
25+
r":configuration/(?P<id>(?P<name>[\w\-_]+)/(?P<uuid>[a-z0-9\-]+))$"
26+
)
27+
28+
29+
def list_all_kafka_versions(
30+
versions: list = None, session: Session = None, **kwargs
31+
) -> list:
32+
"""
33+
Lists all the versions for MSK
34+
"""
35+
if versions is None:
36+
versions: list = []
37+
session = get_session(session)
38+
client = session.client("kafka")
39+
versions_r = client.list_kafka_versions(**kwargs)
40+
versions += versions_r["KafkaVersions"]
41+
if keyisset("NextToken", versions_r):
42+
kwargs.update({"NextToken": versions_r["NextToken"]})
43+
return list_all_kafka_versions(versions, session, **kwargs)
44+
return versions
45+
46+
47+
def list_all_kafka_configurations(
48+
configurations: list = None, session: Session = None, **kwargs
49+
) -> list:
50+
"""
51+
Lists all the configurations for MSK
52+
"""
53+
if configurations is None:
54+
configurations: list = []
55+
session = get_session(session)
56+
client = session.client("kafka")
57+
configurations_r = client.list_configurations(**kwargs)
58+
configurations += configurations_r["Configurations"]
59+
if keyisset("NextToken", configurations_r):
60+
kwargs.update({"NextToken": configurations_r["NextToken"]})
61+
return list_all_kafka_configurations(configurations, session, **kwargs)
62+
return configurations
63+
64+
65+
def list_all_kafka_clusters(
66+
clusters: list = None, session: Session = None, **kwargs
67+
) -> list:
68+
"""
69+
Lists all the clusters for MSK
70+
"""
71+
if clusters is None:
72+
clusters: list = []
73+
session = get_session(session)
74+
client = session.client("kafka")
75+
clusters_r = client.list_clusters(**kwargs)
76+
clusters += clusters_r["ClusterInfoList"]
77+
if keyisset("NextToken", clusters_r):
78+
kwargs.update({"NextToken": clusters_r["NextToken"]})
79+
return list_all_kafka_clusters(clusters, session, **kwargs)
80+
return clusters
81+
82+
83+
def list_all_kafka_clusters_v2(
84+
clusters: list = None, session: Session = None, **kwargs
85+
) -> list:
86+
"""
87+
Lists all the clusters for MSK
88+
"""
89+
if clusters is None:
90+
clusters: list = []
91+
session = get_session(session)
92+
client = session.client("kafka")
93+
clusters_r = client.list_clusters_v2(**kwargs)
94+
clusters += clusters_r["ClusterInfoList"]
95+
if keyisset("NextToken", clusters_r):
96+
kwargs.update({"NextToken": clusters_r["NextToken"]})
97+
return list_all_kafka_clusters(clusters, session, **kwargs)
98+
return clusters
99+
100+
101+
if __name__ == "__main__":
102+
print(list_all_kafka_clusters())
103+
print(list_all_kafka_clusters_v2())
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{
2+
"status_code": 200,
3+
"data": {
4+
"ResponseMetadata": {
5+
"RequestId": "a6cb5dcf-032d-4b21-980c-85b07d473da6",
6+
"HTTPStatusCode": 200,
7+
"HTTPHeaders": {
8+
"content-type": "application/json",
9+
"content-length": "757",
10+
"connection": "keep-alive",
11+
"date": "Fri, 04 Nov 2022 12:35:02 GMT",
12+
"x-amzn-requestid": "a6cb5dcf-032d-4b21-980c-85b07d473da6",
13+
"access-control-allow-origin": "*",
14+
"access-control-allow-headers": "Authorization,Date,X-Amz-Date,X-Amz-Security-Token,X-Amz-Target,content-type,x-amz-content-sha256,x-amz-user-agent,x-amzn-platform-id,x-amzn-trace-id",
15+
"x-amz-apigw-id": "bE4GkG1kjoEF3wg=",
16+
"access-control-allow-methods": "*",
17+
"access-control-expose-headers": "x-amzn-errortype,x-amzn-requestid,x-amzn-errormessage,x-amzn-trace-id,x-amz-apigw-id,date",
18+
"x-amzn-trace-id": "Root=1-636506f6-7b8c40b81db9d3a6773beeff",
19+
"access-control-max-age": "86400",
20+
"x-cache": "Miss from cloudfront",
21+
"via": "1.1 b7a69c767c9474faad515acbe4c0d5f8.cloudfront.net (CloudFront)",
22+
"x-amz-cf-pop": "LHR61-P2",
23+
"x-amz-cf-id": "VF145WplwZwNmOD1KGe7QHPTX2xdigd-OtBS9QgKPUMKK-iWsEOslw=="
24+
},
25+
"RetryAttempts": 0
26+
},
27+
"ClusterInfoList": [
28+
{
29+
"ClusterType": "SERVERLESS",
30+
"ClusterArn": "arn:aws:kafka:eu-west-1:000000000000:cluster/demo-cluster-1/d7e68213-0896-4839-80df-dea01b79750c-s1",
31+
"ClusterName": "demo-cluster-1",
32+
"CreationTime": {
33+
"__class__": "datetime",
34+
"year": 2022,
35+
"month": 11,
36+
"day": 4,
37+
"hour": 12,
38+
"minute": 31,
39+
"second": 14,
40+
"microsecond": 953000
41+
},
42+
"CurrentVersion": "K2EUQ1WTGCTBG2",
43+
"State": "ACTIVE",
44+
"Tags": {
45+
"Name": "demo-cluster-1"
46+
},
47+
"Serverless": {
48+
"VpcConfigs": [
49+
{
50+
"SubnetIds": [
51+
"subnet-08de98749006ee08b",
52+
"subnet-0d72d741d0d8e0ca7",
53+
"subnet-02ccce037ba06d362"
54+
],
55+
"SecurityGroupIds": [
56+
"sg-06405b62ddc1aa38c"
57+
]
58+
}
59+
],
60+
"ClientAuthentication": {
61+
"Sasl": {
62+
"Iam": {
63+
"Enabled": true
64+
}
65+
}
66+
}
67+
}
68+
}
69+
]
70+
}
71+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"status_code": 200,
3+
"data": {
4+
"ResponseMetadata": {
5+
"RequestId": "498a6cd6-9280-4600-b5a0-57231508f714",
6+
"HTTPStatusCode": 200,
7+
"HTTPHeaders": {
8+
"content-type": "application/json",
9+
"content-length": "29",
10+
"connection": "keep-alive",
11+
"date": "Fri, 04 Nov 2022 12:35:01 GMT",
12+
"x-amzn-requestid": "498a6cd6-9280-4600-b5a0-57231508f714",
13+
"access-control-allow-origin": "*",
14+
"access-control-allow-headers": "Authorization,Date,X-Amz-Date,X-Amz-Security-Token,X-Amz-Target,content-type,x-amz-content-sha256,x-amz-user-agent,x-amzn-platform-id,x-amzn-trace-id",
15+
"x-amz-apigw-id": "bE4GcGIFjoEFnWg=",
16+
"access-control-allow-methods": "*",
17+
"access-control-expose-headers": "x-amzn-errortype,x-amzn-requestid,x-amzn-errormessage,x-amzn-trace-id,x-amz-apigw-id,date",
18+
"x-amzn-trace-id": "Root=1-636506f5-0402ae5f483eb7a016182c30",
19+
"access-control-max-age": "86400",
20+
"x-cache": "Miss from cloudfront",
21+
"via": "1.1 22e421a47e59010b5e8eb6ae4d4bd7e4.cloudfront.net (CloudFront)",
22+
"x-amz-cf-pop": "LHR61-P2",
23+
"x-amz-cf-id": "gRajapMeIRceJXWlWJb9zFeT0IpSuact7pwjk1DVg2Q8rAPnpuhPgA=="
24+
},
25+
"RetryAttempts": 0
26+
},
27+
"ClusterInfoList": []
28+
}
29+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
{
2+
"status_code": 200,
3+
"data": {
4+
"ResponseMetadata": {
5+
"RequestId": "52e4d1ac-b381-4e5c-97db-e9fe97a90569",
6+
"HTTPStatusCode": 200,
7+
"HTTPHeaders": {
8+
"content-type": "application/json",
9+
"content-length": "620",
10+
"connection": "keep-alive",
11+
"date": "Fri, 04 Nov 2022 12:27:51 GMT",
12+
"x-amzn-requestid": "52e4d1ac-b381-4e5c-97db-e9fe97a90569",
13+
"access-control-allow-origin": "*",
14+
"access-control-allow-headers": "Authorization,Date,X-Amz-Date,X-Amz-Security-Token,X-Amz-Target,content-type,x-amz-content-sha256,x-amz-user-agent,x-amzn-platform-id,x-amzn-trace-id",
15+
"x-amz-apigw-id": "bE3DOExCDoEFdag=",
16+
"access-control-allow-methods": "*",
17+
"access-control-expose-headers": "x-amzn-errortype,x-amzn-requestid,x-amzn-errormessage,x-amzn-trace-id,x-amz-apigw-id,date",
18+
"x-amzn-trace-id": "Root=1-63650547-05ae7acd52a6dadb15f84662",
19+
"access-control-max-age": "86400",
20+
"x-cache": "Miss from cloudfront",
21+
"via": "1.1 08dc6f02f30e8ad9291872e7e3d5b658.cloudfront.net (CloudFront)",
22+
"x-amz-cf-pop": "LHR61-P2",
23+
"x-amz-cf-id": "adk4_tdtqmSAnl4kMq_On4v0j3n4SD1rLleHUfrvgQQPXg3sJCFEzQ=="
24+
},
25+
"RetryAttempts": 0
26+
},
27+
"Configurations": [
28+
{
29+
"Arn": "arn:aws:kafka:eu-west-1:000000000000:configuration/default-msk-282-tiered/7279bc96-b00f-4f72-9d4d-15f5f8fbde59-8",
30+
"CreationTime": {
31+
"__class__": "datetime",
32+
"year": 2022,
33+
"month": 11,
34+
"day": 4,
35+
"hour": 12,
36+
"minute": 14,
37+
"second": 34,
38+
"microsecond": 813000
39+
},
40+
"KafkaVersions": [],
41+
"LatestRevision": {
42+
"CreationTime": {
43+
"__class__": "datetime",
44+
"year": 2022,
45+
"month": 11,
46+
"day": 4,
47+
"hour": 12,
48+
"minute": 14,
49+
"second": 34,
50+
"microsecond": 813000
51+
},
52+
"Revision": 1
53+
},
54+
"Name": "default-msk-282-tiered",
55+
"State": "ACTIVE"
56+
},
57+
{
58+
"Arn": "arn:aws:kafka:eu-west-1:000000000000:configuration/default-msk-331/e44a32b9-4cba-4686-a1e4-b0e72fb1baa4-8",
59+
"CreationTime": {
60+
"__class__": "datetime",
61+
"year": 2022,
62+
"month": 11,
63+
"day": 4,
64+
"hour": 12,
65+
"minute": 14,
66+
"second": 14,
67+
"microsecond": 202000
68+
},
69+
"KafkaVersions": [],
70+
"LatestRevision": {
71+
"CreationTime": {
72+
"__class__": "datetime",
73+
"year": 2022,
74+
"month": 11,
75+
"day": 4,
76+
"hour": 12,
77+
"minute": 14,
78+
"second": 14,
79+
"microsecond": 202000
80+
},
81+
"Revision": 1
82+
},
83+
"Name": "default-msk-331",
84+
"State": "ACTIVE"
85+
}
86+
]
87+
}
88+
}

0 commit comments

Comments
 (0)