Exemplo n.º 1
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
Exemplo n.º 2
0
    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)
Exemplo n.º 3
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')}
Exemplo n.º 4
0
def create_dhcp_options(context, dhcp_configuration):
    dhcp_options = {}
    for dhcp_option in dhcp_configuration:
        key = dhcp_option['key']
        values = dhcp_option['value']
        if key not in DHCP_OPTIONS_MAP:
            raise exception.InvalidParameterValue(
                value=values,
                parameter=key,
                reason='Unrecognized key is specified')
        if not type(values) is list:
            raise exception.InvalidParameterValue(
                value=values,
                parameter=key,
                reason='List of values is expected')
        if key not in ['domain-name', 'netbios-node-type']:
            ips = []
            for ip in values:
                ip_address = netaddr.IPAddress(ip)
                if not ip_address:
                    raise exception.InvalidParameterValue(
                        value=ip,
                        parameter=key,
                        reason='Invalid list of IPs is specified')
                ips.append(ip)
            dhcp_options[key] = ips
        else:
            dhcp_options[key] = values
    dhcp_options = db_api.add_item(context, 'dopt',
                                   {'dhcp_configuration': dhcp_options})
    return {'dhcpOptions': _format_dhcp_options(context, dhcp_options)}
Exemplo n.º 5
0
def _validate_parameters(protocol, from_port, to_port):
    if (not isinstance(protocol, int) and
            protocol not in ['tcp', 'udp', 'icmp']):
        raise exception.InvalidParameterValue(
            _('Invalid value for IP protocol. Unknown protocol.'))
    if (not isinstance(from_port, int) or
            not isinstance(to_port, int)):
        raise exception.InvalidParameterValue(
            _('Integer values should be specified for ports'))
    if protocol in ['tcp', 'udp', 6, 17]:
        if from_port == -1 or to_port == -1:
            raise exception.InvalidParameterValue(
                _('Must specify both from and to ports with TCP/UDP.'))
        if from_port > to_port:
            raise exception.InvalidParameterValue(
                _('Invalid TCP/UDP port range.'))
        if from_port < 0 or from_port > 65535:
            raise exception.InvalidParameterValue(
                _('TCP/UDP from port is out of range.'))
        if to_port < 0 or to_port > 65535:
            raise exception.InvalidParameterValue(
                _('TCP/UDP to port is out of range.'))
    elif protocol in ['icmp', 1]:
        if from_port < -1 or from_port > 255:
            raise exception.InvalidParameterValue(
                _('ICMP type is out of range.'))
        if to_port < -1 or to_port > 255:
            raise exception.InvalidParameterValue(
                _('ICMP code is out of range.'))
Exemplo n.º 6
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 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(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)

            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 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
Exemplo n.º 8
0
def allocate_address(context, domain=None):
    if domain and domain not in ['vpc', 'standard']:
        msg = _("Invalid value '%(domain)s' for domain.") % {'domain': domain}
        raise exception.InvalidParameterValue(msg)

    address, os_floating_ip = address_engine.allocate_address(context, domain)
    return _format_address(context, address, os_floating_ip)
Exemplo n.º 9
0
def revoke_security_group_egress(context, group_id, ip_permissions=None):
    security_group = ec2utils.get_db_item(context, group_id)
    if not security_group.get('vpc_id'):
        raise exception.InvalidParameterValue(message=_('Only Amazon VPC '
            'security groups may be used with this operation.'))
    return _revoke_security_group(context, group_id, None,
                                  ip_permissions, 'egress')
Exemplo n.º 10
0
def validate_vpn_connection_type(value):
    if value != 'ipsec.1':
        raise exception.InvalidParameterValue(
            value=type,
            parameter='type',
            reason=_('Invalid VPN connection type.'))
    return True
Exemplo n.º 11
0
def create_security_group(context, group_name, group_description,
                          vpc_id=None):
    if group_name == DEFAULT_GROUP_NAME:
        if vpc_id:
            raise exception.InvalidParameterValue(
                _('Cannot use reserved security group name: %s')
                % DEFAULT_GROUP_NAME)
        else:
            raise exception.InvalidGroupReserved(group_name=group_name)
    filter = [{'name': 'group-name',
               'value': [group_name]}]
    if not vpc_id and CONF.disable_ec2_classic:
        vpc_id = ec2utils.get_default_vpc(context)['id']
    if vpc_id and group_name != vpc_id:
        filter.append({'name': 'vpc-id',
                       'value': [vpc_id]})
    security_groups = describe_security_groups(
        context, filter=filter)['securityGroupInfo']
    if not vpc_id:
        # TODO(andrey-mp): remove it when fitering by None will be implemented
        security_groups = [sg for sg in security_groups
                           if sg.get('vpcId') is None]
    if security_groups:
        raise exception.InvalidGroupDuplicate(name=group_name)
    return _create_security_group(context, group_name, group_description,
                                  vpc_id)
