예제 #1
0
def region_name(region_id):
    region_names, region_ids = {}, {}
    from botocore import loaders
    for partition_data in loaders.create_loader().load_data("endpoints")["partitions"]:
        region_names.update({k: v["description"] for k, v in partition_data["regions"].items()})
        region_ids.update({v: k for k, v in region_names.items()})
    return region_names[region_id]
예제 #2
0
def create_endpoint_resolver() -> EndpointResolver:
    """
    Creates an instance of the botocore EndpointResolver. Used to inject the instance during application initialization
    to avoid loading endpoint data on a per-request basis.
    :return: the EndpointResolver instance
    """
    return EndpointResolver(create_loader().load_data("endpoints"))
예제 #3
0
 def _get_endpoint_url(service, region):
     data = boto_loader.create_loader().load_data("endpoints")
     endpoint_data = boto_regions.EndpointResolver(data).construct_endpoint(
         service, region)
     if not endpoint_data:
         raise TaskCatException(
             f"unable to resolve endpoint for {service} in {region}")
     return f"https://{service}.{region}.{endpoint_data['dnsSuffix']}"
예제 #4
0
 def __init__(self, session: boto.Session, partition: str):
     self._boto = session
     self._cache: Dict[str, bool] = {}
     self.partition = partition
     data_dir = os.path.join(os.path.dirname(boto.__file__), 'data')
     self._loader = create_loader(data_dir)
     endpoint_data = self._loader.load_data('endpoints')
     self._endpoints = EndpointResolver(endpoint_data)
예제 #5
0
    def test_can_override_session(self):
        with temporary_file('w') as f:
            # We're going to override _retry.json in 
            # botocore/data by setting our own data directory.
            override_name = self.create_file(
                f, contents='{"foo": "bar"}', name='_retry.json')
            new_data_path = os.path.dirname(override_name)
            loader = loaders.create_loader(search_path_string=new_data_path)

            new_content = loader.load_data('_retry')
            # This should contain the content we just created.
            self.assertEqual(new_content, {"foo": "bar"})
예제 #6
0
    def test_can_override_session(self):
        with temporary_file('w') as f:
            # We're going to override _retry.json in
            # botocore/data by setting our own data directory.
            override_name = self.create_file(f,
                                             contents='{"foo": "bar"}',
                                             name='_retry.json')
            new_data_path = os.path.dirname(override_name)
            loader = loaders.create_loader(search_path_string=new_data_path)

            new_content = loader.load_data('_retry')
            # This should contain the content we just created.
            self.assertEqual(new_content, {"foo": "bar"})
예제 #7
0
def get_service_info(endpoint_resolver: EndpointResolver, service_name: str,
                     region: str) -> ServiceInfo:
    service_model_json = create_loader().load_service_model(
        service_name, "service-2")

    service_data = ClientEndpointBridge(endpoint_resolver).resolve(
        service_name=ServiceModel(service_model_json,
                                  service_name=service_name).endpoint_prefix,
        region_name=region,
    )

    return ServiceInfo(
        service_name,
        service_data["metadata"]["hostname"],
        service_data["endpoint_url"],
        service_data["metadata"].get("credentialScope"),
    )
예제 #8
0
 def _register_data_loader(self):
     self._components.lazy_register_component(
         'data_loader',
         lambda: create_loader(self.get_config_variable('data_path')))
예제 #9
0
 def _register_data_loader(self):
     self._components.lazy_register_component(
         "data_loader", lambda: create_loader(self.get_config_variable("data_path"))
     )
예제 #10
0
 def get_region_names(**kwargs):
     from botocore.loaders import create_loader
     for partition_data in create_loader().load_data("endpoints")["partitions"]:
         if partition_data["partition"] == config.partition:
             return partition_data["regions"].keys()
예제 #11
0
 def test_create_loader_parses_data_path(self):
     search_path = os.pathsep.join(['foo', 'bar', 'baz'])
     loader = create_loader(search_path)
     self.assertIn('foo', loader.search_paths)
     self.assertIn('bar', loader.search_paths)
     self.assertIn('baz', loader.search_paths)
예제 #12
0
 def test_create_loader_parses_data_path(self):
     search_path = os.pathsep.join(['foo', 'bar', 'baz'])
     loader = create_loader(search_path)
     self.assertIn('foo', loader.search_paths)
     self.assertIn('bar', loader.search_paths)
     self.assertIn('baz', loader.search_paths)
예제 #13
0
from typing import List

from botocore.loaders import create_loader
from botocore.model import ServiceModel

loader = create_loader()


