def collect(cls, api_client: client.ApiClient, graph: Graph): for response in cls.list(api_client): kwargs, search_results = default_attributes( response, cls.attr_map, cls.search_map, graph) parent = graph.root namespace = response.metadata.namespace resource = cls(**kwargs) if namespace: ns = graph.search_first_all({ "kind": "kubernetes_namespace", "name": namespace }) if ns: parent = ns log.debug(f"Collected {resource.rtdname} in {parent.rtdname}") graph.add_resource(parent, resource) parent_map = { True: cls.predecessor_names, False: cls.successor_names } for is_parent, sr_names in parent_map.items(): for sr_name in sr_names: if sr_name in search_results: srs = search_results[sr_name] for sr in srs: if is_parent: src = sr dst = resource else: src = resource dst = sr graph.add_edge(src, dst) else: if sr_name in cls.search_map: graph_search = cls.search_map[sr_name] attr = graph_search[0] value_name = graph_search[1] value = get_response_data(response, value_name) if value: if isinstance(value, list): values = value for value in values: resource.add_deferred_connection( {attr: value}, is_parent) elif isinstance(value, str): resource.add_deferred_connection( {attr: value}, is_parent) else: log.error(( "Unable to add deferred connection for" f" value {value} of type {type(value)}" )) else: log.error( f"Key {sr_name} is missing in search_map") post_process = getattr(cls, "post_process", None) if callable(post_process): post_process(resource, graph)
def alarm_cleanup(self, graph: Graph): log.info("AWS Cloudwatch Alarms cleanup called") for node in graph.nodes: if node.protected or not isinstance(node, AWSCloudwatchAlarm): continue cloud = node.cloud(graph) account = node.account(graph) region = node.region(graph) log_prefix = ( f"Found {node.rtdname} in cloud {cloud.name} account {account.dname} " f"region {region.name}.") if len(self.config) > 0: if (cloud.id not in self.config or account.id not in self.config[cloud.id]): log.debug(( f"{log_prefix} Account not found in config - ignoring." )) continue should_clean = False i = None log_msg = log_prefix for dimension in node.dimensions: if dimension.get("Name") == "InstanceId": instance_id = dimension.get("Value") i = graph.search_first_all({ "kind": "aws_ec2_instance", "id": instance_id }) if isinstance( i, AWSEC2Instance) and i.instance_status not in ( "terminated"): should_clean = False break else: should_clean = True log_msg += f" Referenced EC2 instance {instance_id} not found." if not should_clean: continue log.debug(f"{log_msg} - cleaning alarm") node.clean = True