Exemplo n.º 12
0
def validate_key_value_dict_list(dict_list, parameter_name):
    for dict in dict_list:
        if not dict.get('key') or dict.get('value') is None:
            raise exception.InvalidParameterValue(
                value=dict, parameter=parameter_name,
                reason=_('Expected list of key value dictionaries'))
    return True
Exemplo n.º 13
0
def validate_enum(value, allowed_values, parameter_name, allow_empty=False):
    if value is None and allow_empty or value in allowed_values:
        return True
    raise exception.InvalidParameterValue(
        value=value,
        parameter=parameter_name,
        reason=_('Invalid parameter value specified'))
Exemplo n.º 14
0
    def describe(self,
                 context,
                 ids=None,
                 names=None,
                 filter=None,
                 max_results=None,
                 next_token=None):
        if max_results and max_results < 5:
            msg = (_('Value ( %s ) for parameter maxResults is invalid. '
                     'Expecting a value greater than 5.') % max_results)
            raise exception.InvalidParameterValue(msg)

        self.context = context
        self.ids = ids
        self.items = self.get_db_items()
        formatted_items = []

        for item in self.items:
            formatted_item = self.format(item)
            self.post_format(formatted_item, item)
            if (formatted_item
                    and not self.filtered_out(formatted_item, filter)):
                formatted_items.append(formatted_item)

        return self.get_paged(formatted_items, max_results, next_token)
Exemplo n.º 15
0
def delete_route(context, route_table_id, destination_cidr_block):
    route_table = ec2utils.get_db_item(context, route_table_id)
    for route_index, route in enumerate(route_table['routes']):
        if route['destination_cidr_block'] != destination_cidr_block:
            continue
        if route.get('gateway_id', 0) is None:
            msg = _('cannot remove local route %(destination_cidr_block)s '
                    'in route table %(route_table_id)s')
            msg = msg % {'route_table_id': route_table_id,
                         'destination_cidr_block': destination_cidr_block}
            raise exception.InvalidParameterValue(msg)
        break
    else:
        raise exception.InvalidRouteNotFound(
            route_table_id=route_table_id,
            destination_cidr_block=destination_cidr_block)
    update_target = _get_route_target(route)
    if update_target == VPN_TARGET:
        vpn_gateway = db_api.get_item_by_id(context, route['gateway_id'])
        if (not vpn_gateway or
                vpn_gateway['vpc_id'] != route_table['vpc_id']):
            update_target = None
    rollback_route_table_state = copy.deepcopy(route_table)
    del route_table['routes'][route_index]
    with common.OnCrashCleaner() as cleaner:
        db_api.update_item(context, route_table)
        cleaner.addCleanup(db_api.update_item, context,
                           rollback_route_table_state)

        if update_target:
            _update_routes_in_associated_subnets(
                context, cleaner, route_table, update_target=update_target)

    return True
Exemplo n.º 16
0
def disassociate_route_table(context, association_id):
    subnet = db_api.get_item_by_id(
        context, ec2utils.change_ec2_id_kind(association_id, 'subnet'))
    if not subnet:
        vpc = db_api.get_item_by_id(
            context, ec2utils.change_ec2_id_kind(association_id, 'vpc'))
        if vpc is None:
            raise exception.InvalidAssociationIDNotFound(id=association_id)
        msg = _('Cannot disassociate the main route table association '
                '%(rtbassoc_id)s') % {'rtbassoc_id': association_id}
        raise exception.InvalidParameterValue(msg)
    if 'route_table_id' not in subnet:
        raise exception.InvalidAssociationIDNotFound(id=association_id)

    rollback_route_table_id = subnet['route_table_id']
    vpc = db_api.get_item_by_id(context, subnet['vpc_id'])
    main_route_table = db_api.get_item_by_id(context, vpc['route_table_id'])
    with common.OnCrashCleaner() as cleaner:
        _disassociate_subnet_item(context, subnet)
        cleaner.addCleanup(_associate_subnet_item, context, subnet,
                           rollback_route_table_id)

        _update_subnet_routes(context, cleaner, subnet, main_route_table)

    return True
