cmq 0.0.1__py3-none-any.whl

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.
Files changed (44) hide show
  1. cmq/__init__.py +0 -0
  2. cmq/aws/aws.py +256 -0
  3. cmq/aws/resource/__init__.py +0 -0
  4. cmq/aws/resource/address.py +12 -0
  5. cmq/aws/resource/alarm.py +18 -0
  6. cmq/aws/resource/cloudformation.py +10 -0
  7. cmq/aws/resource/cloudtrail.py +111 -0
  8. cmq/aws/resource/dynamodb.py +26 -0
  9. cmq/aws/resource/ec2.py +18 -0
  10. cmq/aws/resource/elasticache.py +26 -0
  11. cmq/aws/resource/elasticache_parameter_group.py +11 -0
  12. cmq/aws/resource/elasticache_replication_group.py +17 -0
  13. cmq/aws/resource/elasticache_subnet_group.py +11 -0
  14. cmq/aws/resource/function.py +28 -0
  15. cmq/aws/resource/kinesis.py +22 -0
  16. cmq/aws/resource/kms.py +28 -0
  17. cmq/aws/resource/kms_alias.py +16 -0
  18. cmq/aws/resource/log.py +20 -0
  19. cmq/aws/resource/log_event.py +19 -0
  20. cmq/aws/resource/log_stream.py +20 -0
  21. cmq/aws/resource/metric.py +69 -0
  22. cmq/aws/resource/rds.py +26 -0
  23. cmq/aws/resource/rds_parameter_group.py +24 -0
  24. cmq/aws/resource/resource_explorer.py +40 -0
  25. cmq/aws/resource/resource_group.py +28 -0
  26. cmq/aws/resource/role.py +19 -0
  27. cmq/aws/resource/s3.py +31 -0
  28. cmq/aws/resource/s3_object.py +16 -0
  29. cmq/aws/resource/sns.py +21 -0
  30. cmq/aws/resource/sqs.py +28 -0
  31. cmq/aws/resource/user.py +30 -0
  32. cmq/aws/resource/user_key.py +17 -0
  33. cmq/aws/session/__init__.py +0 -0
  34. cmq/aws/session/profile.py +62 -0
  35. cmq/base.py +480 -0
  36. cmq/base.pyi +99 -0
  37. cmq/cli.py +29 -0
  38. cmq/iterator.py +55 -0
  39. cmq/plugin.py +54 -0
  40. cmq-0.0.1.dist-info/LICENSE +201 -0
  41. cmq-0.0.1.dist-info/METADATA +194 -0
  42. cmq-0.0.1.dist-info/RECORD +44 -0
  43. cmq-0.0.1.dist-info/WHEEL +4 -0
  44. cmq-0.0.1.dist-info/entry_points.txt +35 -0
