def detach_vpn_gateway(context, vpc_id, vpn_gateway_id): vpn_gateway = ec2utils.get_db_item(context, vpn_gateway_id) if vpn_gateway['vpc_id'] != vpc_id: raise exception.InvalidVpnGatewayAttachmentNotFound( vgw_id=vpn_gateway_id, vpc_id=vpc_id) vpc = db_api.get_item_by_id(context, vpc_id) neutron = clients.neutron(context) remove_os_gateway_router = ( ec2utils.get_attached_gateway(context, vpc_id, 'igw') is None) subnets = [subnet for subnet in db_api.get_items(context, 'subnet') if subnet['vpc_id'] == vpc['id']] with common.OnCrashCleaner() as cleaner: _detach_vpn_gateway_item(context, vpn_gateway) cleaner.addCleanup(_attach_vpn_gateway_item, context, vpn_gateway, vpc_id) vpn_connection_api._stop_gateway_vpn_connections( context, neutron, cleaner, vpn_gateway) for subnet in subnets: _delete_subnet_vpnservice(context, neutron, cleaner, subnet) if remove_os_gateway_router: try: neutron.remove_gateway_router(vpc['os_id']) except neutron_exception.NotFound: pass return True
def disassociate_address(self, context, public_ip=None, association_id=None): 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 address and _is_address_valid(context, neutron, address): msg = _('You must specify an association id when unmapping ' 'an address from a VPC instance') raise exception.InvalidParameterValue(msg) # NOTE(ft): association_id is unused in EC2 Classic mode, but it's # passed there to validate its emptiness in one place return AddressEngineNova().disassociate_address( context, public_ip=public_ip, association_id=association_id) address = db_api.get_item_by_id( context, ec2utils.change_ec2_id_kind(association_id, 'eipalloc')) if address is None or not _is_address_valid(context, neutron, address): raise exception.InvalidAssociationIDNotFound( id=association_id) if 'network_interface_id' in address: with common.OnCrashCleaner() as cleaner: network_interface_id = address['network_interface_id'] private_ip_address = address['private_ip_address'] _disassociate_address_item(context, address) cleaner.addCleanup(_associate_address_item, context, address, network_interface_id, private_ip_address) neutron.update_floatingip(address['os_id'], {'floatingip': {'port_id': None}})
def associate_dhcp_options(context, dhcp_options_id, vpc_id): vpc = ec2utils.get_db_item(context, vpc_id) rollback_dhcp_options_id = vpc.get('dhcp_options_id') if dhcp_options_id == 'default': dhcp_options_id = None dhcp_options = None else: dhcp_options = ec2utils.get_db_item(context, dhcp_options_id) dhcp_options_id = dhcp_options['id'] neutron = clients.neutron(context) os_ports = neutron.list_ports(tenant_id=context.project_id)['ports'] network_interfaces = db_api.get_items(context, 'eni') rollback_dhcp_options_object = ( db_api.get_item_by_id(context, rollback_dhcp_options_id) if dhcp_options_id is not None else None) with common.OnCrashCleaner() as cleaner: _associate_vpc_item(context, vpc, dhcp_options_id) cleaner.addCleanup(_associate_vpc_item, context, vpc, rollback_dhcp_options_id) for network_interface in network_interfaces: os_port = next((p for p in os_ports if p['id'] == network_interface['os_id']), None) if not os_port: continue _add_dhcp_opts_to_port(context, dhcp_options, network_interface, os_port, neutron) cleaner.addCleanup(_add_dhcp_opts_to_port, context, rollback_dhcp_options_object, network_interface, os_port, neutron) return True
def delete_vpn_connection(context, vpn_connection_id): vpn_connection = ec2utils.get_db_item(context, vpn_connection_id) with common.OnCrashCleaner() as cleaner: db_api.delete_item(context, vpn_connection['id']) cleaner.addCleanup(db_api.restore_item, context, 'vpn', vpn_connection) neutron = clients.neutron(context) _stop_vpn_connection(neutron, vpn_connection) try: neutron.delete_ipsecpolicy(vpn_connection['os_ipsecpolicy_id']) except neutron_exception.Conflict as ex: LOG.warning( _('Failed to delete ipsecoplicy %(os_id)s during deleting ' 'VPN connection %(id)s. Reason: %(reason)s'), { 'id': vpn_connection['id'], 'os_id': vpn_connection['os_ipsecpolicy_id'], 'reason': ex.message }) except neutron_exception.NotFound: pass try: neutron.delete_ikepolicy(vpn_connection['os_ikepolicy_id']) except neutron_exception.Conflict as ex: LOG.warning( _('Failed to delete ikepolicy %(os_id)s during deleting ' 'VPN connection %(id)s. Reason: %(reason)s'), { 'id': vpn_connection['id'], 'os_id': vpn_connection['os_ikepolicy_id'], 'reason': ex.message }) except neutron_exception.NotFound: pass return True
def detach_network_interface(context, attachment_id, force=None): network_interface = db_api.get_item_by_id( context, ec2utils.change_ec2_id_kind(attachment_id, 'eni')) if not network_interface or 'instance_id' not in network_interface: raise exception.InvalidAttachmentIDNotFound(id=attachment_id) if network_interface['device_index'] == 0: raise exception.OperationNotPermitted( _('The network interface at device index 0 cannot be detached.')) neutron = clients.neutron(context) os_port = neutron.show_port(network_interface['os_id'])['port'] with common.OnCrashCleaner() as cleaner: instance_id = network_interface['instance_id'] device_index = network_interface['device_index'] attach_time = network_interface['attach_time'] delete_on_termination = network_interface['delete_on_termination'] _detach_network_interface_item(context, network_interface) cleaner.addCleanup(_attach_network_interface_item, context, network_interface, instance_id, device_index, attach_time, delete_on_termination) neutron.update_port(os_port['id'], {'port': { 'device_id': '', 'device_owner': '' }}) return True
def _update_routes_in_associated_subnets(context, cleaner, route_table, default_associations_only=None, update_target=None): if default_associations_only: appropriate_rtb_ids = (None, ) else: vpc = db_api.get_item_by_id(context, route_table['vpc_id']) if vpc['route_table_id'] == route_table['id']: appropriate_rtb_ids = (route_table['id'], None) else: appropriate_rtb_ids = (route_table['id'], ) neutron = clients.neutron(context) subnets = [ subnet for subnet in db_api.get_items(context, 'subnet') if (subnet['vpc_id'] == route_table['vpc_id'] and subnet.get('route_table_id') in appropriate_rtb_ids) ] # NOTE(ft): we need to update host routes for both host and vpn target # because vpn-related routes are present in host routes as well _update_host_routes(context, neutron, cleaner, route_table, subnets) if not update_target or update_target == VPN_TARGET: vpn_connection_api._update_vpn_routes(context, neutron, cleaner, route_table, subnets)
def detach_vpn_gateway(context, vpc_id, vpn_gateway_id): vpn_gateway = ec2utils.get_db_item(context, vpn_gateway_id) if vpn_gateway['vpc_id'] != vpc_id: raise exception.InvalidVpnGatewayAttachmentNotFound( vgw_id=vpn_gateway_id, vpc_id=vpc_id) vpc = db_api.get_item_by_id(context, vpc_id) neutron = clients.neutron(context) remove_os_gateway_router = (ec2utils.get_attached_gateway( context, vpc_id, 'igw') is None) subnets = [ subnet for subnet in db_api.get_items(context, 'subnet') if subnet['vpc_id'] == vpc['id'] ] with common.OnCrashCleaner() as cleaner: _detach_vpn_gateway_item(context, vpn_gateway) cleaner.addCleanup(_attach_vpn_gateway_item, context, vpn_gateway, vpc_id) vpn_connection_api._stop_gateway_vpn_connections( context, neutron, cleaner, vpn_gateway) for subnet in subnets: _delete_subnet_vpnservice(context, neutron, cleaner, subnet) if remove_os_gateway_router: try: neutron.remove_gateway_router(vpc['os_id']) except neutron_exception.NotFound: pass return True
def attach_network_interface(context, network_interface_id, instance_id, device_index): network_interface = ec2utils.get_db_item(context, network_interface_id) if 'instance_id' in network_interface: raise exception.InvalidParameterValue( _("Network interface '%(id)s' is currently in use.") % {'id': network_interface_id}) os_instance_id = ec2utils.get_db_item(context, instance_id)['os_id'] # TODO(Alex) Check that the instance is not yet attached to another VPC # TODO(Alex) Check that the instance is "our", not created via nova # (which means that it doesn't belong to any VPC and can't be attached) if any(eni['device_index'] == device_index for eni in db_api.get_items(context, 'eni') if eni.get('instance_id') == instance_id): raise exception.InvalidParameterValue( _("Instance '%(id)s' already has an interface attached at " "device index '%(index)s'.") % {'id': instance_id, 'index': device_index}) neutron = clients.neutron(context) os_port = neutron.show_port(network_interface['os_id'])['port'] nova = clients.nova(context) with common.OnCrashCleaner() as cleaner: # TODO(Alex) nova inserts compute:%availability_zone into device_owner # 'device_owner': 'compute:None'}}) _attach_network_interface_item(context, network_interface, instance_id, device_index) cleaner.addCleanup(_detach_network_interface_item, context, network_interface) nova.servers.interface_attach(os_instance_id, os_port['id'], None, None) return {'attachmentId': ec2utils.change_ec2_id_kind( network_interface['id'], 'eni-attach')}
def attach_internet_gateway(context, internet_gateway_id, vpc_id): igw = ec2utils.get_db_item(context, internet_gateway_id) if igw.get('vpc_id'): msg_params = {'igw_id': igw['id'], 'vpc_id': igw['vpc_id']} msg = _('resource %(igw_id)s is already attached to ' 'network %(vpc_id)s') % msg_params raise exception.ResourceAlreadyAssociated(msg) vpc = ec2utils.get_db_item(context, vpc_id) if ec2utils.get_attached_gateway(context, vpc['id'], 'igw'): msg = _('Network %(vpc_id)s already has an internet gateway ' 'attached') % {'vpc_id': vpc['id']} raise exception.InvalidParameterValue(msg) external_network_id = None if not ec2utils.get_attached_gateway(context, vpc['id'], 'vgw'): external_network_id = ec2utils.get_os_public_network(context)['id'] neutron = clients.neutron(context) # TODO(ft): set attaching state into db with common.OnCrashCleaner() as cleaner: _attach_internet_gateway_item(context, igw, vpc['id']) cleaner.addCleanup(_detach_internet_gateway_item, context, igw) if external_network_id: neutron.add_gateway_router(vpc['os_id'], {'network_id': external_network_id}) return True
def detach_internet_gateway(context, internet_gateway_id, vpc_id): igw = ec2utils.get_db_item(context, internet_gateway_id) vpc = ec2utils.get_db_item(context, vpc_id) LOG.info('Detaching %(igw)s internet-gateway from %(vpc)s.', {'igw': str(igw), 'vpc': str(vpc)}) if igw.get('vpc_id') != vpc['id']: raise exception.GatewayNotAttached(gw_id=igw['id'], vpc_id=vpc['id']) remove_os_gateway_router = ( ec2utils.get_attached_gateway(context, vpc_id, 'vgw') is None) neutron = clients.neutron(context) # TODO(ft): set detaching state into db with common.OnCrashCleaner() as cleaner: _detach_internet_gateway_item(context, igw) cleaner.addCleanup(_attach_internet_gateway_item, context, igw, vpc['id']) if remove_os_gateway_router: try: neutron.remove_gateway_router(vpc['os_id']) except neutron_exception.NotFound: pass except Exception as ex: floatingips=neutron.list_floatingips(tenant_id=context.project_id)['floatingips'] LOG.info('Existing floating ips: %(floatingips)s. Exception: %(ex)s.', {'floatingips': floatingips, 'ex': ex}) return True
def _create_security_group(context, group_name, group_description, vpc_id=None, default=False): neutron = clients.neutron(context) with common.OnCrashCleaner() as cleaner: try: secgroup_body = ( {'security_group': {'name': group_name, 'description': group_description}}) os_security_group = neutron.create_security_group( secgroup_body)['security_group'] except neutron_exception.OverQuotaClient: raise exception.ResourceLimitExceeded(resource='security groups') cleaner.addCleanup(neutron.delete_security_group, os_security_group['id']) if vpc_id: # NOTE(Alex) Check if such vpc exists ec2utils.get_db_item(context, vpc_id) item = {'vpc_id': vpc_id, 'os_id': os_security_group['id']} if not default: security_group = db_api.add_item(context, 'sg', item) else: item['id'] = ec2utils.change_ec2_id_kind(vpc_id, 'sg') # NOTE(andrey-mp): try to add item with specific id # and catch exception if it exists security_group = db_api.restore_item(context, 'sg', item) return {'return': 'true', 'groupId': security_group['id']}
def release_address(self, context, public_ip, allocation_id): 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 address and _is_address_valid(context, neutron, address): msg = _('You must specify an allocation id when releasing a ' 'VPC elastic IP address') raise exception.InvalidParameterValue(msg) return AddressEngineNova().release_address(context, public_ip, None) address = ec2utils.get_db_item(context, allocation_id) if not _is_address_valid(context, neutron, address): raise exception.InvalidAllocationIDNotFound( id=allocation_id) if 'network_interface_id' in address: raise exception.InvalidIPAddressInUse( ip_address=address['public_ip']) with common.OnCrashCleaner() as cleaner: db_api.delete_item(context, address['id']) cleaner.addCleanup(db_api.restore_item, context, 'eipalloc', address) try: neutron.delete_floatingip(address['os_id']) except neutron_exception.NotFound: pass
def delete_group(self, context, group_name=None, group_id=None, delete_default=False): neutron = clients.neutron(context) if group_name: sg = describe_security_groups( context, group_name=[group_name])['securityGroupInfo'][0] group_id = sg['groupId'] group_name = None security_group = ec2utils.get_db_item(context, group_id) try: if not delete_default: os_security_group = neutron.show_security_group( security_group['os_id']) if (os_security_group and os_security_group['security_group']['name'] == security_group['vpc_id']): raise exception.CannotDelete() neutron.delete_security_group(security_group['os_id']) except neutron_exception.Conflict as ex: # TODO(Alex): Instance ID is unknown here, report exception message # in its place - looks readable. raise exception.DependencyViolation( obj1_id=group_id, obj2_id=ex.message) except neutron_exception.NeutronClientException as ex: # TODO(Alex): do log error # TODO(Alex): adjust caught exception classes to catch: # the port doesn't exist pass db_api.delete_item(context, group_id)
def associate_dhcp_options(context, dhcp_options_id, vpc_id): vpc = ec2utils.get_db_item(context, vpc_id) rollback_dhcp_options_id = vpc.get('dhcp_options_id') if dhcp_options_id == 'default': dhcp_options_id = None dhcp_options = None else: dhcp_options = ec2utils.get_db_item(context, dhcp_options_id) dhcp_options_id = dhcp_options['id'] neutron = clients.neutron(context) os_ports = neutron.list_ports(tenant_id=context.project_id)['ports'] network_interfaces = db_api.get_items(context, 'eni') rollback_dhcp_options_object = (db_api.get_item_by_id( context, rollback_dhcp_options_id) if dhcp_options_id is not None else None) with common.OnCrashCleaner() as cleaner: _associate_vpc_item(context, vpc, dhcp_options_id) cleaner.addCleanup(_associate_vpc_item, context, vpc, rollback_dhcp_options_id) for network_interface in network_interfaces: os_port = next( (p for p in os_ports if p['id'] == network_interface['os_id']), None) if not os_port: continue _add_dhcp_opts_to_port(context, dhcp_options, network_interface, os_port, neutron) cleaner.addCleanup(_add_dhcp_opts_to_port, context, rollback_dhcp_options_object, network_interface, os_port, neutron) return True
def delete_group(self, context, group_name=None, group_id=None, delete_default=False): neutron = clients.neutron(context) if group_id is None or not group_id.startswith('sg-'): return SecurityGroupEngineNova().delete_group(context, group_name, group_id) security_group = ec2utils.get_db_item(context, group_id) try: if not delete_default: os_security_group = neutron.show_security_group( security_group['os_id']) if (os_security_group and os_security_group['security_group']['name'] == security_group['vpc_id']): raise exception.CannotDelete() neutron.delete_security_group(security_group['os_id']) except neutron_exception.Conflict as ex: # TODO(Alex): Instance ID is unknown here, report exception message # in its place - looks readable. raise exception.DependencyViolation( obj1_id=group_id, obj2_id=ex.message) except neutron_exception.NeutronClientException as ex: # TODO(Alex): do log error # TODO(Alex): adjust caught exception classes to catch: # the port doesn't exist pass db_api.delete_item(context, group_id)
def unassign_private_ip_addresses(context, network_interface_id, private_ip_address): network_interface = ec2utils.get_db_item(context, network_interface_id) if network_interface['private_ip_address'] in private_ip_address: raise exception.InvalidParameterValue( value=str(network_interface['private_ip_address']), parameter='PrivateIpAddresses', reason='Primary IP address cannot be unassigned') neutron = clients.neutron(context) os_port = neutron.show_port(network_interface['os_id'])['port'] fixed_ips = os_port['fixed_ips'] or [] new_fixed_ips = [ ip for ip in fixed_ips if ip['ip_address'] not in private_ip_address ] if len(new_fixed_ips) + len(private_ip_address) != len(fixed_ips): msg = _('Some of the specified addresses are not assigned to ' 'interface %(id)s') % { 'id': network_interface_id } raise exception.InvalidParameterValue(msg) os_port = neutron.update_port(os_port['id'], {'port': { 'fixed_ips': new_fixed_ips }}) return True
def delete_vpn_connection(context, vpn_connection_id): vpn_connection = ec2utils.get_db_item(context, vpn_connection_id) with common.OnCrashCleaner() as cleaner: db_api.delete_item(context, vpn_connection['id']) cleaner.addCleanup(db_api.restore_item, context, 'vpn', vpn_connection) neutron = clients.neutron(context) _stop_vpn_connection(neutron, vpn_connection) try: neutron.delete_ipsecpolicy(vpn_connection['os_ipsecpolicy_id']) except neutron_exception.Conflict as ex: LOG.warning( _('Failed to delete ipsecoplicy %(os_id)s during deleting ' 'VPN connection %(id)s. Reason: %(reason)s'), {'id': vpn_connection['id'], 'os_id': vpn_connection['os_ipsecpolicy_id'], 'reason': ex.message}) except neutron_exception.NotFound: pass try: neutron.delete_ikepolicy(vpn_connection['os_ikepolicy_id']) except neutron_exception.Conflict as ex: LOG.warning( _('Failed to delete ikepolicy %(os_id)s during deleting ' 'VPN connection %(id)s. Reason: %(reason)s'), {'id': vpn_connection['id'], 'os_id': vpn_connection['os_ikepolicy_id'], 'reason': ex.message}) except neutron_exception.NotFound: pass return True
def disassociate_address(self, context, public_ip=None, association_id=None): LOG.info('Disassociating %s', association_id) neutron = clients.neutron(context) floatingips=neutron.list_floatingips(tenant_id=context.project_id)['floatingips'] LOG.info('Existing floating ips: %s', floatingips) 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 address and _is_address_valid(context, neutron, address): msg = _('You must specify an association id when ' 'unmapping an address from a VPC instance') raise exception.InvalidParameterValue(msg) # NOTE(tikitavi): check the public IP exists to raise AWS # exception otherwise os_floating_ip = self.get_os_floating_ip_by_public_ip( context, public_ip) os_ports = self.get_os_ports(context) os_instance_id = _get_os_instance_id(context, os_floating_ip, os_ports) if os_instance_id: nova = clients.nova(context) nova.servers.remove_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}) if 'network_interface_id' not in address: msg = _('You must specify an association id when unmapping ' 'an address from a VPC instance') raise exception.InvalidParameterValue(msg) association_id = ec2utils.change_ec2_id_kind(address['id'], 'eipassoc') address = db_api.get_item_by_id( context, ec2utils.change_ec2_id_kind(association_id, 'eipalloc')) LOG.info('DB address: %s', address) if address is None or not _is_address_valid(context, neutron, address): raise exception.InvalidAssociationIDNotFound( id=association_id) if 'network_interface_id' in address: with common.OnCrashCleaner() as cleaner: network_interface_id = address['network_interface_id'] private_ip_address = address['private_ip_address'] LOG.info('Disassociating %(private_ip_address)s from interface %(network_interface_id)s', {'private_ip_address': private_ip_address, 'network_interface_id': network_interface_id}) _disassociate_address_item(context, address) cleaner.addCleanup(_associate_address_item, context, address, network_interface_id, private_ip_address) update = neutron.update_floatingip(address['os_id'], {'floatingip': {'port_id': None}}) LOG.info('Neutron.update result is %s', update)
def attach_vpn_gateway(context, vpc_id, vpn_gateway_id): vpn_gateway = ec2utils.get_db_item(context, vpn_gateway_id) vpc = ec2utils.get_db_item(context, vpc_id) if vpn_gateway["vpc_id"] and vpn_gateway["vpc_id"] != vpc["id"]: raise exception.VpnGatewayAttachmentLimitExceeded() attached_vgw = ec2utils.get_attached_gateway(context, vpc["id"], "vgw") if attached_vgw and attached_vgw["id"] != vpn_gateway["id"]: raise exception.InvalidVpcState(vpc_id=vpc["id"], vgw_id=attached_vgw["id"]) subnets = [subnet for subnet in db_api.get_items(context, "subnet") if subnet["vpc_id"] == vpc["id"]] if not vpn_gateway["vpc_id"]: external_network_id = None if not ec2utils.get_attached_gateway(context, vpc["id"], "igw"): external_network_id = ec2utils.get_os_public_network(context)["id"] neutron = clients.neutron(context) with common.OnCrashCleaner() as cleaner: _attach_vpn_gateway_item(context, vpn_gateway, vpc["id"]) cleaner.addCleanup(_detach_vpn_gateway_item, context, vpn_gateway) if external_network_id: neutron.add_gateway_router(vpc["os_id"], {"network_id": external_network_id}) cleaner.addCleanup(neutron.remove_gateway_router, vpc["os_id"]) for subnet in subnets: _create_subnet_vpnservice(context, neutron, cleaner, subnet, vpc) vpn_connection_api._reset_vpn_connections(context, neutron, cleaner, vpn_gateway, subnets=subnets) return {"attachment": _format_attachment(vpn_gateway)}
def get_os_items(self): neutron = clients.neutron(self.context) self.os_networks = neutron.list_networks( tenant_id=self.context.project_id)['networks'] self.os_ports = neutron.list_ports( tenant_id=self.context.project_id)['ports'] return neutron.list_subnets( tenant_id=self.context.project_id)['subnets']
def authorize_security_group(self, context, rule_body): neutron = clients.neutron(context) try: os_security_group_rule = neutron.create_security_group_rule( {'security_group_rule': rule_body})['security_group_rule'] except neutron_exception.OverQuotaClient: raise exception.RulesPerSecurityGroupLimitExceeded() except neutron_exception.Conflict as ex: raise exception.InvalidPermissionDuplicate()
def get_os_items(self): addresses = address_api.describe_addresses(self.context) self.ec2_addresses = collections.defaultdict(list) for address in addresses['addressesSet']: if 'networkInterfaceId' in address: self.ec2_addresses[ address['networkInterfaceId']].append(address) self.security_groups = ( security_group_api._format_security_groups_ids_names(self.context)) neutron = clients.neutron(self.context) return neutron.list_ports(tenant_id=self.context.project_id)['ports']
def get_os_group_by_name(self, context, group_name, os_security_groups=None): if os_security_groups is None: neutron = clients.neutron(context) os_security_groups = ( neutron.list_security_groups()['security_groups']) os_group = next((g for g in os_security_groups if g['name'] == group_name), None) if os_group is None: raise exception.InvalidGroupNotFound(id=group_name) return os_group
def create_subnet(context, vpc_id, cidr_block, availability_zone=None): vpc = ec2utils.get_db_item(context, vpc_id) vpc_ipnet = netaddr.IPNetwork(vpc['cidr_block']) subnet_ipnet = netaddr.IPNetwork(cidr_block) if subnet_ipnet not in vpc_ipnet: raise exception.InvalidSubnetRange(cidr_block=cidr_block) main_route_table = db_api.get_item_by_id(context, vpc['route_table_id']) (host_routes, gateway_ip) = route_table_api._get_subnet_host_routes_and_gateway_ip( context, main_route_table, cidr_block) neutron = clients.neutron(context) with common.OnCrashCleaner() as cleaner: # NOTE(andrey-mp): set fake name to filter networks in instance api os_network_body = {'network': {'name': 'subnet-0'}} try: os_network = neutron.create_network(os_network_body)['network'] cleaner.addCleanup(neutron.delete_network, os_network['id']) # NOTE(Alex): AWS takes 4 first addresses (.1 - .4) but for # OpenStack we decided not to support this as compatibility. os_subnet_body = {'subnet': {'network_id': os_network['id'], 'ip_version': '4', 'cidr': cidr_block, 'host_routes': host_routes}} os_subnet = neutron.create_subnet(os_subnet_body)['subnet'] cleaner.addCleanup(neutron.delete_subnet, os_subnet['id']) except neutron_exception.OverQuotaClient: raise exception.SubnetLimitExceeded() try: neutron.add_interface_router(vpc['os_id'], {'subnet_id': os_subnet['id']}) except neutron_exception.BadRequest: raise exception.InvalidSubnetConflict(cidr_block=cidr_block) cleaner.addCleanup(neutron.remove_interface_router, vpc['os_id'], {'subnet_id': os_subnet['id']}) subnet = db_api.add_item(context, 'subnet', {'os_id': os_subnet['id'], 'vpc_id': vpc['id']}) cleaner.addCleanup(db_api.delete_item, context, subnet['id']) vpn_gateway_api._start_vpn_in_subnet(context, neutron, cleaner, subnet, vpc, main_route_table) neutron.update_network(os_network['id'], {'network': {'name': subnet['id']}}) # NOTE(ft): In some cases we need gateway_ip to be None (see # _get_subnet_host_routes_and_gateway_ip). It's not set during subnet # creation to allow automatic configuration of the default port by # which subnet is attached to the router. neutron.update_subnet(os_subnet['id'], {'subnet': {'name': subnet['id'], 'gateway_ip': gateway_ip}}) os_ports = neutron.list_ports(tenant_id=context.project_id)['ports'] return {'subnet': _format_subnet(context, subnet, os_subnet, os_network, os_ports)}
def get_os_items(self): addresses = address_api.describe_addresses(self.context) self.ec2_addresses = collections.defaultdict(list) for address in addresses['addressesSet']: if 'networkInterfaceId' in address: self.ec2_addresses[address['networkInterfaceId']].append( address) self.security_groups = ( security_group_api._format_security_groups_ids_names(self.context)) neutron = clients.neutron(self.context) return neutron.list_ports(tenant_id=self.context.project_id)['ports']
def create_subnet(context, vpc_id, cidr_block, availability_zone=None): vpc = ec2utils.get_db_item(context, vpc_id) vpc_ipnet = netaddr.IPNetwork(vpc['cidr_block']) subnet_ipnet = netaddr.IPNetwork(cidr_block) if subnet_ipnet not in vpc_ipnet: raise exception.InvalidSubnetRange(cidr_block=cidr_block) main_route_table = db_api.get_item_by_id(context, vpc['route_table_id']) (host_routes, gateway_ip) = route_table_api._get_subnet_host_routes_and_gateway_ip( context, main_route_table, cidr_block) neutron = clients.neutron(context) with common.OnCrashCleaner() as cleaner: os_network_body = {'network': {}} try: os_network = neutron.create_network(os_network_body)['network'] cleaner.addCleanup(neutron.delete_network, os_network['id']) # NOTE(Alex): AWS takes 4 first addresses (.1 - .4) but for # OpenStack we decided not to support this as compatibility. os_subnet_body = {'subnet': {'network_id': os_network['id'], 'ip_version': '4', 'cidr': cidr_block, 'host_routes': host_routes}} os_subnet = neutron.create_subnet(os_subnet_body)['subnet'] cleaner.addCleanup(neutron.delete_subnet, os_subnet['id']) except neutron_exception.OverQuotaClient: raise exception.SubnetLimitExceeded() try: neutron.add_interface_router(vpc['os_id'], {'subnet_id': os_subnet['id']}) except neutron_exception.BadRequest: raise exception.InvalidSubnetConflict(cidr_block=cidr_block) cleaner.addCleanup(neutron.remove_interface_router, vpc['os_id'], {'subnet_id': os_subnet['id']}) subnet = db_api.add_item(context, 'subnet', {'os_id': os_subnet['id'], 'vpc_id': vpc['id']}) cleaner.addCleanup(db_api.delete_item, context, subnet['id']) vpn_gateway_api._start_vpn_in_subnet(context, neutron, cleaner, subnet, vpc, main_route_table) neutron.update_network(os_network['id'], {'network': {'name': subnet['id']}}) # NOTE(ft): In some cases we need gateway_ip to be None (see # _get_subnet_host_routes_and_gateway_ip). It's not set during subnet # creation to allow automatic configuration of the default port by # which subnet is attached to the router. neutron.update_subnet(os_subnet['id'], {'subnet': {'name': subnet['id'], 'gateway_ip': gateway_ip}}) os_ports = neutron.list_ports(tenant_id=context.project_id)['ports'] return {'subnet': _format_subnet(context, subnet, os_subnet, os_network, os_ports)}
def release_address(self, context, public_ip, allocation_id): 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 address and _is_address_valid(context, neutron, address): msg = _('You must specify an allocation id when releasing a ' 'VPC elastic IP address') raise exception.InvalidParameterValue(msg) os_floating_ip = self.get_os_floating_ip_by_public_ip(context, public_ip) try: neutron.delete_floatingip(os_floating_ip['id']) except neutron_exception.NotFound: pass return address = ec2utils.get_db_item(context, allocation_id) if not _is_address_valid(context, neutron, address): raise exception.InvalidAllocationIDNotFound( id=allocation_id) if 'network_interface_id' in address: if CONF.disable_ec2_classic: network_interface_id = address['network_interface_id'] network_interface = db_api.get_item_by_id(context, network_interface_id) default_vpc = ec2utils.check_and_create_default_vpc(context) if default_vpc: default_vpc_id = default_vpc['id'] if (network_interface and network_interface['vpc_id'] == default_vpc_id): association_id = ec2utils.change_ec2_id_kind(address['id'], 'eipassoc') self.disassociate_address( context, association_id=association_id) else: raise exception.InvalidIPAddressInUse( ip_address=address['public_ip']) else: raise exception.InvalidIPAddressInUse( ip_address=address['public_ip']) with common.OnCrashCleaner() as cleaner: db_api.delete_item(context, address['id']) cleaner.addCleanup(db_api.restore_item, context, 'eipalloc', address) try: neutron.delete_floatingip(address['os_id']) except neutron_exception.NotFound: pass
def disassociate_address(self, context, public_ip=None, association_id=None): 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 address and _is_address_valid(context, neutron, address): msg = _('You must specify an association id when ' 'unmapping an address from a VPC instance') raise exception.InvalidParameterValue(msg) # NOTE(tikitavi): check the public IP exists to raise AWS # exception otherwise os_floating_ip = self.get_os_floating_ip_by_public_ip( context, public_ip) os_ports = self.get_os_ports(context) os_instance_id = _get_os_instance_id(context, os_floating_ip, os_ports) if os_instance_id: nova = clients.nova(context) nova.servers.remove_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}) if 'network_interface_id' not in address: msg = _('You must specify an association id when unmapping ' 'an address from a VPC instance') raise exception.InvalidParameterValue(msg) association_id = ec2utils.change_ec2_id_kind(address['id'], 'eipassoc') address = db_api.get_item_by_id( context, ec2utils.change_ec2_id_kind(association_id, 'eipalloc')) if address is None or not _is_address_valid(context, neutron, address): raise exception.InvalidAssociationIDNotFound( id=association_id) if 'network_interface_id' in address: with common.OnCrashCleaner() as cleaner: network_interface_id = address['network_interface_id'] private_ip_address = address['private_ip_address'] _disassociate_address_item(context, address) cleaner.addCleanup(_associate_address_item, context, address, network_interface_id, private_ip_address) neutron.update_floatingip(address['os_id'], {'floatingip': {'port_id': None}})
def _add_dhcp_opts_to_port(context, dhcp_options, network_interface, os_port, neutron=None): dhcp_opts = [{'opt_name': 'mtu', 'opt_value': str(CONF.network_device_mtu)}] if dhcp_options is not None: for key, values in dhcp_options['dhcp_configuration'].items(): strvalues = [str(v) for v in values] dhcp_opts.append({'opt_name': DHCP_OPTIONS_MAP[key], 'opt_value': ','.join(strvalues)}) if not neutron: neutron = clients.neutron(context) neutron.update_port(os_port['id'], {'port': {'extra_dhcp_opts': dhcp_opts}})
def modify_network_interface_attribute(context, network_interface_id, description=None, source_dest_check=None, security_group_id=None, attachment=None): params_count = (int(description is not None) + int(source_dest_check is not None) + int(security_group_id is not None) + int(attachment is not None)) if params_count != 1: raise exception.InvalidParameterCombination( 'Multiple attributes specified') network_interface = ec2utils.get_db_item(context, network_interface_id) if description is not None: network_interface['description'] = description db_api.update_item(context, network_interface) neutron = clients.neutron(context) if security_group_id is not None: os_groups = [ sg['os_id'] for sg in ec2utils.get_db_items(context, 'sg', security_group_id) ] neutron.update_port(network_interface['os_id'], {'port': { 'security_groups': os_groups }}) if source_dest_check is not None: allowed = [] if source_dest_check else [{'ip_address': '0.0.0.0/0'}] neutron.update_port(network_interface['os_id'], {'port': { 'allowed_address_pairs': allowed }}) network_interface['source_dest_check'] = source_dest_check db_api.update_item(context, network_interface) if attachment: attachment_id = attachment.get('attachment_id') delete_on_termination = attachment.get('delete_on_termination') if attachment_id is None or delete_on_termination is None: raise exception.MissingParameter( _('The request must contain the parameter attachment ' 'deleteOnTermination')) attachment_id_own = ec2utils.change_ec2_id_kind( network_interface['id'], 'eni-attach') if ('instance_id' not in network_interface or attachment_id_own != attachment_id): raise exception.InvalidAttachmentIDNotFound(id=attachment_id) network_interface['delete_on_termination'] = delete_on_termination db_api.update_item(context, network_interface) 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 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 _format_security_groups_ids_names(context): neutron = clients.neutron(context) os_security_groups = neutron.list_security_groups( tenant_id=context.project_id)['security_groups'] security_groups = db_api.get_items(context, 'sg') ec2_security_groups = {} for os_security_group in os_security_groups: security_group = next((g for g in security_groups if g['os_id'] == os_security_group['id']), None) if security_group is None: continue ec2_security_groups[os_security_group['id']] = ( {'groupId': security_group['id'], 'groupName': _translate_group_name(context, os_security_group, security_groups)}) return ec2_security_groups
def _create_vpc(context, cidr_block, is_default=False): neutron = clients.neutron(context) with common.OnCrashCleaner() as cleaner: os_router_body = {'router': {}} try: os_router = neutron.create_router(os_router_body)['router'] except neutron_exception.OverQuotaClient: raise exception.VpcLimitExceeded() cleaner.addCleanup(neutron.delete_router, os_router['id']) vpc = db_api.add_item( context, 'vpc', { 'os_id': os_router['id'], 'cidr_block': cidr_block, 'is_default': is_default }) cleaner.addCleanup(db_api.delete_item, context, vpc['id']) route_table = route_table_api._create_route_table(context, vpc) cleaner.addCleanup(route_table_api._delete_route_table, context, route_table['id']) vpc['route_table_id'] = route_table['id'] db_api.update_item(context, vpc) neutron.update_router(os_router['id'], {'router': {'name': vpc['id']}}) sg_id = security_group_api._create_default_security_group(context, vpc) cleaner.addCleanup(security_group_api.delete_security_group, context, group_id=sg_id, delete_default=True) if is_default: igw_id = internet_gateway_api.create_internet_gateway( context)['internetGateway']['internetGatewayId'] cleaner.addCleanup(internet_gateway_api.delete_internet_gateway, context, igw_id) internet_gateway_api.attach_internet_gateway( context, igw_id, vpc['id']) cleaner.addCleanup(internet_gateway_api.detach_internet_gateway, context, igw_id, vpc['id']) subnet = subnet_api.create_subnet( context, vpc['id'], DEFAULT_SUBNET_CIDR_BLOCK)['subnet'] cleaner.addCleanup(subnet_api.delete_subnet, context, subnet['subnetId']) route_table_api.create_route(context, route_table['id'], '0.0.0.0/0', gateway_id=igw_id) return vpc
def modify_network_interface_attribute(context, network_interface_id, description=None, source_dest_check=None, security_group_id=None, attachment=None): params_count = ( int(description is not None) + int(source_dest_check is not None) + int(security_group_id is not None) + int(attachment is not None)) if params_count != 1: raise exception.InvalidParameterCombination( 'Multiple attributes specified') network_interface = ec2utils.get_db_item(context, network_interface_id) if description is not None: network_interface['description'] = description db_api.update_item(context, network_interface) neutron = clients.neutron(context) if security_group_id is not None: os_groups = [sg['os_id'] for sg in ec2utils.get_db_items(context, 'sg', security_group_id)] neutron.update_port(network_interface['os_id'], {'port': {'security_groups': os_groups}}) if source_dest_check is not None: allowed = [] if source_dest_check else [{'ip_address': '0.0.0.0/0'}] neutron.update_port(network_interface['os_id'], {'port': {'allowed_address_pairs': allowed}}) network_interface['source_dest_check'] = source_dest_check db_api.update_item(context, network_interface) if attachment: attachment_id = attachment.get('attachment_id') delete_on_termination = attachment.get('delete_on_termination') if attachment_id is None or delete_on_termination is None: raise exception.MissingParameter( _('The request must contain the parameter attachment ' 'deleteOnTermination')) attachment_id_own = ec2utils.change_ec2_id_kind( network_interface['id'], 'eni-attach') if ('instance_id' not in network_interface or attachment_id_own != attachment_id): raise exception.InvalidAttachmentIDNotFound(id=attachment_id) network_interface['delete_on_termination'] = delete_on_termination db_api.update_item(context, network_interface) return True
def create_vpn_connection_route(context, vpn_connection_id, destination_cidr_block): vpn_connection = ec2utils.get_db_item(context, vpn_connection_id) if destination_cidr_block in vpn_connection['cidrs']: return True neutron = clients.neutron(context) vpn_gateway = db_api.get_item_by_id(context, vpn_connection['vpn_gateway_id']) with common.OnCrashCleaner() as cleaner: _add_cidr_to_vpn_connection_item(context, vpn_connection, destination_cidr_block) cleaner.addCleanup(_remove_cidr_from_vpn_connection_item, context, vpn_connection, destination_cidr_block) _reset_vpn_connections(context, neutron, cleaner, vpn_gateway, vpn_connections=[vpn_connection]) return True
def get_os_public_network(context): neutron = clients.neutron(context) search_opts = {'router:external': True, 'name': CONF.external_network} os_networks = neutron.list_networks(**search_opts)['networks'] if len(os_networks) != 1: if CONF.external_network: if len(os_networks) == 0: msg = "No external network with name '%s' is found" else: msg = "More than one external network with name '%s' is found" LOG.error(msg, CONF.external_network) else: if len(os_networks) == 0: msg = 'No external network is found' else: msg = 'More than one external network is found' LOG.error(msg) raise exception.Unsupported(_('Feature is restricted by OS admin')) return os_networks[0]
def delete_subnet(context, subnet_id): subnet = ec2utils.get_db_item(context, subnet_id) vpc = db_api.get_item_by_id(context, subnet['vpc_id']) network_interfaces = network_interface_api.describe_network_interfaces( context, filter=[{ 'name': 'subnet-id', 'value': [subnet_id] }])['networkInterfaceSet'] if network_interfaces: msg = _("The subnet '%(subnet_id)s' has dependencies and " "cannot be deleted.") % { 'subnet_id': subnet_id } raise exception.DependencyViolation(msg) neutron = clients.neutron(context) with common.OnCrashCleaner() as cleaner: db_api.delete_item(context, subnet['id']) cleaner.addCleanup(db_api.restore_item, context, 'subnet', subnet) vpn_gateway_api._stop_vpn_in_subnet(context, neutron, cleaner, subnet) try: neutron.remove_interface_router(vpc['os_id'], {'subnet_id': subnet['os_id']}) except neutron_exception.NotFound: pass cleaner.addCleanup(neutron.add_interface_router, vpc['os_id'], {'subnet_id': subnet['os_id']}) try: os_subnet = neutron.show_subnet(subnet['os_id'])['subnet'] except neutron_exception.NotFound: pass else: try: neutron.delete_network(os_subnet['network_id']) except neutron_exception.NetworkInUseClient as ex: LOG.warning( _('Failed to delete network %(os_id)s during ' 'deleting Subnet %(id)s. Reason: %(reason)s'), { 'id': subnet['id'], 'os_id': os_subnet['network_id'], 'reason': ex.message }) return True
def assign_private_ip_addresses(context, network_interface_id, private_ip_address=None, secondary_private_ip_address_count=None, allow_reassignment=False): # TODO(Alex): allow_reassignment is not supported at the moment network_interface = ec2utils.get_db_item(context, network_interface_id) subnet = db_api.get_item_by_id(context, network_interface['subnet_id']) neutron = clients.neutron(context) os_subnet = neutron.show_subnet(subnet['os_id'])['subnet'] os_port = neutron.show_port(network_interface['os_id'])['port'] subnet_ipnet = netaddr.IPNetwork(os_subnet['cidr']) fixed_ips = os_port['fixed_ips'] or [] if private_ip_address is not None: for ip_address in private_ip_address: if netaddr.IPAddress(ip_address) not in subnet_ipnet: raise exception.InvalidParameterValue( value=str(ip_address), parameter='PrivateIpAddress', reason='IP address is out of the subnet range') fixed_ips.append({'ip_address': str(ip_address)}) elif secondary_private_ip_address_count > 0: for _i in range(secondary_private_ip_address_count): fixed_ips.append({'subnet_id': os_subnet['id']}) try: neutron.update_port(os_port['id'], {'port': {'fixed_ips': fixed_ips}}) except neutron_exception.IpAddressGenerationFailureClient: raise exception.InsufficientFreeAddressesInSubnet() except neutron_exception.IpAddressInUseClient: msg = _('Some of %(addresses)s is assigned, but move is not ' 'allowed.') % { 'addresses': private_ip_address } raise exception.InvalidParameterValue(msg) except neutron_exception.BadRequest as ex: # NOTE(ft):AWS returns PrivateIpAddressLimitExceeded, but Neutron does # general InvalidInput (converted to BadRequest) in the same case. msg = _('Specified network interface parameters are invalid. ' 'Reason: %(reason)s') % { 'reason': ex.message } raise exception.InvalidParameterValue(msg) return True
def get_db_items(self): self.customer_gateways = { cgw['id']: cgw for cgw in db_api.get_items(self.context, 'cgw')} neutron = clients.neutron(self.context) self.os_ikepolicies = { ike['id']: ike for ike in neutron.list_ikepolicies( tenant_id=self.context.project_id)['ikepolicies']} self.os_ipsecpolicies = { ipsec['id']: ipsec for ipsec in neutron.list_ipsecpolicies( tenant_id=self.context.project_id)['ipsecpolicies']} self.os_ipsec_site_connections = { conn['id']: conn for conn in neutron.list_ipsec_site_connections( tenant_id=self.context.project_id)['ipsec_site_connections']} self.external_ips = _get_vpn_gateways_external_ips( self.context, neutron) return super(VpnConnectionDescriber, self).get_db_items()
def unassign_private_ip_addresses(context, network_interface_id, private_ip_address): network_interface = ec2utils.get_db_item(context, network_interface_id) if network_interface['private_ip_address'] in private_ip_address: raise exception.InvalidParameterValue( value=str(network_interface['private_ip_address']), parameter='PrivateIpAddresses', reason='Primary IP address cannot be unassigned') neutron = clients.neutron(context) os_port = neutron.show_port(network_interface['os_id'])['port'] fixed_ips = os_port['fixed_ips'] or [] new_fixed_ips = [ip for ip in fixed_ips if ip['ip_address'] not in private_ip_address] if len(new_fixed_ips) + len(private_ip_address) != len(fixed_ips): msg = _('Some of the specified addresses are not assigned to ' 'interface %(id)s') % {'id': network_interface_id} raise exception.InvalidParameterValue(msg) os_port = neutron.update_port(os_port['id'], {'port': {'fixed_ips': new_fixed_ips}}) return True
def allocate_address(self, context, domain=None): if not domain or domain == 'standard': return AddressEngineNova().allocate_address(context) os_public_network = ec2utils.get_os_public_network(context) neutron = clients.neutron(context) with common.OnCrashCleaner() as cleaner: os_floating_ip = {'floating_network_id': os_public_network['id']} try: os_floating_ip = neutron.create_floatingip( {'floatingip': os_floating_ip}) except neutron_exception.OverQuotaClient: raise exception.AddressLimitExceeded() os_floating_ip = os_floating_ip['floatingip'] cleaner.addCleanup(neutron.delete_floatingip, os_floating_ip['id']) address = {'os_id': os_floating_ip['id'], 'public_ip': os_floating_ip['floating_ip_address']} address = db_api.add_item(context, 'eipalloc', address) return address, os_floating_ip
def delete_vpn_connection_route(context, vpn_connection_id, destination_cidr_block): vpn_connection = ec2utils.get_db_item(context, vpn_connection_id) if destination_cidr_block not in vpn_connection['cidrs']: raise exception.InvalidRouteNotFound( _('The specified route %(destination_cidr_block)s does not exist') % {'destination_cidr_block': destination_cidr_block}) neutron = clients.neutron(context) vpn_gateway = db_api.get_item_by_id(context, vpn_connection['vpn_gateway_id']) with common.OnCrashCleaner() as cleaner: _remove_cidr_from_vpn_connection_item(context, vpn_connection, destination_cidr_block) cleaner.addCleanup(_add_cidr_to_vpn_connection_item, context, vpn_connection, destination_cidr_block) _reset_vpn_connections(context, neutron, cleaner, vpn_gateway, vpn_connections=[vpn_connection]) return True
def detach_internet_gateway(context, internet_gateway_id, vpc_id): igw = ec2utils.get_db_item(context, internet_gateway_id) vpc = ec2utils.get_db_item(context, vpc_id) if igw.get('vpc_id') != vpc['id']: raise exception.GatewayNotAttached(gw_id=igw['id'], vpc_id=vpc['id']) remove_os_gateway_router = (ec2utils.get_attached_gateway( context, vpc_id, 'vgw') is None) neutron = clients.neutron(context) # TODO(ft): set detaching state into db with common.OnCrashCleaner() as cleaner: _detach_internet_gateway_item(context, igw) cleaner.addCleanup(_attach_internet_gateway_item, context, igw, vpc['id']) if remove_os_gateway_router: try: neutron.remove_gateway_router(vpc['os_id']) except neutron_exception.NotFound: pass return True
def _update_routes_in_associated_subnets(context, cleaner, route_table, default_associations_only=None, update_target=None): if default_associations_only: appropriate_rtb_ids = (None,) else: vpc = db_api.get_item_by_id(context, route_table['vpc_id']) if vpc['route_table_id'] == route_table['id']: appropriate_rtb_ids = (route_table['id'], None) else: appropriate_rtb_ids = (route_table['id'],) neutron = clients.neutron(context) subnets = [subnet for subnet in db_api.get_items(context, 'subnet') if (subnet['vpc_id'] == route_table['vpc_id'] and subnet.get('route_table_id') in appropriate_rtb_ids)] # NOTE(ft): we need to update host routes for both host and vpn target # because vpn-related routes are present in host routes as well _update_host_routes(context, neutron, cleaner, route_table, subnets) if not update_target or update_target == VPN_TARGET: vpn_connection_api._update_vpn_routes(context, neutron, cleaner, route_table, subnets)
def detach_internet_gateway(context, internet_gateway_id, vpc_id): igw = ec2utils.get_db_item(context, internet_gateway_id) vpc = ec2utils.get_db_item(context, vpc_id) if igw.get('vpc_id') != vpc['id']: raise exception.GatewayNotAttached(gw_id=igw['id'], vpc_id=vpc['id']) remove_os_gateway_router = ( ec2utils.get_attached_gateway(context, vpc_id, 'vgw') is None) neutron = clients.neutron(context) # TODO(ft): set detaching state into db with common.OnCrashCleaner() as cleaner: _detach_internet_gateway_item(context, igw) cleaner.addCleanup(_attach_internet_gateway_item, context, igw, vpc['id']) if remove_os_gateway_router: try: neutron.remove_gateway_router(vpc['os_id']) except neutron_exception.NotFound: pass return True
def create_vpc(context, cidr_block, instance_tenancy='default'): neutron = clients.neutron(context) with common.OnCrashCleaner() as cleaner: os_router_body = {'router': {}} try: os_router = neutron.create_router(os_router_body)['router'] except neutron_exception.OverQuotaClient: raise exception.VpcLimitExceeded() cleaner.addCleanup(neutron.delete_router, os_router['id']) vpc = db_api.add_item(context, 'vpc', {'os_id': os_router['id'], 'cidr_block': cidr_block}) cleaner.addCleanup(db_api.delete_item, context, vpc['id']) route_table = route_table_api._create_route_table(context, vpc) cleaner.addCleanup(route_table_api._delete_route_table, context, route_table['id']) vpc['route_table_id'] = route_table['id'] db_api.update_item(context, vpc) neutron.update_router(os_router['id'], {'router': {'name': vpc['id']}}) security_group_api._create_default_security_group(context, vpc) return {'vpc': _format_vpc(vpc)}
def delete_network_interface(context, network_interface_id): network_interface = ec2utils.get_db_item(context, network_interface_id) if 'instance_id' in network_interface: msg = _("Network interface '%(eni_id)s' is currently in use.") msg = msg % {'eni_id': network_interface_id} raise exception.InvalidParameterValue(msg) for address in db_api.get_items(context, 'eipalloc'): if address.get('network_interface_id') == network_interface['id']: address_api._disassociate_address_item(context, address) neutron = clients.neutron(context) with common.OnCrashCleaner() as cleaner: db_api.delete_item(context, network_interface['id']) cleaner.addCleanup(db_api.restore_item, context, 'eni', network_interface) try: neutron.delete_port(network_interface['os_id']) except neutron_exception.PortNotFoundClient: pass return True