def delete_vpc(context, vpc_id): vpc = ec2utils.get_db_item(context, vpc_id) subnets = subnet_api.describe_subnets(context, filter=[{ 'name': 'vpc-id', 'value': [vpc_id] }])['subnetSet'] internet_gateways = internet_gateway_api.describe_internet_gateways( context, filter=[{ 'name': 'attachment.vpc-id', 'value': [vpc['id']] }])['internetGatewaySet'] route_tables = route_table_api.describe_route_tables(context, filter=[{ 'name': 'vpc-id', 'value': [vpc['id']] }])['routeTableSet'] security_groups = security_group_api.describe_security_groups( context, filter=[{ 'name': 'vpc-id', 'value': [vpc['id']] }])['securityGroupInfo'] if (subnets or internet_gateways or len(route_tables) > 1 or len(security_groups) > 1): msg = _("The vpc '%(vpc_id)s' has dependencies and " "cannot be deleted.") msg = msg % {'vpc_id': vpc['id']} raise exception.DependencyViolation(msg) neutron = clients.neutron(context) with common.OnCrashCleaner() as cleaner: db_api.delete_item(context, vpc['id']) cleaner.addCleanup(db_api.restore_item, context, 'vpc', vpc) route_table_api._delete_route_table(context, vpc['route_table_id'], cleaner=cleaner) if len(security_groups) > 0: security_group_api.delete_security_group( context, group_id=security_groups[0]['groupId'], delete_default=True) try: neutron.delete_router(vpc['os_id']) except neutron_exception.Conflict as ex: LOG.warning( _('Failed to delete router %(os_id)s during deleting ' 'VPC %(id)s. Reason: %(reason)s'), { 'id': vpc['id'], 'os_id': vpc['os_id'], 'reason': ex.message }) except neutron_exception.NotFound: pass return True
def delete_vpc(context, vpc_id): vpc = ec2utils.get_db_item(context, vpc_id) subnets = subnet_api.describe_subnets( context, filter=[{'name': 'vpc-id', 'value': [vpc_id]}])['subnetSet'] internet_gateways = internet_gateway_api.describe_internet_gateways( context, filter=[{'name': 'attachment.vpc-id', 'value': [vpc['id']]}])['internetGatewaySet'] route_tables = route_table_api.describe_route_tables( context, filter=[{'name': 'vpc-id', 'value': [vpc['id']]}])['routeTableSet'] security_groups = security_group_api.describe_security_groups( context, filter=[{'name': 'vpc-id', 'value': [vpc['id']]}])['securityGroupInfo'] vpn_gateways = vpn_gateway_api.describe_vpn_gateways( context, filter=[{'name': 'attachment.vpc-id', 'value': [vpc['id']]}])['vpnGatewaySet'] if (subnets or internet_gateways or len(route_tables) > 1 or len(security_groups) > 1 or vpn_gateways): msg = _("The vpc '%(vpc_id)s' has dependencies and " "cannot be deleted.") msg = msg % {'vpc_id': vpc['id']} raise exception.DependencyViolation(msg) neutron = clients.neutron(context) with common.OnCrashCleaner() as cleaner: db_api.delete_item(context, vpc['id']) cleaner.addCleanup(db_api.restore_item, context, 'vpc', vpc) route_table_api._delete_route_table(context, vpc['route_table_id'], cleaner=cleaner) if len(security_groups) > 0: security_group_api.delete_security_group( context, group_id=security_groups[0]['groupId'], delete_default=True) try: neutron.delete_router(vpc['os_id']) except neutron_exception.Conflict as ex: LOG.warning('Failed to delete router %(os_id)s during deleting ' 'VPC %(id)s. Reason: %(reason)s', {'id': vpc['id'], 'os_id': vpc['os_id'], 'reason': ex.message}) except neutron_exception.NotFound: pass return True
def associate_address(self, context, public_ip=None, instance_id=None, allocation_id=None, network_interface_id=None, private_ip_address=None, allow_reassociation=False): instance_network_interfaces = [] if instance_id: # TODO(ft): implement search in DB layer for eni in db_api.get_items(context, 'eni'): if instance_id and eni.get('instance_id') == instance_id: instance_network_interfaces.append(eni) neutron = clients.neutron(context) if public_ip: if instance_network_interfaces: msg = _('You must specify an allocation id when mapping ' 'an address to a VPC instance') raise exception.InvalidParameterCombination(msg) # TODO(ft): implement search in DB layer address = next((addr for addr in db_api.get_items(context, 'eipalloc') if addr['public_ip'] == public_ip), None) if address and _is_address_valid(context, neutron, address): msg = _("The address '%(public_ip)s' does not belong to you.") raise exception.AuthFailure(msg % {'public_ip': public_ip}) # NOTE(ft): in fact only the first two parameters are used to # associate an address in EC2 Classic mode. Other parameters are # sent to validate their emptiness in one place return AddressEngineNova().associate_address( context, public_ip=public_ip, instance_id=instance_id, allocation_id=allocation_id, network_interface_id=network_interface_id, private_ip_address=private_ip_address, allow_reassociation=allow_reassociation) if instance_id: if not instance_network_interfaces: # NOTE(ft): check the instance exists ec2utils.get_db_item(context, instance_id) msg = _('You must specify an IP address when mapping ' 'to a non-VPC instance') raise exception.InvalidParameterCombination(msg) if len(instance_network_interfaces) > 1: raise exception.InvalidInstanceId(instance_id=instance_id) network_interface = instance_network_interfaces[0] else: network_interface = ec2utils.get_db_item(context, network_interface_id) if not private_ip_address: private_ip_address = network_interface['private_ip_address'] address = ec2utils.get_db_item(context, allocation_id) if not _is_address_valid(context, neutron, address): raise exception.InvalidAllocationIDNotFound(id=allocation_id) if address.get('network_interface_id') == network_interface['id']: # NOTE(ft): idempotent call pass elif address.get('network_interface_id') and not allow_reassociation: msg = _('resource %(eipalloc_id)s is already associated with ' 'associate-id %(eipassoc_id)s') msg = msg % { 'eipalloc_id': allocation_id, 'eipassoc_id': ec2utils.change_ec2_id_kind(address['id'], 'eipassoc') } raise exception.ResourceAlreadyAssociated(msg) else: internet_gateways = ( internet_gateway_api.describe_internet_gateways( context, filter=[{ 'name': 'attachment.vpc-id', 'value': [network_interface['vpc_id']] }])['internetGatewaySet']) if len(internet_gateways) == 0: msg = _('Network %(vpc_id)s is not attached to any internet ' 'gateway') % { 'vpc_id': network_interface['vpc_id'] } raise exception.GatewayNotAttached(msg) with common.OnCrashCleaner() as cleaner: _associate_address_item(context, address, network_interface['id'], private_ip_address) cleaner.addCleanup(_disassociate_address_item, context, address) os_floating_ip = { 'port_id': network_interface['os_id'], 'fixed_ip_address': private_ip_address } neutron.update_floatingip(address['os_id'], {'floatingip': os_floating_ip}) # TODO(ft): generate unique association id for each act of association return ec2utils.change_ec2_id_kind(address['id'], 'eipassoc')
def associate_address(self, context, public_ip=None, instance_id=None, allocation_id=None, network_interface_id=None, private_ip_address=None, allow_reassociation=False): instance_network_interfaces = [] if instance_id: # TODO(ft): implement search in DB layer for eni in db_api.get_items(context, 'eni'): if eni.get('instance_id') == instance_id: instance_network_interfaces.append(eni) neutron = clients.neutron(context) if public_ip: # TODO(ft): implement search in DB layer address = next((addr for addr in db_api.get_items(context, 'eipalloc') if addr['public_ip'] == public_ip), None) if not CONF.disable_ec2_classic: if instance_network_interfaces: msg = _('You must specify an allocation id when mapping ' 'an address to a VPC instance') raise exception.InvalidParameterCombination(msg) if address and _is_address_valid(context, neutron, address): msg = _( "The address '%(public_ip)s' does not belong to you.") raise exception.AuthFailure(msg % {'public_ip': public_ip}) os_instance_id = ec2utils.get_db_item(context, instance_id)['os_id'] # NOTE(ft): check the public IP exists to raise AWS exception # otherwise self.get_os_floating_ip_by_public_ip(context, public_ip) nova = clients.nova(context) nova.servers.add_floating_ip(os_instance_id, public_ip) return None if not address: msg = _("The address '%(public_ip)s' does not belong to you.") raise exception.AuthFailure(msg % {'public_ip': public_ip}) allocation_id = address['id'] if instance_id: if not instance_network_interfaces: # NOTE(ft): check the instance exists ec2utils.get_db_item(context, instance_id) msg = _('You must specify an IP address when mapping ' 'to a non-VPC instance') raise exception.InvalidParameterCombination(msg) if len(instance_network_interfaces) > 1: raise exception.InvalidInstanceId(instance_id=instance_id) network_interface = instance_network_interfaces[0] else: network_interface = ec2utils.get_db_item(context, network_interface_id) if not private_ip_address: private_ip_address = network_interface['private_ip_address'] address = ec2utils.get_db_item(context, allocation_id) if not _is_address_valid(context, neutron, address): raise exception.InvalidAllocationIDNotFound( id=allocation_id) if address.get('network_interface_id') == network_interface['id']: # NOTE(ft): idempotent call pass elif address.get('network_interface_id') and not allow_reassociation: msg = _('resource %(eipalloc_id)s is already associated with ' 'associate-id %(eipassoc_id)s') msg = msg % {'eipalloc_id': allocation_id, 'eipassoc_id': ec2utils.change_ec2_id_kind( address['id'], 'eipassoc')} raise exception.ResourceAlreadyAssociated(msg) else: internet_gateways = ( internet_gateway_api.describe_internet_gateways( context, filter=[{'name': 'attachment.vpc-id', 'value': [network_interface['vpc_id']]}]) ['internetGatewaySet']) if len(internet_gateways) == 0: msg = _('Network %(vpc_id)s is not attached to any internet ' 'gateway') % {'vpc_id': network_interface['vpc_id']} raise exception.GatewayNotAttached(msg) with common.OnCrashCleaner() as cleaner: _associate_address_item(context, address, network_interface['id'], private_ip_address) cleaner.addCleanup(_disassociate_address_item, context, address) os_floating_ip = {'port_id': network_interface['os_id'], 'fixed_ip_address': private_ip_address} neutron.update_floatingip(address['os_id'], {'floatingip': os_floating_ip}) # TODO(ft): generate unique association id for each act of association return ec2utils.change_ec2_id_kind(address['id'], 'eipassoc')