diff --git a/src/spaceone/inventory/connector/aws_elb_connector/connector.py b/src/spaceone/inventory/connector/aws_elb_connector/connector.py index 7f184791..affdf670 100644 --- a/src/spaceone/inventory/connector/aws_elb_connector/connector.py +++ b/src/spaceone/inventory/connector/aws_elb_connector/connector.py @@ -1,4 +1,6 @@ import logging + +from moto.efs.urls import response from spaceone.core.utils import * from spaceone.inventory.connector.aws_elb_connector.schema.data import ( LoadBalancer, @@ -7,6 +9,7 @@ TargetGroupAttributes, Listener, Instance, + ListenerRule, ) from spaceone.inventory.connector.aws_elb_connector.schema.resource import ( LoadBalancerResource, @@ -151,6 +154,7 @@ def request_load_balancer_data(self, region_name): ) match_tags = self.search_tags(all_tags, raw_lb.get("LoadBalancerArn")) raw_listeners = self.request_listeners(raw_lb.get("LoadBalancerArn")) + listener_rules = self.get_listener_rules(raw_listeners) for match_tg in match_target_groups: match_instances.extend(self.match_elb_instance(match_tg, instances)) @@ -167,6 +171,12 @@ def request_load_balancer_data(self, region_name): raw_listeners, ) ), + "listener_rules": list( + map( + lambda _listener_rule: ListenerRule(_listener_rule, strict=False), + listener_rules, + ) + ), "cloudwatch": self.elb_cloudwatch(raw_lb, region_name), "cloudtrail": self.set_cloudtrail( region_name, @@ -247,6 +257,94 @@ def match_elb_instance(self, target_group, instances): return match_instances + def get_listener_rules(self, raw_listeners: list): + for raw_listener in raw_listeners: + raw_listener_rules = self.request_rules_by_listeners(raw_listener) + + rule_infos = [] + for raw_listener_rule in raw_listener_rules: + is_default = raw_listener_rule.get("IsDefault", False) + conditions = self.get_formatted_conditions(raw_listener_rule["Conditions"], is_default) + actions = self.get_formatted_actions(raw_listener_rule["Actions"]) + rule_info = { + "Protocol": raw_listener.get("Protocol"), + "Port": raw_listener.get("Port"), + "RuleArn": raw_listener_rule.get("RuleArn"), + "Priority": raw_listener_rule.get("Priority"), + "Conditions": conditions, + "Actions": actions, + "IsDefault": is_default, + } + + rule_infos.append(rule_info) + + return rule_infos + + @staticmethod + def get_formatted_conditions(raw_conditions: list, is_default: bool) -> list: + str_conditions = [] + + if is_default: + str_conditions.append("If no other rule applies") + return str_conditions + + for condition in raw_conditions: + field = condition.get("Field") + values = ','.join(condition.get("Values")) + + str_conditions.append(f"{field} : {values}") + + return str_conditions + + @staticmethod + def get_formatted_actions(actions: list) -> list: + str_actions = [] + + for action in actions: + action_type = action.get("Type") + + if action_type == "forward": + config = action.get("ForwardConfig") + target_groups = config.get("TargetGroups") + stickiness = "on" if config.get("TargetGroupStickinessConfig", {}).get("Enabled", False) == True else "off" + + str_actions.append("Forward to target group") + + for target_group in target_groups: + target = target_group.get("TargetGroupArn") + weight = target_group.get("Weight") + str_actions.append(f" - {target}: {weight}") + + str_actions.append(f" - Target group stickiness: {stickiness}") + elif action_type == "authenticate-oidc": + pass + elif action_type == "authenticate-cognito": + pass + elif action_type == "redirect": + config = action.get("RedirectConfig") + protocol = config.get("Protocol") + port = config.get("Port") + host = config.get("Host") + path = config.get("Path") + query = config.get("Query") + status_code = config.get("StatusCode") + + str_action = f"Redirect to {protocol}://#{host}:{port}{path}?{query}" + str_actions.append(str_action) + str_actions.append(f" - Status code: {status_code}") + + elif action_type == "fixed-response": + config = action.get("FixedResponseConfig") + response_code = config.get("StatusCode") + content_type = config.get("ContentType") + + str_actions.append("Return fixed response") + str_actions.append(f" - Response code: {response_code}") + str_actions.append(" - Response body") + str_actions.append(f" - Response content type: {content_type}") + + return str_actions + def request_loadbalancer(self, region_name): load_balancers = [] paginator = self.client.get_paginator("describe_load_balancers") @@ -292,6 +390,12 @@ def request_listeners(self, lb_arn): response = self.client.describe_listeners(LoadBalancerArn=lb_arn) return response.get("Listeners", []) + def request_rules_by_listeners(self, listener: dict) -> list: + listener_arn = listener.get("ListenerArn") + response = self.client.describe_rules(ListenerArn=listener_arn) + + return response.get("Rules", []) + def request_tags(self, resource_arns): all_tags = [] diff --git a/src/spaceone/inventory/connector/aws_elb_connector/schema/data.py b/src/spaceone/inventory/connector/aws_elb_connector/schema/data.py index aad8fc31..6f23aba3 100644 --- a/src/spaceone/inventory/connector/aws_elb_connector/schema/data.py +++ b/src/spaceone/inventory/connector/aws_elb_connector/schema/data.py @@ -144,6 +144,28 @@ class Listener(Model): ) +""" +Listener Rule +""" + + +class ListenerRule(Model): + protocol = StringType( + deserialize_from="Protocol", + choices=("HTTP", "HTTPS", "TCP", "TLS", "UDP", "TCP_UDP"), + ) + port = IntType(deserialize_from="Port") + rule_arn = StringType(deserialize_from="RuleArn") + priority = StringType(deserialize_from="Priority") + conditions = ListType( + StringType, deserialize_from="Conditions" + ) + actions = ListType( + StringType, deserialize_from="Actions" + ) + is_default = BooleanType(deserialize_from="IsDefault") + + """ Target Group """ @@ -341,6 +363,7 @@ class LoadBalancer(AWSCloudService): deserialize_from="IpAddressType", choices=("ipv4", "dualstack") ) listeners = ListType(ModelType(Listener)) + listener_rules = ListType(ModelType(ListenerRule)) target_groups = ListType(ModelType(TargetGroup), default=[]) attributes = ModelType(LoadBalancerAttributes) instances = ListType(ModelType(Instance), default=[]) diff --git a/src/spaceone/inventory/connector/aws_elb_connector/schema/resource.py b/src/spaceone/inventory/connector/aws_elb_connector/schema/resource.py index 84b2a063..f79f4e82 100644 --- a/src/spaceone/inventory/connector/aws_elb_connector/schema/resource.py +++ b/src/spaceone/inventory/connector/aws_elb_connector/schema/resource.py @@ -97,6 +97,23 @@ ], ) +lb_listener_rule = TableDynamicLayout.set_fields( + "Listener Rules", + "data.listener_rules", + fields=[ + EnumDyField.data_source( + "Protocol", + "protocol", + default_outline_badge=["HTTP", "HTTPS", "TCP", "TLS", "UDP", "TCP_UDP"], + ), + TextDyField.data_source("Port", "port"), + TextDyField.data_source("Priority", "priority"), + ListDyField.data_source("Conditions", "conditions"), + ListDyField.data_source("Actions", "actions"), + TextDyField.data_source("Role Arn", "role_arn"), + ], +) + lb_tg = TableDynamicLayout.set_fields( "Target Groups", "data.target_groups", @@ -177,7 +194,7 @@ ) lb_metadata = CloudServiceMeta.set_layouts( - layouts=[lb_base, lb_attr, lb_listener, lb_tg, lb_instance] + layouts=[lb_base, lb_attr, lb_listener, lb_listener_rule, lb_tg, lb_instance] ) """