def list_services(model_type="service-2") -> List[ServiceModel]:
    return [
        load_service(service)
        for service in loader.list_available_services(model_type)
    ]


def load_service(service: str,
                 version: str = None,
                 model_type="service-2") -> ServiceModel:
    """
    For example: load_service("sqs", "2012-11-05")
    """
    service_description = loader.load_service_model(service, model_type,
                                                    version)
    return ServiceModel(service_description, service)
예제 #14
0
def main():
    def create():
        # Wait for VPC Endpoint Service to be available
        while True:
            service = agwe_client.describe_vpc_endpoint_service_configurations(
                ServiceIds=[agwe_service_id])
            if service['ServiceConfigurations'][0]['ServiceState'].lower(
            ) == 'available':
                pprint('VPC Endpoint Service is now in Available State.')
                break
            elif service['ServiceConfigurations'][0]['ServiceState'].lower(
            ) == 'pending':
                pprint('VPC Endpoint Service is in pending state...')
                time.sleep(30)
                continue
            else:
                pprint('VPC Endpoint Service deployment failed.')
                return 1, {}

        # Create GWLB Endpoint
        try:
            agwe = agwe_client.create_vpc_endpoint(
                VpcEndpointType='GatewayLoadBalancer',
                VpcId=app_vpc,
                SubnetIds=[app_agwe_subnet],
                ServiceName=agwe_service_name)
            pprint('Gateway Load Balancer Endpoint:')
            pprint(agwe)
        except Exception as e:
            pprint(
                f'Failed to Deploy VPC Endpoint(Gateway Load Balancer Endpoint): {str(e)}'
            )
            return 1, {}

        # Wait for VPC Endpoint to be Available
        while True:
            time.sleep(30)
            agwe_state = agwe_client.describe_vpc_endpoints(
                VpcEndpointIds=[agwe['VpcEndpoint']['VpcEndpointId']])
            pprint(agwe_state['VpcEndpoints'][0]['State'])
            if agwe_state['VpcEndpoints'][0]['State'].lower() == 'available':
                pprint('VPC Endpoint is now in Available State.')
                break
            elif agwe_state['VpcEndpoints'][0]['State'].lower() == 'pending':
                pprint('VPC Endpoint is in pending state...')
                continue
            else:
                pprint('VPC Endpoint deployment failed.')
                return 1, {'agwe_id': agwe['VpcEndpoint']['VpcEndpointId']}

        # Create Route on IGW Route Table(APP_LB->GWLBE)
        route1 = []
        for alb_cidr in app_data_subnet_cidr:
            route1.append(
                agwe_client.create_route(
                    RouteTableId=igw_route_table_id,
                    DestinationCidrBlock=alb_cidr,
                    VpcEndpointId=agwe['VpcEndpoint']['VpcEndpointId']))
        pprint('Route from IGW to GWLBE:')
        pprint(route1)

        # Create Route on ALB Route Table(0.0.0.0/0->GWLBE)
        route2 = agwe_client.create_route(
            RouteTableId=alb_route_table_id,
            DestinationCidrBlock='0.0.0.0/0',
            VpcEndpointId=agwe['VpcEndpoint']['VpcEndpointId'])
        pprint('Route from ALB to GWLBE:')
        pprint(route2)

        # Create Route on SEC-NATGW Route Table(APP->SEC-GWLBE-OB)
        for idx, rt_id in enumerate(sec_natgw_route_table_id):
            route3 = agwe_client.create_route(
                RouteTableId=rt_id,
                DestinationCidrBlock=app_vpc_cidr,
                VpcEndpointId=sec_agwe_ob_id[idx])
            pprint(f'Route from SEC-NATGW {idx} to SEC-GWLBE-OB {idx}:')
            pprint(route3)

        # Create Route on SEC-TGWA Route Table(SEC-TGWA->SEC-GWLBE-EW)
        for idx, rt_id in enumerate(sec_tgwa_route_table_id):
            route4 = agwe_client.create_route(
                RouteTableId=rt_id,
                DestinationCidrBlock=app_vpc_cidr,
                VpcEndpointId=sec_agwe_ew_id[idx])
            pprint(f'Route from SEC-TGWA {idx} to SEC-GWLBE-EW {idx}:')
            pprint(route4)

        return 0, {
            'agwe': agwe,
            'route_igw_agwe': {
                'rt_id': igw_route_table_id,
                'dst_cidr': app_data_subnet_cidr
            },
            'route_alb_agwe': {
                'rt_id': alb_route_table_id,
                'dst_cidr': '0.0.0.0/0'
            },
            'route_sec_natgw_sec_agwe': {
                'rt_id': sec_natgw_route_table_id,
                'dst_cidr': app_vpc_cidr
            },
            'route_sec_tgwa_sec_agwe_ew': {
                'rt_id': sec_tgwa_route_table_id,
                'dst_cidr': app_vpc_cidr
            },
            'State': 'Create Complete'
        }

    def destroy(**kwargs):
        agwe_id = kwargs.get('agwe_id', None)
        route_igw_agwe = kwargs.get('route_igw_agwe', None)
        route_alb_agwe = kwargs.get('route_alb_agwe', None)
        route_sec_natgw_sec_agwe = kwargs.get('route_sec_natgw_sec_agwe', None)
        route_sec_tgwa_sec_agwe_ew = kwargs.get('route_sec_tgwa_sec_agwe_ew',
                                                None)

        # Delete Route from IGW to GWLBE
        if route_igw_agwe:
            for alb_cidr in route_igw_agwe['dst_cidr']:
                route = agwe_client.delete_route(
                    RouteTableId=route_igw_agwe['rt_id'],
                    DestinationCidrBlock=alb_cidr,
                )
                pprint('Route from IGW to GWLBE Destroy:')
                pprint(route)
                time.sleep(10)

        # Delete Route from APP to GWLBE
        if route_alb_agwe:
            route = agwe_client.delete_route(
                RouteTableId=route_alb_agwe['rt_id'],
                DestinationCidrBlock=route_alb_agwe['dst_cidr'],
            )
            pprint('Route from APP to GWLBE Destroy:')
            pprint(route)
            time.sleep(10)

        # Delete Route from SEC-NATGW to SEC-GWLBE
        if route_sec_natgw_sec_agwe:
            for idx, rt_id in enumerate(route_sec_natgw_sec_agwe['rt_id']):
                route = agwe_client.delete_route(
                    RouteTableId=rt_id,
                    DestinationCidrBlock=route_sec_natgw_sec_agwe['dst_cidr'],
                )
                pprint(
                    f'Route from SEC-NATGW {idx} to SEC-GWLBE-OB {idx} Destroy:'
                )
                pprint(route)
                time.sleep(10)

        # Delete Route from SEC-TGWA to SEC-GWLBE-EW
        if route_sec_tgwa_sec_agwe_ew:
            for idx, rt_id in enumerate(route_sec_tgwa_sec_agwe_ew['rt_id']):
                route = agwe_client.delete_route(
                    RouteTableId=rt_id,
                    DestinationCidrBlock=route_sec_tgwa_sec_agwe_ew[
                        'dst_cidr'],
                )
                pprint('Route from SEC-TGWA to SEC-GWLBE-EW Destroy:')
                pprint(route)
                time.sleep(10)

        # Delete AGW Endpoint
        if agwe_id:
            agwe = agwe_client.delete_vpc_endpoints(VpcEndpointIds=[agwe_id])
            pprint('Gateway Load Balancer Endpoint Destroy:')
            pprint(agwe)
            time.sleep(60)

        return 0, {'State': 'Destroy Complete'}

    # Fetch state info
    state_file = 'handoff_state_app2.json'
    with open(state_file, 'r') as inputfile:
        state_info = json.load(inputfile)

    pprint('State File:')
    pprint(state_info)

    # Get Credentials
    secret_key_id = state_info['access_key']
    secret_access_key = state_info['secret_key']
    region = state_info['region']
    deployment_id = state_info['deployment_id']
    app_vpc = state_info['app_vpc']
    app_agwe_subnet = state_info['app_agwe_subnet']
    agwe_service_id = state_info['agwe_service_id']
    agwe_service_name = state_info['agwe_service_name']
    app_vpc_cidr = state_info['app_vpc_cidr']
    igw_route_table_id = state_info['igw_route_table_id']
    app_data_subnet_cidr = state_info['app_data_subnet_cidr']
    alb_route_table_id = state_info['alb_route_table_id']

    sec_natgw_route_table_id = state_info['sec_natgw_route_table_id']
    sec_agwe_ob_id = state_info['sec_agwe_ob_id']
    sec_agwe_ew_id = state_info['sec_agwe_ew_id']
    sec_tgwa_route_table_id = state_info['sec_tgwa_route_table_id']

    try:
        # Create Gateway Load Balancer Resources for Boto3
        loader_client = loaders.create_loader()
        loader_client.load_service_model('ec2-gwlbe', 'service-2')

        # Create Boto3 resources
        agwe_client = boto3.client('ec2-gwlbe',
                                   aws_access_key_id=secret_key_id,
                                   aws_secret_access_key=secret_access_key,
                                   region_name=region)
    except:
        agwe_client = boto3.client('ec2',
                                   aws_access_key_id=secret_key_id,
                                   aws_secret_access_key=secret_access_key,
                                   region_name=region)

    if sys.argv[1] == 'create':
        create_status, create_output = create()
        if create_status != 0:
            pprint('Destroying to maintain state...')
            destroy_status, destroy_output = destroy(**create_output)
            pprint('Destroy Output')
            pprint(destroy_output)
        else:
            pprint('Create Complete.')
            with open(state_file, 'w') as outputfile:
                state_info['agwe_id'] = create_output['agwe']['VpcEndpoint'][
                    'VpcEndpointId']
                state_info['route_igw_agwe'] = create_output["route_igw_agwe"]
                state_info['route_alb_agwe'] = create_output["route_alb_agwe"]
                state_info['route_sec_natgw_sec_agwe'] = create_output[
                    "route_sec_natgw_sec_agwe"]
                state_info['route_sec_tgwa_sec_agwe_ew'] = create_output[
                    "route_sec_tgwa_sec_agwe_ew"]
                json.dump(state_info, outputfile)
        exit(create_status)
    elif sys.argv[1] == 'destroy':
        destroy_status, destroy_output = destroy(**state_info)
        pprint('Destroy Output')
        pprint(destroy_output)
        exit(destroy_status)