cmq/__init__.py ADDED
File without changes
cmq/aws/aws.py ADDED
@@ -0,0 +1,256 @@
1
+ import boto3
2
+
3
+ from botocore.exceptions import ClientError
4
+ from datetime import datetime, timedelta
5
+ from functools import partial
6
+ from matplotlib import pyplot as plt
7
+ from typing import Any
8
+
9
+ from cmq.base import Resource
10
+ from cmq.iterator import UnknownSizeIterator, InfiniteAtpbar, Atpbar
11
+
12
+
13
+ class AWSClientInterface:
14
+
15
+ def __init__(self):
16
+ self._service = ""
17
+ self._list_function = ""
18
+ self._list_key = ""
19
+ self._list_parameters = {}
20
+ self._list_paginated = True
21
+ self._includes = []
22
+
23
+ @property
24
+ def _desc(self) -> str:
25
+ return f"{self._service}_{self._resource}"
26
+
27
+ def __call__(self, **kwargs) -> "AWSClientInterface":
28
+ self._list_parameters = kwargs
29
+ return self
30
+
31
+ def get_client(self, context, service = None) -> boto3.client:
32
+ return context["aws_session"].client(service or self._service)
33
+
34
+ def get_parameters(self, context: dict) -> dict:
35
+ return self._list_parameters
36
+
37
+ def traverse(self, context: dict) -> None:
38
+ for resource in self.bar(context, self.get(context), desc=f"{self._desc} traverse"):
39
+ context.update({
40
+ f"{self._desc}": resource
41
+ })
42
+ self._traverse(context)
43
+
44
+ def get_paged_results(self, page) -> list:
45
+ return page.get(self._list_key, []) if self._list_key else self._get_results(page)
46
+
47
+ def _get_pages(self, context) -> Any:
48
+ client = self.get_client(context)
49
+ paginator = client.get_paginator(self._list_function)
50
+ return paginator.paginate(**self.get_parameters(context))
51
+
52
+ def _get(self, context) -> list:
53
+ resources = []
54
+ try:
55
+ if self._list_paginated:
56
+ resources = self.paginate(context)
57
+ resources = [r if isinstance(r, dict) else {"resource": r} for r in resources]
58
+ else:
59
+ client = self.get_client(context)
60
+ page = getattr(client, self._list_function)(**self.get_parameters(context))
61
+ resources = self.get_paged_results(page)
62
+
63
+ # Include additional information in the resources
64
+ for include in self._includes:
65
+ include(context, resources)
66
+
67
+ return resources
68
+ except Exception as ex:
69
+ return [{"error": str(ex)}]
70
+
71
+ def get(self, context):
72
+ resources = self._get(context)
73
+ return self._get_attr(self._exclude(resources))
74
+
75
+ def _get_results(self, page) -> list | None:
76
+ for value in page.values():
77
+ if isinstance(value, list):
78
+ return value
79
+ return None
80
+
81
+
82
+ class TagResourceInterface:
83
+
84
+ def __init__(self):
85
+ self._tag_function = ""
86
+ self._tag_function_key = ""
87
+ self._tag_resource_key = ""
88
+
89
+ def tags(self) -> "TagResourceInterface":
90
+ self._includes.append(self._tag_resources)
91
+ return self
92
+
93
+ def _get_tag_resource_identifier(self, context, resource) -> str:
94
+ return resource[self._tag_resource_key]
95
+
96
+ def _tag_resources(self, context, resources):
97
+ if self._tag_function:
98
+ client = self.get_client(context)
99
+ for resource in self.bar(context, resources, "tags"):
100
+ if isinstance(resource, dict):
101
+ try:
102
+ tag_function = getattr(client, self._tag_function)
103
+ tag_identifier = self._get_tag_resource_identifier(context, resource)
104
+ result = tag_function(**{self._tag_function_key: tag_identifier})
105
+ result_tags = self._get_tag_from_result(result)
106
+ tags = self._format_tags(result_tags)
107
+ resource.update(tags)
108
+ except ClientError as ex:
109
+ resource.update({"Tags": {"error": str(ex)}})
110
+
111
+ def _get_tag_from_result(self, result) -> list:
112
+ return self._get_results(result) or []
113
+
114
+ def _format_tags(self, tags) -> dict:
115
+ return {"Tags": {tag["Key"]: tag["Value"] for tag in tags}}
116
+
117
+
118
+ class DescribeResourceInterface:
119
+
120
+ def __init__(self):
121
+ self._describe_function = ""
122
+ self._describe_function_key = ""
123
+ self._describe_resource_key = ""
124
+
125
+ def describe(self) -> "DescribeResourceInterface":
126
+ self._includes.append(self._describe_resources)
127
+ return self
128
+
129
+ def _get_describe_resource_identifier(self, context, resource) -> str:
130
+ return resource[self._describe_resource_key]
131
+
132
+ def _describe_resources(self, context, resources):
133
+ if self._describe_function:
134
+ client = self.get_client(context)
135
+ for resource in self.bar(context, resources, "describe"):
136
+ if isinstance(resource, dict):
137
+ try:
138
+ describe_function = getattr(client, self._describe_function)
139
+ describe_identifier = self._get_describe_resource_identifier(context, resource)
140
+ details = describe_function(**{self._describe_function_key: describe_identifier})
141
+ resource.update({"Describe": details})
142
+ except ClientError as ex:
143
+ resource.update({"Describe": {"error": str(ex)}})
144
+
145
+
146
+ class MetricResourceInterface:
147
+
148
+ def __init__(self):
149
+ self._metric_namespace = ""
150
+ self._metric_dimension_name = ""
151
+ self._metric_dimension_resource_key = ""
152
+
153
+ def _format_parameters(self,
154
+ statistic: str,
155
+ namespace: str, metric_name: str,
156
+ dimensions: dict = {},
157
+ period: int = 60*60, unit: str = "Count",
158
+ start_time: datetime = None, end_time: datetime = None) -> dict:
159
+ # Set default parameter values
160
+ start_time = start_time or datetime.today() - timedelta(days=90)
161
+ end_time = end_time or datetime.today()
162
+ return {
163
+ "MetricDataQueries": [{
164
+ "Id": f"CMQ_{metric_name}",
165
+ "MetricStat": {
166
+ "Metric": {
167
+ "Namespace": namespace,
168
+ "MetricName": metric_name,
169
+ "Dimensions": [
170
+ {"Name": k, "Value": v}
171
+ for k, v in dimensions.items()
172
+ ]
173
+ },
174
+ "Period": period,
175
+ "Stat": statistic,
176
+ "Unit": unit
177
+ },
178
+ "Label": unit,
179
+ "ReturnData": True,
180
+ }],
181
+ "StartTime": start_time,
182
+ "EndTime": end_time
183
+ }
184
+
185
+ def get_metric_data(self, results, context, **kwargs):
186
+ client = self.get_client(context, "cloudwatch")
187
+ dimensions = {self._metric_dimension_name: context[f"{self._desc}"][self._metric_dimension_resource_key]}
188
+ parameters = self._format_parameters(
189
+ namespace=self._metric_namespace,
190
+ dimensions=dimensions,
191
+ **kwargs
192
+ )
193
+ response = dimensions.copy()
194
+ paginator = client.get_paginator("get_metric_data")
195
+
196
+ for page in self.bar(context, paginator.paginate(**parameters), desc=f"metrics {dimensions[self._metric_dimension_name]}"):
197
+ for metric in page["MetricDataResults"]:
198
+ for key, value in metric.items():
199
+ if key in response and isinstance(value, list):
200
+ response[key].extend(value)
201
+ else:
202
+ response[key] = value
203
+ account_list = results.setdefault(context["session_name"], [])
204
+ account_list.append(response)
205
+
206
+ def metric(self, **kwargs) -> dict:
207
+ if not self._metric_namespace:
208
+ exit(f"Metric namespace not defined for {self._service}")
209
+
210
+ results: dict = {}
211
+ self._perform_action(partial(self.get_metric_data, results, **kwargs))
212
+ return results
213
+
214
+ def plot(self, unit_factor=1, **kwargs) -> None:
215
+ resources = self.metric(**kwargs)
216
+
217
+ plt.clf()
218
+ for metrics in resources.values():
219
+ for metric in metrics:
220
+ timestamps = metric["Timestamps"]
221
+ values = [value/unit_factor for value in metric["Values"]]
222
+ plt.plot(timestamps, values, label=metric[self._metric_dimension_resource_key])
223
+ plt.title(f"{self._resource} {kwargs['statistic']} {kwargs['metric_name']}")
224
+ plt.legend(loc='best')
225
+ plt.show()
226
+
227
+
228
+ class AWSResource(TagResourceInterface, DescribeResourceInterface, MetricResourceInterface, AWSClientInterface, Resource):
229
+
230
+ def __init__(self, parent=None):
231
+ Resource.__init__(self, parent)
232
+ AWSClientInterface.__init__(self)
233
+ TagResourceInterface.__init__(self)
234
+ DescribeResourceInterface.__init__(self)
235
+ MetricResourceInterface.__init__(self)
236
+
237
+ def bar(self, context, resources, desc: str = "", leave=True):
238
+ if not self.enable_console():
239
+ return resources
240
+ desc = f"{context['session_name']: <20} {self._service} {desc}"
241
+ if not getattr(resources, "__len__", None):
242
+ resources = UnknownSizeIterator(resources)
243
+ return InfiniteAtpbar(resources, name=desc, len_=len(resources))
244
+ else:
245
+ return Atpbar(resources, name=desc, len_=len(resources))
246
+
247
+ def _get_pages(self, context) -> Any:
248
+ return self.bar(context, super()._get_pages(context), desc=f"{self._desc} get_pages")
249
+
250
+ def _list(self, results, context) -> None:
251
+ results.append(context[f"{self._desc}"])
252
+
253
+ def _dict(self, results, context) -> None:
254
+ account_list = results.setdefault(context["session_name"], [])
255
+ account_list.append(context.get(f"{self._desc}"))
256
+
File without changes
@@ -0,0 +1,12 @@
1
+ from cmq.aws.aws import AWSResource
2
+
3
+
4
+ class address(AWSResource):
5
+
6
+ def __init__(self, parent=None):
7
+ super().__init__(parent)
8
+ self._service = "ec2"
9
+ self._resource = "address"
10
+ self._list_function = "describe_addresses"
11
+ self._list_key = "Addresses"
12
+ self._list_paginated = False
@@ -0,0 +1,18 @@
1
+ from typing import Any
2
+ from cmq.aws.aws import AWSResource
3
+
4
+
5
+ class alarm(AWSResource):
6
+
7
+ def __init__(self, parent=None):
8
+ super().__init__(parent)
9
+ self._service = "cloudwatch"
10
+ self._resource = "alarm"
11
+ self._list_function = "describe_alarms"
12
+ self._list_key = "MetricAlarms"
13
+
14
+ self._tag_function = "list_tags_for_resource"
15
+ self._tag_function_key = "ResourceARN"
16
+
17
+ def _get_tag_resource_identifier(self, context: dict[str, Any], resource: dict[str, Any]) -> str:
18
+ return resource["AlarmArn"]
@@ -0,0 +1,10 @@
1
+ from cmq.aws.aws import AWSResource
2
+
3
+
4
+ class cloudformation(AWSResource):
5
+
6
+ def __init__(self, parent=None):
7
+ super().__init__(parent)
8
+ self._service = "cloudformation"
9
+ self._resource = "stack"
10
+ self._list_function = "list_stacks"
@@ -0,0 +1,111 @@
1
+ import json
2
+ from datetime import datetime, timedelta, timezone
3
+ from cmq.aws.aws import AWSResource
4
+
5
+
6
+ class cloudtrail(AWSResource):
7
+
8
+ def __init__(self, parent=None):
9
+ super().__init__(parent)
10
+ self._service = "cloudtrail"
11
+ self._resource = "event"
12
+ self._list_function = "lookup_events"
13
+ self._transformers = {"CloudTrailEvent": json.loads}
14
+
15
+ def event_name(self, event_name: str) -> "cloudtrail":
16
+ """
17
+ Sets the event name for filtering events.
18
+
19
+ Args:
20
+ event_name (str): The event name to filter by.
21
+
22
+ Returns:
23
+ cloudtrail: The cloudtrail object for method chaining.
24
+ """
25
+ lookup = self._list_parameters.setdefault("LookupAttributes", [])
26
+ lookup.append({"AttributeKey": "EventName", "AttributeValue": event_name})
27
+ return self
28
+
29
+ def event_source(self, event_source: str) -> "cloudtrail":
30
+ """
31
+ Sets the event source for filtering events.
32
+
33
+ Args:
34
+ event_source (str): The event source to filter by.
35
+
36
+ Returns:
37
+ cloudtrail: The cloudtrail object for method chaining.
38
+ """
39
+ lookup = self._list_parameters.setdefault("LookupAttributes", [])
40
+ lookup.append({"AttributeKey": "EventSource", "AttributeValue": event_source})
41
+ return self
42
+
43
+ def resource_name(self, resource_name: str) -> "cloudtrail":
44
+ """
45
+ Sets the resource name for filtering events.
46
+
47
+ Args:
48
+ resource_name (str): The resource name to filter by.
49
+
50
+ Returns:
51
+ cloudtrail: The cloudtrail object for method chaining.
52
+ """
53
+ lookup = self._list_parameters.setdefault("LookupAttributes", [])
54
+ lookup.append({"AttributeKey": "ResourceName", "AttributeValue": resource_name})
55
+ return self
56
+
57
+ def user_name(self, user_name: str) -> "cloudtrail":
58
+ """
59
+ Sets the user name for filtering events.
60
+
61
+ Args:
62
+ user_name (str): The user name to filter by.
63
+
64
+ Returns:
65
+ cloudtrail: The cloudtrail object for method chaining.
66
+ """
67
+ lookup = self._list_parameters.setdefault("LookupAttributes", [])
68
+ lookup.append({"AttributeKey": "Username", "AttributeValue": user_name})
69
+ return self
70
+
71
+ def access_key(self, access_key: str) -> "cloudtrail":
72
+ """
73
+ Sets the access key for filtering events.
74
+
75
+ Args:
76
+ access_key (str): The access key to filter by.
77
+
78
+ Returns:
79
+ cloudtrail: The cloudtrail object for method chaining.
80
+ """
81
+ lookup = self._list_parameters.setdefault("LookupAttributes", [])
82
+ lookup.append({"AttributeKey": "AccessKeyId", "AttributeValue": access_key})
83
+ return self
84
+
85
+ def event_time(self, start_time: datetime, end_time: datetime) -> "cloudtrail":
86
+ """
87
+ Sets the event time range for filtering events.
88
+
89
+ Args:
90
+ start_time (datetime): The start time of the event range.
91
+ end_time (datetime): The end time of the event range.
92
+
93
+ Returns:
94
+ cloudtrail: The cloudtrail object for method chaining.
95
+ """
96
+ self._list_parameters.update({"StartTime": start_time, "EndTime": end_time})
97
+ return self
98
+
99
+ def last(self, **kwargs: dict[str, int]) -> "cloudtrail":
100
+ """
101
+ Sets the number of events to retrieve.
102
+
103
+ Args:
104
+ **kwargs: The keyword arguments for the timedelta.
105
+
106
+ Returns:
107
+ cloudtrail: The cloudtrail object for method chaining.
108
+ """
109
+ self._list_parameters.update({"StartTime": datetime.now(tz=timezone.utc) - timedelta(**kwargs),
110
+ "EndTime": datetime.now(tz=timezone.utc)})
111
+ return self
@@ -0,0 +1,26 @@
1
+ from typing import Any
2
+ from cmq.aws.aws import AWSResource
3
+
4
+
5
+ class dynamodb(AWSResource):
6
+
7
+ def __init__(self, parent=None):
8
+ super().__init__(parent)
9
+ self._service = "dynamodb"
10
+ self._resource = "dynamodb"
11
+ self._list_function = "list_tables"
12
+
13
+ self._describe_function = "describe_table"
14
+ self._describe_function_key = "TableName"
15
+ self._describe_resource_key = "resource"
16
+
17
+ self._tag_function = "list_tags_of_resource"
18
+ self._tag_function_key = "ResourceArn"
19
+ self._tag_resource_key = "resource"
20
+
21
+ self._metric_namespace = "AWS/DynamoDB"
22
+ self._metric_dimension_name = "TableName"
23
+ self._metric_dimension_resource_key = "resource"
24
+
25
+ def _get_tag_resource_identifier(self, context: dict[str, Any], resource) -> str:
26
+ return f"arn:aws:dynamodb:{context['aws_region']}:{context['aws_account']}:table/{resource['resource']}"
@@ -0,0 +1,18 @@
1
+ from cmq.aws.aws import AWSResource
2
+
3
+
4
+ class ec2(AWSResource):
5
+
6
+ def __init__(self, parent=None):
7
+ super().__init__(parent)
8
+ self._service = "ec2"
9
+ self._resource = "instance"
10
+ self._list_function = "describe_instances"
11
+
12
+ def _get_results(self, page) -> list | None:
13
+ instances = []
14
+ reservations = page.get("Reservations", [])
15
+ for reservation in reservations:
16
+ for instance in reservation.get("Instances", []):
17
+ instances.append(instance)
18
+ return instances
@@ -0,0 +1,26 @@
1
+ from typing import Any
2
+ from cmq.aws.aws import AWSResource
3
+ from cmq.aws.resource.elasticache_parameter_group import elasticache_parameter_group
4
+
5
+
6
+ class elasticache(AWSResource):
7
+
8
+ def __init__(self, parent=None):
9
+ super().__init__(parent)
10
+ self._service = "elasticache"
11
+ self._resource = "elasticache"
12
+ self._list_function = "describe_cache_clusters"
13
+ self._list_key = "CacheClusters"
14
+
15
+ self._tag_function = "list_tags_for_resource"
16
+ self._tag_function_key = "ResourceName"
17
+
18
+ self._metric_namespace = "AWS/ElastiCache"
19
+ self._metric_dimension_name = "CacheClusterId"
20
+ self._metric_dimension_resource_key = "CacheClusterId"
21
+
22
+ def parameter_group(self) -> AWSResource:
23
+ return elasticache_parameter_group(self)
24
+
25
+ def _get_tag_resource_identifier(self, context: dict[str, Any], resource: dict[str, Any]) -> str:
26
+ return resource["ARN"]
@@ -0,0 +1,11 @@
1
+ from cmq.aws.aws import AWSResource
2
+
3
+
4
+ class elasticache_parameter_group(AWSResource):
5
+
6
+ def __init__(self, parent=None):
7
+ super().__init__(parent)
8
+ self._service = "elasticache"
9
+ self._resource = "elasticache_parameter_group"
10
+ self._list_function = "describe_cache_parameter_groups"
11
+ self._list_key = "CacheParameterGroups"
@@ -0,0 +1,17 @@
1
+ from typing import Any
2
+ from cmq.aws.aws import AWSResource
3
+
4
+
5
+ class elasticache_replication_group(AWSResource):
6
+
7
+ def __init__(self, parent=None):
8
+ super().__init__(parent)
9
+ self._service = "elasticache"
10
+ self._resource = "elasticache_replication_group"
11
+ self._list_function = "describe_replication_groups"
12
+ self._list_key = "ReplicationGroups"
13
+ self._tag_function = "list_tags_for_resource"
14
+ self._tag_function_key = "ResourceName"
15
+
16
+ def _get_tag_resource_identifier(self, context: dict[str, Any], resource: dict[str, Any]) -> str:
17
+ return resource["ARN"]
@@ -0,0 +1,11 @@
1
+ from cmq.aws.aws import AWSResource
2
+
3
+
4
+ class elasticache_subnet_group(AWSResource):
5
+
6
+ def __init__(self, parent=None):
7
+ super().__init__(parent)
8
+ self._service = "elasticache"
9
+ self._resource = "elasticache_subnet_group"
10
+ self._list_function = "describe_cache_subnet_groups"
11
+ self._list_key = "CacheSubnetGroups"
@@ -0,0 +1,28 @@
1
+ from typing import Any
2
+ from cmq.aws.aws import AWSResource
3
+
4
+
5
+ class function(AWSResource):
6
+
7
+ def __init__(self, parent=None):
8
+ super().__init__(parent)
9
+ self._service = "lambda"
10
+ self._resource = "function"
11
+ self._list_function = "list_functions"
12
+ self._list_key = "Functions"
13
+
14
+ self._tag_function = "list_tags"
15
+ self._tag_function_key = "Resource"
16
+
17
+ self._metric_namespace = "AWS/Lambda"
18
+ self._metric_dimension_name = "FunctionName"
19
+ self._metric_dimension_resource_key = "FunctionName"
20
+
21
+ def _get_tag_resource_identifier(self, context: dict[str, Any], resource: dict[str, Any]) -> str:
22
+ return resource["FunctionArn"]
23
+
24
+ def _get_tag_from_result(self, result):
25
+ return result.get("Tags", {})
26
+
27
+ def _format_tags(self, tags) -> dict:
28
+ return {"Tags": tags}
@@ -0,0 +1,22 @@
1
+ from typing import Any
2
+ from cmq.aws.aws import AWSResource
3
+
4
+
5
+ class kinesis(AWSResource):
6
+
7
+ def __init__(self, parent=None):
8
+ super().__init__(parent)
9
+ self._service = "kinesis"
10
+ self._resource = "kinesis"
11
+ self._list_function = "list_streams"
12
+ self._list_key = "StreamSummaries"
13
+
14
+ self._tag_function = "list_tags_for_stream"
15
+ self._tag_function_key = "StreamARN"
16
+
17
+ self._metric_namespace = "AWS/Kinesis"
18
+ self._metric_dimension_name = "StreamName"
19
+ self._metric_dimension_resource_key = "StreamName"
20
+
21
+ def _get_tag_resource_identifier(self, context: dict[str, Any], resource: dict[str, Any]) -> str:
22
+ return resource["StreamARN"]
@@ -0,0 +1,28 @@
1
+ from typing import Any
2
+ from cmq.aws.aws import AWSResource
3
+ from cmq.aws.resource.kms_alias import kms_alias
4
+
5
+
6
+ class kms(AWSResource):
7
+
8
+ def __init__(self, parent=None):
9
+ super().__init__(parent)
10
+ self._service = "kms"
11
+ self._resource = "kms"
12
+ self._list_function = "list_keys"
13
+
14
+ self._tag_function = "list_resource_tags"
15
+ self._tag_function_key = "KeyId"
16
+
17
+ self._describe_function = "describe_key"
18
+ self._describe_function_key = "KeyId"
19
+ self._describe_resource_key = "KeyId"
20
+
21
+ def _get_tag_resource_identifier(self, context: dict[str, Any], resource) -> str:
22
+ return resource["KeyId"]
23
+
24
+ def _format_tags(self, tags) -> dict:
25
+ return {"Tags": {tag["TagKey"]: tag["TagValue"] for tag in tags}}
26
+
27
+ def aliases(self) -> AWSResource:
28
+ return kms_alias(self)
@@ -0,0 +1,16 @@
1
+ from cmq.aws.aws import AWSResource
2
+
3
+
4
+ class kms_alias(AWSResource):
5
+
6
+ def __init__(self, parent=None):
7
+ super().__init__(parent)
8
+ self._service = "kms"
9
+ self._resource = "kms_alias"
10
+ self._list_function = "list_aliases"
11
+
12
+ def get_parameters(self, context: dict) -> dict:
13
+ parameters = self._list_parameters.copy()
14
+ if 'kms_kms' in context:
15
+ parameters["KeyId"] = context["kms_kms"]["KeyId"]
16
+ return parameters
@@ -0,0 +1,20 @@
1
+ from cmq.aws.aws import AWSResource
2
+ from cmq.aws.resource.log_stream import log_stream
3
+ from cmq.aws.resource.log_event import log_event
4
+
5
+
6
+ class log(AWSResource):
7
+
8
+ def __init__(self, parent=None):
9
+ super().__init__(parent)
10
+ self._service = "logs"
11
+ self._resource = "log-group"
12
+ self._list_function = "describe_log_groups"
13
+
14
+ @property
15
+ def stream(self) -> log_stream:
16
+ return log_stream(self)
17
+
18
+ @property
19
+ def event(self, **kwargs) -> log_event:
20
+ return log_event(self).__call__(**kwargs)
@@ -0,0 +1,19 @@
1
+ from cmq.aws.aws import AWSResource
2
+
3
+
4
+ class log_event(AWSResource):
5
+
6
+ def __init__(self, parent=None):
7
+ super().__init__(parent)
8
+ self._service = "logs"
9
+ self._resource = "log-event"
10
+ self._list_function = "filter_log_events"
11
+ self._list_paginated = False
12
+
13
+ def get_parameters(self, context: dict) -> dict:
14
+ parameters = self._list_parameters.copy()
15
+ if 'logs_log-group' in context:
16
+ parameters["logGroupName"] = context["logs_log-group"]["logGroupName"]
17
+ if 'logs_log-stream' in context:
18
+ parameters["logStreamNames"] = [context["logs_log-stream"]["logStreamName"]]
19
+ return parameters