Exemplo n.º 17
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
def associate_route_table(context, route_table_id, subnet_id):
    route_table = ec2utils.get_db_item(context, route_table_id)
    subnet = ec2utils.get_db_item(context, subnet_id)
    if route_table['vpc_id'] != subnet['vpc_id']:
        msg = _('Route table %(rtb_id)s and subnet %(subnet_id)s belong to '
                'different networks')
        msg = msg % {'rtb_id': route_table_id, 'subnet_id': subnet_id}
        raise exception.InvalidParameterValue(msg)
    if 'route_table_id' in subnet:
        msg = _('The specified association for route table %(rtb_id)s '
                'conflicts with an existing association')
        msg = msg % {'rtb_id': route_table_id}
        raise exception.ResourceAlreadyAssociated(msg)

    vpc = db_api.get_item_by_id(context, subnet['vpc_id'])
    main_route_table = db_api.get_item_by_id(context, vpc['route_table_id'])
    with common.OnCrashCleaner() as cleaner:
        _associate_subnet_item(context, subnet, route_table['id'])
        cleaner.addCleanup(_disassociate_subnet_item, context, subnet)

        _update_subnet_host_routes(
            context,
            subnet,
            route_table,
            cleaner=cleaner,
            rollback_route_table_object=main_route_table)

    return {
        'associationId': ec2utils.change_ec2_id_kind(subnet['id'], 'rtbassoc')
    }
Exemplo n.º 19
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
Exemplo n.º 20
0
def validate_cidr_with_ipv6(cidr, parameter_name, **kwargs):
    invalid_format_exception = exception.InvalidParameterValue(
        value=cidr,
        parameter=parameter_name,
        reason='This is not a valid CIDR block.')
    if not _is_valid_cidr(cidr):
        raise invalid_format_exception
    return True
Exemplo n.º 21
0
    def describe(self, context, ids=None, names=None, filter=None,
                 max_results=None, next_token=None):
        if max_results and max_results < 5:
            msg = (_('Value ( %s ) for parameter maxResults is invalid. '
                     'Expecting a value greater than 5.') % max_results)
            raise exception.InvalidParameterValue(msg)

        self.context = context
        self.selective_describe = ids is not None or names is not None
        self.ids = set(ids or [])
        self.names = set(names or [])
        self.items = self.get_db_items()
        self.os_items = self.get_os_items()
        formatted_items = []

        self.items_dict = {i['os_id']: i for i in (self.items or [])}
        paired_items_ids = set()
        for os_item in self.os_items:
            os_item_name = self.get_name(os_item)
            os_item_id = self.get_id(os_item)
            item = self.items_dict.get(os_item_id, None)
            if item:
                paired_items_ids.add(item['id'])
            # NOTE(Alex): Filter out items not requested in names or ids
            if (self.selective_describe and
                    not self.is_selected_item(context, os_item_name, item)):
                continue
            # NOTE(Alex): Autoupdate DB for autoupdatable items
            item = self.auto_update_db(item, os_item)
            # NOTE(andrey-mp): save item id again
            # (if item has created by auto update)
            if item:
                paired_items_ids.add(item['id'])
            formatted_item = self.format(item, os_item)
            self.post_format(formatted_item, item)
            if os_item_name in self.names:
                self.names.remove(os_item_name)
            if item and item['id'] in self.ids:
                self.ids.remove(item['id'])
            if (formatted_item and
                    not self.filtered_out(formatted_item, filter)):
                formatted_items.append(formatted_item)
        # NOTE(Alex): delete obsolete items
        for item in self.items:
            if item['id'] in paired_items_ids:
                continue
            formatted_item = self.handle_unpaired_item(item)
            if formatted_item:
                if not self.filtered_out(formatted_item, filter):
                    formatted_items.append(formatted_item)
                if item['id'] in self.ids:
                    self.ids.remove(item['id'])
        # NOTE(Alex): some requested items are not found
        if self.ids or self.names:
            params = {'id': next(iter(self.ids or self.names))}
            raise ec2utils.NOT_FOUND_EXCEPTION_MAP[self.KIND](**params)

        return self.get_paged(formatted_items, max_results, next_token)
Exemplo n.º 22
0
def validate_ipv4(address, parameter_name):
    """Verify that address represents a valid IPv4 address."""
    try:
        if netaddr.valid_ipv4(address):
            return True
    except Exception:
        pass
    raise exception.InvalidParameterValue(
        value=address, parameter=parameter_name,
        reason=_('Not a valid IP address'))
