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)
    # TODO(ft): move search by vpc_id to DB api
    for gw in db_api.get_items(context, 'igw'):
        if gw.get('vpc_id') == vpc['id']:
            msg = _("Network %(vpc_id)s already has an internet gateway "
                    "attached") % {
                        'vpc_id': vpc['id']
                    }
            raise exception.InvalidParameterValue(msg)

    os_public_network = ec2utils.get_os_public_network(context)
    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)
        neutron.add_gateway_router(vpc['os_id'],
                                   {'network_id': os_public_network['id']})
    return True
예제 #2
0
    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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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')}
예제 #8
0
    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
예제 #9
0
 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)
예제 #10
0
    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}})
예제 #11
0
    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
                                          }})
예제 #12
0
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
예제 #13
0
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 _update_routes_in_associated_subnets(context,
                                         route_table,
                                         cleaner,
                                         rollabck_route_table_object,
                                         is_main=None):
    if is_main is None:
        vpc = db_api.get_item_by_id(context, route_table['vpc_id'])
        is_main = vpc['route_table_id'] == route_table['id']
    if is_main:
        appropriate_rtb_ids = (route_table['id'], None)
    else:
        appropriate_rtb_ids = (route_table['id'], )
    router_objects = _get_router_objects(context, route_table)
    neutron = clients.neutron(context)
    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):
            _update_subnet_host_routes(
                context,
                subnet,
                route_table,
                cleaner=cleaner,
                rollback_route_table_object=rollabck_route_table_object,
                router_objects=router_objects,
                neutron=neutron)
예제 #15
0
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 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)
예제 #17
0
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
예제 #18
0
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)
예제 #19
0
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
예제 #20
0
 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']
예제 #21
0
 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()
예제 #23
0
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
예제 #24
0
 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()
예제 #25
0
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)

    gateway_ip = str(netaddr.IPAddress(subnet_ipnet.first + 1))
    main_route_table = db_api.get_item_by_id(context, vpc['route_table_id'])
    host_routes = route_table_api._get_subnet_host_routes(
        context, main_route_table, gateway_ip)
    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'])
        neutron.update_network(os_network['id'],
                               {'network': {
                                   'name': subnet['id']
                               }})
        neutron.update_subnet(os_subnet['id'],
                              {'subnet': {
                                  'name': subnet['id']
                              }})
    os_ports = neutron.list_ports(tenant_id=context.project_id)['ports']
    return {
        'subnet': _format_subnet(context, subnet, os_subnet, os_network,
                                 os_ports)
    }
예제 #26
0
 def test_neutron(self, neutron):
     context = mock.Mock(
         auth_token='fake_token',
         service_catalog=[{'type': 'network',
                           'endpoints': [{'publicURL': 'neutron_url'}]}])
     res = clients.neutron(context)
     self.assertEqual(neutron.return_value, res)
     neutron.assert_called_with(
         auth_url='keystone_url', cacert=None, service_type='network',
         insecure=False, token='fake_token', endpoint_url='neutron_url')
예제 #27
0
 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']
예제 #28
0
 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']
예제 #29
0
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)}
예제 #30
0
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}})
예제 #31
0
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
예제 #32
0
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 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(igw_id=igw['id'], vpc_id=vpc['id'])

    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'])
        try:
            neutron.remove_gateway_router(vpc["os_id"])
        except neutron_exception.NotFound:
            pass
    return True
예제 #34
0
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 _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
예제 #36
0
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
예제 #37
0
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
예제 #38
0
def get_os_instance_and_project_id_by_provider_id(context, provider_id,
                                                  fixed_ip):
    neutron = clients.neutron(context)
    os_subnets = neutron.list_subnets(advanced_service_providers=[provider_id],
                                      fields=['network_id'])
    if not os_subnets:
        raise exception.EC2MetadataNotFound()
    os_networks = [subnet['network_id'] for subnet in os_subnets['subnets']]
    try:
        os_port = neutron.list_ports(fixed_ips='ip_address=' + fixed_ip,
                                     network_id=os_networks,
                                     fields=['device_id',
                                             'tenant_id'])['ports'][0]
    except IndexError:
        raise exception.EC2MetadataNotFound()
    os_instance_id = os_port['device_id']
    project_id = os_port['tenant_id']
    return os_instance_id, project_id
예제 #39
0
파일: api.py 프로젝트: openstack/ec2-api
def get_os_instance_and_project_id_by_provider_id(context, provider_id,
                                                  fixed_ip):
    neutron = clients.neutron(context)
    os_subnets = neutron.list_subnets(advanced_service_providers=[provider_id],
                                      fields=['network_id'])
    if not os_subnets:
        raise exception.EC2MetadataNotFound()
    os_networks = [subnet['network_id']
                   for subnet in os_subnets['subnets']]
    try:
        os_port = neutron.list_ports(
            fixed_ips='ip_address=' + fixed_ip,
            network_id=os_networks,
            fields=['device_id', 'tenant_id'])['ports'][0]
    except IndexError:
        raise exception.EC2MetadataNotFound()
    os_instance_id = os_port['device_id']
    project_id = os_port['tenant_id']
    return os_instance_id, project_id
예제 #40
0
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
예제 #41
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
예제 #42
0
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 = _LE("No external network with name '%s' is found")
            else:
                msg = _LE("More than one external network with name '%s' "
                          "is found")
            LOG.error(msg, CONF.external_network)
        else:
            if len(os_networks) == 0:
                msg = _LE('No external network is found')
            else:
                msg = _LE('More than one external network is found')
            LOG.error(msg)
        raise exception.Unsupported(_('Feature is restricted by OS admin'))
    return os_networks[0]
예제 #43
0
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 = _LE("No external network with name '%s' is found")
            else:
                msg = _LE("More than one external network with name '%s' "
                          "is found")
            LOG.error(msg, CONF.external_network)
        else:
            if len(os_networks) == 0:
                msg = _LE('No external network is found')
            else:
                msg = _LE('More than one external network is found')
            LOG.error(msg)
        raise exception.Unsupported(_('Feature is restricted by OS admin'))
    return os_networks[0]
예제 #44
0
    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 _update_subnet_host_routes(context,
                               subnet,
                               route_table,
                               cleaner=None,
                               rollback_route_table_object=None,
                               router_objects=None,
                               neutron=None):
    neutron = neutron or clients.neutron(context)
    os_subnet = neutron.show_subnet(subnet['os_id'])['subnet']
    gateway_ip = str(
        netaddr.IPAddress(netaddr.IPNetwork(os_subnet['cidr']).first + 1))
    host_routes = _get_subnet_host_routes(context, route_table, gateway_ip,
                                          router_objects)
    neutron.update_subnet(subnet['os_id'],
                          {'subnet': {
                              'host_routes': host_routes
                          }})
    if cleaner and rollback_route_table_object:
        cleaner.addCleanup(_update_subnet_host_routes, context, subnet,
                           rollback_route_table_object)
예제 #46
0
 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()
예제 #47
0
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
예제 #48
0
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
예제 #49
0
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)
예제 #50
0
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)}
예제 #51
0
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
예제 #52
0
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
예제 #53
0
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.NetworkInterfaceLimitExceeded(
                    subnet_id=subnet['id'])
    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
예제 #54
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
예제 #55
0
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
예제 #56
0
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