예제 #15
0
def main():
    def create():

        # Modify Security VPC TGW Attachment to enable appliance mode
        try:
            ec2_client.modify_transit_gateway_vpc_attachment(
                TransitGatewayAttachmentId=tgw_sec_attach_id,
                Options={'ApplianceModeSupport': 'enable'})
            pprint(
                f'Modified Security VPC TGW Attachment to enable appliance mode.'
            )
        except Exception as e:
            pprint(
                f'Failed to Modify Security VPC TGW Attachment to enable appliance mode: {str(e)}'
            )

        # Create Gateway Load Balancer
        try:
            agw = agw_client.create_load_balancer(
                Name=f'sec-gwlb-{deployment_id}',
                Subnets=sec_data_subnet,
                Type='gateway')
            pprint('Gateway Load Balancer:')
            pprint(agw)
        except Exception as e:
            pprint(f'Failed to Deploy Gateway Load Balancer: {str(e)}')
            return 1, {}

        # Create Target Group
        try:
            agw_tg = agw_client.create_target_group(
                Name=f'sec-gwlb-tg-{deployment_id}',
                Protocol='GENEVE',
                Port=6081,
                VpcId=sec_vpc,
                TargetType='instance',
                HealthCheckEnabled=True,
                HealthCheckPort='80',
                HealthCheckProtocol='TCP')
            pprint('Taget Group:')
            pprint(agw_tg)
        except Exception as e:
            pprint(f'Failed to Deploy Target Group: {str(e)}')
            return 1, {'agw_arn': agw['LoadBalancers'][0]['LoadBalancerArn']}

        # Wait for GWLB to be available
        while True:
            time.sleep(30)
            lb = agw_client.describe_load_balancers(
                LoadBalancerArns=[agw['LoadBalancers'][0]['LoadBalancerArn']])
            if lb['LoadBalancers'][0]['State']['Code'] == 'active':
                pprint('Gateway Load Balancer is now in Active State.')
                break
            elif lb['LoadBalancers'][0]['State']['Code'] == 'provisioning':
                pprint('Gateway Load Balancer is provisioning...')
                continue
            else:
                pprint('Gateway Load Balancer deployment failed.')
                return 1, {
                    'agw_arn': agw['LoadBalancers'][0]['LoadBalancerArn'],
                    'agw_tg_arn': agw_tg['TargetGroups'][0]['TargetGroupArn']
                }

        # Create Listener
        try:
            agw_listener = agw_client.create_listener(
                LoadBalancerArn=agw['LoadBalancers'][0]['LoadBalancerArn'],
                DefaultActions=[
                    {
                        'Type':
                        'forward',
                        'TargetGroupArn':
                        agw_tg['TargetGroups'][0]['TargetGroupArn']
                    },
                ],
            )
            pprint('Gateway Load Balancer Listener:')
            pprint(agw_listener)
        except Exception as e:
            pprint(f'Failed to Deploy Listener: {str(e)}')
            return 1, {
                'agw_arn': agw['LoadBalancers'][0]['LoadBalancerArn'],
                'agw_tg_arn': agw_tg['TargetGroups'][0]['TargetGroupArn']
            }

        # Register instance as a target
        try:
            for iid in instance_id:
                register = agw_client.register_targets(
                    TargetGroupArn=agw_tg['TargetGroups'][0]['TargetGroupArn'],
                    Targets=[{
                        'Id': iid
                    }])
                pprint(f'Instance {iid} Registration:')
                pprint(register)
        except Exception as e:
            pprint(f'Failed to Register Instance as target: {str(e)}')
            return 1, {
                'agw_arn': agw['LoadBalancers'][0]['LoadBalancerArn'],
                'agw_tg_arn': agw_tg['TargetGroups'][0]['TargetGroupArn'],
                'agw_listener_arn': agw_listener['Listeners'][0]['ListenerArn']
            }

        # Create VPC Endpoint Service
        try:
            agwe_service = agwe_client.create_vpc_endpoint_service_configuration(
                GatewayLoadBalancerArns=[
                    agw['LoadBalancers'][0]['LoadBalancerArn']
                ],
                AcceptanceRequired=False)
            pprint('VPC Endpoint Service:')
            pprint(agwe_service)
        except Exception as e:
            pprint(f'Failed to Deploy VPC Endpoint Service: {str(e)}')
            return 1, {
                'agw_arn': agw['LoadBalancers'][0]['LoadBalancerArn'],
                'agw_tg_arn': agw_tg['TargetGroups'][0]['TargetGroupArn'],
                'agw_listener_arn': agw_listener['Listeners'][0]['ListenerArn']
            }

        # Wait for VPC Endpoint Service to be available
        while True:
            time.sleep(30)
            service = agwe_client.describe_vpc_endpoint_service_configurations(
                ServiceIds=[agwe_service['ServiceConfiguration']['ServiceId']])
            if service['ServiceConfigurations'][0]['ServiceState'].lower(
            ) == 'available':
                pprint('VPC Endpoint Service is now in Available State.')
                break
            elif service['ServiceConfigurations'][0]['ServiceState'].lower(
            ) == 'pending':
                pprint('VPC Endpoint Service is in pending state...')
                continue
            else:
                pprint('VPC Endpoint Service deployment failed.')
                return 1, {
                    'agw_arn':
                    agw['LoadBalancers'][0]['LoadBalancerArn'],
                    'agw_tg_arn':
                    agw_tg['TargetGroups'][0]['TargetGroupArn'],
                    'agw_listener_arn':
                    agw_listener['Listeners'][0]['ListenerArn'],
                    'agwe_service_name':
                    agwe_service['ServiceConfiguration']['ServiceName'],
                    'agwe_service_id':
                    agwe_service['ServiceConfiguration']['ServiceId']
                }

        # Modify VPC Endpoint Service Permissions
        agwe_service_permissions = agwe_client.modify_vpc_endpoint_service_permissions(
            ServiceId=agwe_service['ServiceConfiguration']['ServiceId'],
            AddAllowedPrincipals=[
                f'arn:aws:iam::{account_id}:root',
            ])
        pprint('VPC Endpoint Service Permission:')
        pprint(agwe_service_permissions)

        # Wait for VPC Endpoint Service to be available
        while True:
            time.sleep(30)
            service = agwe_client.describe_vpc_endpoint_service_configurations(
                ServiceIds=[agwe_service['ServiceConfiguration']['ServiceId']])
            if service['ServiceConfigurations'][0]['ServiceState'].lower(
            ) == 'available':
                pprint('VPC Endpoint Service is now in Available State.')
                break
            elif service['ServiceConfigurations'][0]['ServiceState'].lower(
            ) == 'pending':
                pprint('VPC Endpoint Service is in pending state...')
                continue
            else:
                pprint('VPC Endpoint Service deployment failed.')
                return 1, {
                    'agw_arn':
                    agw['LoadBalancers'][0]['LoadBalancerArn'],
                    'agw_tg_arn':
                    agw_tg['TargetGroups'][0]['TargetGroupArn'],
                    'agw_listener_arn':
                    agw_listener['Listeners'][0]['ListenerArn'],
                    'agwe_service_name':
                    agwe_service['ServiceConfiguration']['ServiceName'],
                    'agwe_service_id':
                    agwe_service['ServiceConfiguration']['ServiceId']
                }

        # Create GWLB Endpoint (OB traffic)
        agwe = []

        for idx, subnet in enumerate(sec_agwe_subnet):
            try:
                agwe.append(
                    agwe_client.create_vpc_endpoint(
                        VpcEndpointType='GatewayLoadBalancer',
                        VpcId=sec_vpc,
                        SubnetIds=[subnet],
                        ServiceName=agwe_service['ServiceConfiguration']
                        ['ServiceName']))
                pprint(f'Gateway Load Balancer Outbound Endpoint {idx}:')
                pprint(agwe[idx])
            except Exception as e:
                pprint(
                    f'Failed to Deploy VPC Endpoint {idx}(Gateway Load Balancer Endpoint): {str(e)}'
                )
                return 1, {
                    'agw_arn':
                    agw['LoadBalancers'][0]['LoadBalancerArn'],
                    'agw_tg_arn':
                    agw_tg['TargetGroups'][0]['TargetGroupArn'],
                    'agw_listener_arn':
                    agw_listener['Listeners'][0]['ListenerArn'],
                    'agwe_service_name':
                    agwe_service['ServiceConfiguration']['ServiceName'],
                    'agwe_service_id':
                    agwe_service['ServiceConfiguration']['ServiceId']
                }

        # Get all AGWE IDs
        agwe_ids = []
        for endpoint in agwe:
            agwe_ids.append(endpoint['VpcEndpoint']['VpcEndpointId'])

        # Wait for VPC Endpoints to be Available
        time.sleep(30)
        for idx, endpoint in enumerate(agwe):
            while True:
                agwe_state = agwe_client.describe_vpc_endpoints(
                    VpcEndpointIds=[endpoint['VpcEndpoint']['VpcEndpointId']])
                pprint(agwe_state['VpcEndpoints'][0]['State'])
                if agwe_state['VpcEndpoints'][0]['State'].lower(
                ) == 'available':
                    pprint(f'VPC Endpoint {idx} is now in Available State.')
                    break
                elif agwe_state['VpcEndpoints'][0]['State'].lower(
                ) == 'pending':
                    pprint(f'VPC Endpoint {idx} is in pending state...')
                    time.sleep(30)
                    continue
                else:
                    pprint(f'VPC Endpoint {idx} deployment failed.')
                    return 1, {
                        'agw_arn':
                        agw['LoadBalancers'][0]['LoadBalancerArn'],
                        'agw_tg_arn':
                        agw_tg['TargetGroups'][0]['TargetGroupArn'],
                        'agw_listener_arn':
                        agw_listener['Listeners'][0]['ListenerArn'],
                        'agwe_service_name':
                        agwe_service['ServiceConfiguration']['ServiceName'],
                        'agwe_service_id':
                        agwe_service['ServiceConfiguration']['ServiceId'],
                        'agwe_id':
                        agwe_ids
                    }

        # Create AGW Endpoint (EW traffic)
        agwe_ew = []
        for idx, subnet in enumerate(sec_agwe_ew_subnet):
            try:
                agwe_ew.append(
                    agwe_client.create_vpc_endpoint(
                        VpcEndpointType='GatewayLoadBalancer',
                        VpcId=sec_vpc,
                        SubnetIds=[subnet],
                        ServiceName=agwe_service['ServiceConfiguration']
                        ['ServiceName']))
                pprint(f'Gateway Load Balancer East-West Endpoint {idx}:')
                pprint(agwe_ew[idx])
            except Exception as e:
                pprint(
                    f'Failed to Deploy VPC Endpoint {idx}(Gateway Load Balancer Endpoint): {str(e)}'
                )
                return 1, {
                    'agw_arn':
                    agw['LoadBalancers'][0]['LoadBalancerArn'],
                    'agw_tg_arn':
                    agw_tg['TargetGroups'][0]['TargetGroupArn'],
                    'agw_listener_arn':
                    agw_listener['Listeners'][0]['ListenerArn'],
                    'agwe_service_name':
                    agwe_service['ServiceConfiguration']['ServiceName'],
                    'agwe_service_id':
                    agwe_service['ServiceConfiguration']['ServiceId'],
                    'agwe_id':
                    agwe_ids
                }

        # Get all AGWE-EW IDs
        agwe_ew_ids = []
        for endpoint in agwe_ew:
            agwe_ew_ids.append(endpoint['VpcEndpoint']['VpcEndpointId'])

        # Wait for VPC Endpoint to be Available
        time.sleep(30)
        for idx, endpoint in enumerate(agwe_ew):
            while True:
                agwe_state_ew = agwe_client.describe_vpc_endpoints(
                    VpcEndpointIds=[endpoint['VpcEndpoint']['VpcEndpointId']])
                pprint(agwe_state_ew['VpcEndpoints'][0]['State'])
                if agwe_state_ew['VpcEndpoints'][0]['State'].lower(
                ) == 'available':
                    pprint(f'VPC Endpoint {idx} is now in Available State.')
                    break
                elif agwe_state_ew['VpcEndpoints'][0]['State'].lower(
                ) == 'pending':
                    pprint(f'VPC Endpoint {idx} is in pending state...')
                    time.sleep(30)
                    continue
                else:
                    pprint(f'VPC Endpoint {idx} deployment failed.')
                    return 1, {
                        'agw_arn':
                        agw['LoadBalancers'][0]['LoadBalancerArn'],
                        'agw_tg_arn':
                        agw_tg['TargetGroups'][0]['TargetGroupArn'],
                        'agw_listener_arn':
                        agw_listener['Listeners'][0]['ListenerArn'],
                        'agwe_service_name':
                        agwe_service['ServiceConfiguration']['ServiceName'],
                        'agwe_service_id':
                        agwe_service['ServiceConfiguration']['ServiceId'],
                        'agwe_id':
                        agwe_ids,
                        'agwe_ew_id':
                        agwe_ew_ids
                    }

        # Create Route on TGWA Route Table(0.0.0.0/0->GWLBE_OB)
        for idx, rt_id in enumerate(sec_tgwa_route_table_id):
            try:
                route = agwe_client.create_route(
                    RouteTableId=rt_id,
                    DestinationCidrBlock='0.0.0.0/0',
                    VpcEndpointId=agwe_ids[idx])
                pprint(f'Route from TGWA {idx} to GWLBE_OB {idx}:')
                pprint(route)
            except Exception as e:
                pprint(
                    f'Failed to Deploy Route on TGWA {idx} Route Table {rt_id}: {str(e)}'
                )
                return 1, {
                    'agw_arn':
                    agw['LoadBalancers'][0]['LoadBalancerArn'],
                    'agw_tg_arn':
                    agw_tg['TargetGroups'][0]['TargetGroupArn'],
                    'agw_listener_arn':
                    agw_listener['Listeners'][0]['ListenerArn'],
                    'agwe_service_name':
                    agwe_service['ServiceConfiguration']['ServiceName'],
                    'agwe_service_id':
                    agwe_service['ServiceConfiguration']['ServiceId'],
                    'agwe_id':
                    agwe_ids,
                    'agwe_ew_id':
                    agwe_ew_ids
                }

        return 0, {
            'agw': agw,
            'agw_tg': agw_tg,
            'agw_listener': agw_listener,
            'agwe_service': agwe_service,
            'agwe': agwe,
            'agwe_ew': agwe_ew,
            'agwe_ids': agwe_ids,
            'agwe_ew_ids': agwe_ew_ids,
            'route_tgwa_agwe': {
                'rt_id': sec_tgwa_route_table_id,
                'dst_cidr': '0.0.0.0/0'
            },
            'State': 'Create Complete'
        }

    def destroy(**kwargs):
        agwe_ew_id = kwargs.get('agwe_ew_id', None)
        agwe_id = kwargs.get('agwe_id', None)
        agwe_service_id = kwargs.get('agwe_service_id', None)
        agw_listener_arn = kwargs.get('agw_listener_arn', None)
        agw_tg_arn = kwargs.get('agw_tg_arn', None)
        agw_arn = kwargs.get('agw_arn', None)
        route_tgwa_agwe = kwargs.get('route_tgwa_agwe', None)

        # Delete Route from TGWA to GWLBE
        if route_tgwa_agwe:
            for idx, rt_id in enumerate(route_tgwa_agwe['rt_id']):
                route = agwe_client.delete_route(
                    RouteTableId=rt_id,
                    DestinationCidrBlock=route_tgwa_agwe['dst_cidr'],
                )
                pprint(f'Route {idx} from TGWA to GWLBE Destroy:')
                pprint(route)
                time.sleep(10)

        # Delete GWLB Endpoint(East-West)
        if agwe_ew_id:
            agwe_ew = agwe_client.delete_vpc_endpoints(
                VpcEndpointIds=agwe_ew_id)
            pprint('Gateway Load Balancer East-West Endpoint(s) Destroy:')
            pprint(agwe_ew)
            time.sleep(30)

        # Delete GWLB Endpoint(Outbound)
        if agwe_id:
            agwe = agwe_client.delete_vpc_endpoints(VpcEndpointIds=agwe_id)
            pprint('Gateway Load Balancer Outbound Endpoint(s) Destroy:')
            pprint(agwe)
            time.sleep(30)

        # Delete VPC Endpoint Service
        if agwe_service_id:
            agwe_service = agwe_client.delete_vpc_endpoint_service_configurations(
                ServiceIds=[agwe_service_id])
            pprint('VPC Endpoint Service Destroy:')
            pprint(agwe_service)
            time.sleep(60)

        # Delete Listener
        if agw_listener_arn:
            agw_listener = agw_client.delete_listener(
                ListenerArn=agw_listener_arn)
            pprint('Gateway Load Balancer Listener Destroy:')
            pprint(agw_listener)
            time.sleep(30)

        # Delete Target Group
        if agw_tg_arn:
            agw_tg = agw_client.delete_target_group(TargetGroupArn=agw_tg_arn)
            pprint('Gateway Load Balancer Target group Destroy:')
            pprint(agw_tg)
            time.sleep(30)

        # Delete Gateway Load Balancer
        if agw_arn:
            agw = agw_client.delete_load_balancer(LoadBalancerArn=agw_arn)
            pprint('Gateway Load Balancer Destroy:')
            pprint(agw)
            time.sleep(30)

        return 0, {'State': 'Destroy Complete'}

    # Fetch state info
    state_file = 'handoff_state.json'
    with open(state_file, 'r') as inputfile:
        state_info = json.load(inputfile)

    pprint('State File:')
    pprint(state_info)

    # Get Credentials
    secret_key_id = state_info['access_key']
    secret_access_key = state_info['secret_key']
    region = state_info['region']
    deployment_id = state_info['deployment_id']
    sec_vpc = state_info['sec_vpc']
    sec_data_subnet = state_info['sec_data_subnet']
    sec_agwe_subnet = state_info['sec_agwe_subnet']
    sec_agwe_ew_subnet = state_info['sec_agwe_ew_subnet']
    sec_tgwa_route_table_id = state_info['sec_tgwa_route_table_id']
    instance_id = state_info['instance_id']
    account_id = state_info['account_id']
    tgw_sec_attach_id = state_info['tgw_sec_attach_id']

    # Create Gateway Load Balancer Resources for Boto3
    ec2_client = boto3.client('ec2',
                              aws_access_key_id=secret_key_id,
                              aws_secret_access_key=secret_access_key,
                              region_name=region)
    try:
        loader_client = loaders.create_loader()
        loader_client.load_service_model('elbv2-gwlb', 'service-2')
        loader_client.load_service_model('ec2-gwlbe', 'service-2')

        # Create Boto3 resources
        agw_client = boto3.client('elbv2-gwlb',
                                  aws_access_key_id=secret_key_id,
                                  aws_secret_access_key=secret_access_key,
                                  region_name=region)
        agwe_client = boto3.client('ec2-gwlbe',
                                   aws_access_key_id=secret_key_id,
                                   aws_secret_access_key=secret_access_key,
                                   region_name=region)
    except:
        # Create Boto3 resources
        agw_client = boto3.client('elbv2',
                                  aws_access_key_id=secret_key_id,
                                  aws_secret_access_key=secret_access_key,
                                  region_name=region)
        agwe_client = boto3.client('ec2',
                                   aws_access_key_id=secret_key_id,
                                   aws_secret_access_key=secret_access_key,
                                   region_name=region)

    if sys.argv[1] == 'create':
        create_status, create_output = create()
        if create_status != 0:
            pprint('Destroying to maintain state...')
            destroy_status, destroy_output = destroy(**create_output)
            pprint('Destroy Output')
            pprint(destroy_output)
        else:
            pprint('Create Complete.')
            with open(state_file, 'w') as outputfile:
                state_info['agw_arn'] = create_output['agw']['LoadBalancers'][
                    0]['LoadBalancerArn']
                state_info['agw_tg_arn'] = create_output['agw_tg'][
                    'TargetGroups'][0]['TargetGroupArn']
                state_info['agw_listener_arn'] = create_output['agw_listener'][
                    'Listeners'][0]['ListenerArn']
                state_info['agwe_service_name'] = create_output[
                    'agwe_service']['ServiceConfiguration']['ServiceName']
                state_info['agwe_service_id'] = create_output['agwe_service'][
                    'ServiceConfiguration']['ServiceId']
                state_info['agwe_id'] = create_output['agwe_ids']
                state_info['agwe_ew_id'] = create_output['agwe_ew_ids']
                state_info['route_tgwa_agwe'] = create_output[
                    'route_tgwa_agwe']
                json.dump(state_info, outputfile)
        exit(create_status)
    elif sys.argv[1] == 'destroy':
        destroy_status, destroy_output = destroy(**state_info)
        pprint('Destroy Output')
        pprint(destroy_output)
        exit(destroy_status)