Exemplo n.º 23
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
Exemplo n.º 24
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)
            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 replace_route_table_association(context, association_id, route_table_id):
    route_table = ec2utils.get_db_item(context, route_table_id)
    if route_table['vpc_id'] == ec2utils.change_ec2_id_kind(
            association_id, 'vpc'):
        vpc = db_api.get_item_by_id(
            context, ec2utils.change_ec2_id_kind(association_id, 'vpc'))
        if vpc is None:
            raise exception.InvalidAssociationIDNotFound(id=association_id)

        rollabck_route_table_object = db_api.get_item_by_id(
            context, vpc['route_table_id'])
        with common.OnCrashCleaner() as cleaner:
            _associate_vpc_item(context, vpc, route_table['id'])
            cleaner.addCleanup(_associate_vpc_item, context, vpc,
                               rollabck_route_table_object['id'])

            # NOTE(ft): this can cause unnecessary update of subnets, which are
            # associated with the route table
            _update_routes_in_associated_subnets(context,
                                                 route_table,
                                                 cleaner,
                                                 rollabck_route_table_object,
                                                 is_main=True)
    else:
        subnet = db_api.get_item_by_id(
            context, ec2utils.change_ec2_id_kind(association_id, 'subnet'))
        if subnet is None or 'route_table_id' not in subnet:
            raise exception.InvalidAssociationIDNotFound(id=association_id)
        if subnet['vpc_id'] != route_table['vpc_id']:
            msg = _('Route table association %(rtbassoc_id)s and route table '
                    '%(rtb_id)s belong to different networks')
            msg = msg % {
                'rtbassoc_id': association_id,
                'rtb_id': route_table_id
            }
            raise exception.InvalidParameterValue(msg)

        rollabck_route_table_object = db_api.get_item_by_id(
            context, subnet['route_table_id'])
        with common.OnCrashCleaner() as cleaner:
            _associate_subnet_item(context, subnet, route_table['id'])
            cleaner.addCleanup(_associate_subnet_item, context, subnet,
                               rollabck_route_table_object['id'])

            _update_subnet_host_routes(
                context,
                subnet,
                route_table,
                cleaner=cleaner,
                rollback_route_table_object=rollabck_route_table_object)

    return {'newAssociationId': association_id}
Exemplo n.º 26
0
def validate_ec2_id(val, parameter_name, prefices):
    try:
        prefix, value = val.rsplit('-', 1)
        int(value, 16)
        if not prefices or prefix in prefices:
            return True
    except Exception:
        pass

    if not prefices:
        reason = _('Invalid EC2 id was specified.')
    else:
        reason = _('Expected: %(prefix)s-...') % {'prefix': prefices[0]}
    raise exception.InvalidParameterValue(
        value=val, parameter=parameter_name, reason=reason)
Exemplo n.º 27
0
def validate_cidr(cidr, parameter_name):
    invalid_format_exception = exception.InvalidParameterValue(
        value=cidr,
        parameter=parameter_name,
        reason='This is not a valid CIDR block.')
    if not _cidr_re.match(cidr):
        raise invalid_format_exception
    address, size = cidr.split("/")
    octets = address.split(".")
    if any(int(octet) > 255 for octet in octets):
        raise invalid_format_exception
    size = int(size)
    if size > 32:
        raise invalid_format_exception
    return True
Exemplo n.º 28
0
def describe_network_interface_attribute(context,
                                         network_interface_id,
                                         attribute=None):
    if attribute is None:
        raise exception.InvalidParameterCombination(
            _('No attributes specified.'))
    network_interface = ec2utils.get_db_item(context, network_interface_id)

    def _format_attr_description(result):
        result['description'] = {
            'value': network_interface.get('description', '')
        }

    def _format_attr_source_dest_check(result):
        result['sourceDestCheck'] = {
            'value': network_interface.get('source_dest_check', True)
        }

    def _format_attr_group_set(result):
        ec2_network_interface = describe_network_interfaces(
            context, network_interface_id=[network_interface_id
                                           ])['networkInterfaceSet'][0]
        result['groupSet'] = ec2_network_interface['groupSet']

    def _format_attr_attachment(result):
        ec2_network_interface = describe_network_interfaces(
            context, network_interface_id=[network_interface_id
                                           ])['networkInterfaceSet'][0]
        if 'attachment' in ec2_network_interface:
            result['attachment'] = ec2_network_interface['attachment']

    attribute_formatter = {
        'description': _format_attr_description,
        'sourceDestCheck': _format_attr_source_dest_check,
        'groupSet': _format_attr_group_set,
        'attachment': _format_attr_attachment,
    }

    fn = attribute_formatter.get(attribute)
    if fn is None:
        raise exception.InvalidParameterValue(value=attribute,
                                              parameter='attribute',
                                              reason='Unknown attribute.')

    result = {'networkInterfaceId': network_interface['id']}
    fn(result)
    return result
Exemplo n.º 29
0
 def filtered_out(self, item, filters):
     if filters is None:
         return False
     for filter in filters:
         filter_name = self.FILTER_MAP.get(filter['name'])
         if filter_name is None:
             raise exception.InvalidParameterValue(
                 value=filter['name'], parameter='filter',
                 reason='invalid filter')
         values = self.get_values_by_filter(filter_name, item)
         if not values:
             return True
         filter_values = filter['value']
         for filter_value in filter_values:
             if any(self.is_filtering_value_found(filter_value, value)
                    for value in values):
                 break
         else:
             return True
     return False
Exemplo n.º 30
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