-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathaws_resource.py
165 lines (152 loc) · 6.88 KB
/
aws_resource.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
from abc import ABC, abstractmethod
from itertools import filterfalse
class Resource(ABC):
def __init__(self, input_file: dict):
self.template = list()
self.input_file: dict = input_file
self.is_elbv2 = False
self.is_cf = False
self.is_elastic_cache = False
self.is_s3 = False
@abstractmethod
def write_template(self) -> list:
pass
@abstractmethod
def _read_template(self):
pass
def _data_processing(self, namespace: str, dimension_value: str):
for widgets in self.template:
if widgets["type"] == "metric":
metric = widgets["properties"]["metrics"][0]
widgets["properties"]["metrics"] = []
resources = self.input_file[namespace]["Resources"]
for region in resources:
for resource in resources[region]:
if self.is_elbv2:
if (
metric[1] in ("UnHealthyHostCount", "HealthyHostCount")
and "TargetGroup" not in resource
):
continue # There is not target group in the input, skip it
else:
new_widget_list = self._get_lb_metric(
metric, resource, region
)
widgets["properties"]["metrics"] += new_widget_list
elif self.is_cf:
new_widget = self._get_cf_metric(metric, resource)
widgets["properties"]["metrics"].append(new_widget)
elif self.is_elastic_cache:
new_widget = self._get_elastic_cache_metric(
metric, resource, region
)
widgets["properties"]["metrics"].append(new_widget)
elif self.is_s3:
new_widget = self._get_s3_metric(metric, resource, region)
widgets["properties"]["metrics"].append(new_widget)
else:
widgets["properties"]["metrics"].append(
[
metric[0], # Namespace
metric[1], # MetricName
metric[2], # DimensionName
resource[dimension_value], # DimensionValue
{"region": region},
]
)
# We specify regions under the scope of a metric instead of a widget
# widgets["properties"].pop("region", None)
# Fix Bug as CW still need region field at properties level to save dashboard
widgets["properties"]["region"] = region
# widgets["properties"]["title"] += " ({})".format(region)
# we have to iterate the filled template again to check for empty metrics, and remove widgets if metrics are empty.
for widgets in self.template[:]:
if widgets["type"] == "metric":
if not widgets["properties"]["metrics"]:
self.template.remove(widgets)
# ALB/NLB has different dimensions between different metrics
def _get_lb_metric(self, metric_attr: list, resource: dict, region: str) -> list:
if metric_attr[1] in ("UnHealthyHostCount", "HealthyHostCount"):
TargetGroupList = []
for tg in resource["TargetGroup"]:
TargetGroupList.append(
[
metric_attr[0], # Namespace
metric_attr[1], # MetricName
metric_attr[2], # TargetGroup
tg, # TargetGroup ID
metric_attr[4], # LoadBalancer
resource["LoadBalancer"], # LoadBalancer ID
{"region": region},
]
)
return TargetGroupList
elif metric_attr[1] == "RequestCount":
return [
[
metric_attr[0], # Namespace
metric_attr[1], # MetricName
metric_attr[2], # TargetGroup
resource["LoadBalancer"], # TargetGroup ID,
{"region": region},
]
]
else:
return [
[
metric_attr[0], # Namespace
metric_attr[1], # MetricName
metric_attr[2], # TargetGroup
resource["LoadBalancer"], # LoadBalancer ID
{"region": region},
]
]
# CloudFront has multiple Dimensions
def _get_cf_metric(self, metric_attr: list, resource: dict) -> list:
return [
metric_attr[0], # Namespace
metric_attr[1], # MetricName
metric_attr[2], # DimensionName1
metric_attr[3], # DimensionValue1
metric_attr[4], # DimensionName2
resource["DistributionId"], # DimensionValue2
{"region": "us-east-1"}, # CloudFront metric only has one region "us-east-1"
]
def _get_elastic_cache_metric(
self, metric_attr: list, resource: dict, region: str
) -> list:
if metric_attr[1] in (
"FreeableMemory",
"NetworkBytesOut",
"CurrConnections",
"ReplicationLag",
):
return [
metric_attr[0], # Namespace
metric_attr[1], # MetricName
metric_attr[2], # CacheClusterId
resource["CacheClusterId"], # LoadBalancer ID
{"region": region},
]
else:
return [
metric_attr[0], # Namespace
metric_attr[1], # MetricName
metric_attr[2], # DimensionName1
resource["CacheClusterId"], # DimensionValue1
metric_attr[4], # DimensionName2
resource["CacheNodeId"][0], # DimensionValue2
{"region": region},
]
def _get_s3_metric(self, metric_attr: list, resource: dict, region: str) -> list:
return [
metric_attr[0], # Namespace
metric_attr[1], # MetricName
metric_attr[2], # DimensionName
resource["BucketName"], # DimensionValue
metric_attr[4], # DimensionName "FilterID"
resource["BucketName"], # DimensionValue, same as bucket name
{"region": region},
]