def unassign_private_ip_addresses(context, network_interface_id, private_ip_address): network_interface = ec2utils.get_db_item(context, network_interface_id) if network_interface['private_ip_address'] in private_ip_address: raise exception.InvalidParameterValue( value=str(network_interface['private_ip_address']), parameter='PrivateIpAddresses', reason='Primary IP address cannot be unassigned') neutron = clients.neutron(context) os_port = neutron.show_port(network_interface['os_id'])['port'] fixed_ips = os_port['fixed_ips'] or [] new_fixed_ips = [ ip for ip in fixed_ips if ip['ip_address'] not in private_ip_address ] if len(new_fixed_ips) + len(private_ip_address) != len(fixed_ips): msg = _('Some of the specified addresses are not assigned to ' 'interface %(id)s') % { 'id': network_interface_id } raise exception.InvalidParameterValue(msg) os_port = neutron.update_port(os_port['id'], {'port': { 'fixed_ips': new_fixed_ips }}) return True
def disassociate_address(self, context, public_ip=None, association_id=None): LOG.info('Disassociating %s', association_id) neutron = clients.neutron(context) floatingips=neutron.list_floatingips(tenant_id=context.project_id)['floatingips'] LOG.info('Existing floating ips: %s', floatingips) if public_ip: # TODO(ft): implement search in DB layer address = next((addr for addr in db_api.get_items(context, 'eipalloc') if addr['public_ip'] == public_ip), None) if not CONF.disable_ec2_classic: if address and _is_address_valid(context, neutron, address): msg = _('You must specify an association id when ' 'unmapping an address from a VPC instance') raise exception.InvalidParameterValue(msg) # NOTE(tikitavi): check the public IP exists to raise AWS # exception otherwise os_floating_ip = self.get_os_floating_ip_by_public_ip( context, public_ip) os_ports = self.get_os_ports(context) os_instance_id = _get_os_instance_id(context, os_floating_ip, os_ports) if os_instance_id: nova = clients.nova(context) nova.servers.remove_floating_ip(os_instance_id, public_ip) return None if not address: msg = _("The address '%(public_ip)s' does not belong to you.") raise exception.AuthFailure(msg % {'public_ip': public_ip}) if 'network_interface_id' not in address: msg = _('You must specify an association id when unmapping ' 'an address from a VPC instance') raise exception.InvalidParameterValue(msg) association_id = ec2utils.change_ec2_id_kind(address['id'], 'eipassoc') address = db_api.get_item_by_id( context, ec2utils.change_ec2_id_kind(association_id, 'eipalloc')) LOG.info('DB address: %s', address) if address is None or not _is_address_valid(context, neutron, address): raise exception.InvalidAssociationIDNotFound( id=association_id) if 'network_interface_id' in address: with common.OnCrashCleaner() as cleaner: network_interface_id = address['network_interface_id'] private_ip_address = address['private_ip_address'] LOG.info('Disassociating %(private_ip_address)s from interface %(network_interface_id)s', {'private_ip_address': private_ip_address, 'network_interface_id': network_interface_id}) _disassociate_address_item(context, address) cleaner.addCleanup(_associate_address_item, context, address, network_interface_id, private_ip_address) update = neutron.update_floatingip(address['os_id'], {'floatingip': {'port_id': None}}) LOG.info('Neutron.update result is %s', update)
def attach_network_interface(context, network_interface_id, instance_id, device_index): network_interface = ec2utils.get_db_item(context, network_interface_id) if 'instance_id' in network_interface: raise exception.InvalidParameterValue( _("Network interface '%(id)s' is currently in use.") % {'id': network_interface_id}) os_instance_id = ec2utils.get_db_item(context, instance_id)['os_id'] # TODO(Alex) Check that the instance is not yet attached to another VPC # TODO(Alex) Check that the instance is "our", not created via nova # (which means that it doesn't belong to any VPC and can't be attached) if any(eni['device_index'] == device_index for eni in db_api.get_items(context, 'eni') if eni.get('instance_id') == instance_id): raise exception.InvalidParameterValue( _("Instance '%(id)s' already has an interface attached at " "device index '%(index)s'.") % {'id': instance_id, 'index': device_index}) neutron = clients.neutron(context) os_port = neutron.show_port(network_interface['os_id'])['port'] nova = clients.nova(context) with common.OnCrashCleaner() as cleaner: # TODO(Alex) nova inserts compute:%availability_zone into device_owner # 'device_owner': 'compute:None'}}) _attach_network_interface_item(context, network_interface, instance_id, device_index) cleaner.addCleanup(_detach_network_interface_item, context, network_interface) nova.servers.interface_attach(os_instance_id, os_port['id'], None, None) return {'attachmentId': ec2utils.change_ec2_id_kind( network_interface['id'], 'eni-attach')}
def 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)}
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.'))
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
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)
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')
def validate_vpn_connection_type(value): if value != 'ipsec.1': raise exception.InvalidParameterValue( value=type, parameter='type', reason=_('Invalid VPN connection type.')) return True
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)
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
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'))
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)
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
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
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') }
def attach_internet_gateway(context, internet_gateway_id, vpc_id): igw = ec2utils.get_db_item(context, internet_gateway_id) if igw.get('vpc_id'): msg_params = {'igw_id': igw['id'], 'vpc_id': igw['vpc_id']} msg = _('resource %(igw_id)s is already attached to ' 'network %(vpc_id)s') % msg_params raise exception.ResourceAlreadyAssociated(msg) vpc = ec2utils.get_db_item(context, vpc_id) if ec2utils.get_attached_gateway(context, vpc['id'], 'igw'): msg = _('Network %(vpc_id)s already has an internet gateway ' 'attached') % { 'vpc_id': vpc['id'] } raise exception.InvalidParameterValue(msg) external_network_id = None if not ec2utils.get_attached_gateway(context, vpc['id'], 'vgw'): external_network_id = ec2utils.get_os_public_network(context)['id'] neutron = clients.neutron(context) # TODO(ft): set attaching state into db with common.OnCrashCleaner() as cleaner: _attach_internet_gateway_item(context, igw, vpc['id']) cleaner.addCleanup(_detach_internet_gateway_item, context, igw) if external_network_id: neutron.add_gateway_router(vpc['os_id'], {'network_id': external_network_id}) return True
def 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
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)
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'))
def assign_private_ip_addresses(context, network_interface_id, private_ip_address=None, secondary_private_ip_address_count=None, allow_reassignment=False): # TODO(Alex): allow_reassignment is not supported at the moment network_interface = ec2utils.get_db_item(context, network_interface_id) subnet = db_api.get_item_by_id(context, network_interface['subnet_id']) neutron = clients.neutron(context) os_subnet = neutron.show_subnet(subnet['os_id'])['subnet'] os_port = neutron.show_port(network_interface['os_id'])['port'] subnet_ipnet = netaddr.IPNetwork(os_subnet['cidr']) fixed_ips = os_port['fixed_ips'] or [] if private_ip_address is not None: for ip_address in private_ip_address: if netaddr.IPAddress(ip_address) not in subnet_ipnet: raise exception.InvalidParameterValue( value=str(ip_address), parameter='PrivateIpAddress', reason='IP address is out of the subnet range') fixed_ips.append({'ip_address': str(ip_address)}) elif secondary_private_ip_address_count > 0: for _i in range(secondary_private_ip_address_count): fixed_ips.append({'subnet_id': os_subnet['id']}) try: neutron.update_port(os_port['id'], {'port': {'fixed_ips': fixed_ips}}) except neutron_exception.IpAddressGenerationFailureClient: raise exception.InsufficientFreeAddressesInSubnet() except neutron_exception.IpAddressInUseClient: msg = _('Some of %(addresses)s is assigned, but move is not ' 'allowed.') % { 'addresses': private_ip_address } raise exception.InvalidParameterValue(msg) except neutron_exception.BadRequest as ex: # NOTE(ft):AWS returns PrivateIpAddressLimitExceeded, but Neutron does # general InvalidInput (converted to BadRequest) in the same case. msg = _('Specified network interface parameters are invalid. ' 'Reason: %(reason)s') % { 'reason': ex.message } raise exception.InvalidParameterValue(msg) return True
def 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}
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)
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
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
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
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