def get_os_group_by_name(self, context, group_name, os_security_groups=None): if os_security_groups is None: neutron = clients.neutron(context) os_security_groups = ( neutron.list_security_groups()['security_groups']) os_group = next((g for g in os_security_groups if g['name'] == group_name), None) if os_group is None: raise exception.InvalidGroupNotFound(id=group_name) return os_group
def get_nova_group_by_name(self, context, group_name, nova_security_groups=None): if nova_security_groups is None: nova = clients.nova(context) nova_security_groups = nova.security_groups.list() nova_group = next( (g for g in nova_security_groups if g.name == group_name), None) if nova_group is None: raise exception.InvalidGroupNotFound(id=group_name) return nova_group
def create_network_interface(context, subnet_id, private_ip_address=None, private_ip_addresses=None, secondary_private_ip_address_count=None, description=None, security_group_id=None): subnet = ec2utils.get_db_item(context, subnet_id) if subnet is None: raise exception.InvalidSubnetIDNotFound(id=subnet_id) neutron = clients.neutron(context) os_subnet = neutron.show_subnet(subnet['os_id'])['subnet'] # NOTE(Alex): Combine and check ip addresses. Neutron will accept # ip_address as a parameter for specified address and subnet_id for # address to auto-allocate. # TODO(Alex): Implement better diagnostics. subnet_ipnet = netaddr.IPNetwork(os_subnet['cidr']) if not private_ip_addresses: private_ip_addresses = [] if private_ip_address is not None: private_ip_addresses.insert(0, { 'private_ip_address': private_ip_address, 'primary': True }) primary_ip = None fixed_ips = [] for ip in private_ip_addresses: ip_address = netaddr.IPAddress(ip['private_ip_address']) if ip_address not in subnet_ipnet: raise exception.InvalidParameterValue( value=str(ip_address), parameter='PrivateIpAddresses', reason='IP address is out of the subnet range') if ip.get('primary', False): if primary_ip is not None: raise exception.InvalidParameterValue( value=str(ip_address), parameter='PrivateIpAddresses', reason='More than one primary ip is supplied') else: primary_ip = str(ip_address) fixed_ips.insert(0, {'ip_address': primary_ip}) else: fixed_ips.append({'ip_address': str(ip_address)}) if not fixed_ips and not secondary_private_ip_address_count: secondary_private_ip_address_count = 1 if secondary_private_ip_address_count is None: secondary_private_ip_address_count = 0 if secondary_private_ip_address_count > 0: for _i in range(secondary_private_ip_address_count): fixed_ips.append({'subnet_id': os_subnet['id']}) vpc = db_api.get_item_by_id(context, subnet['vpc_id']) vpc_id = vpc['id'] dhcp_options_id = vpc.get('dhcp_options_id', None) if not security_group_id: default_groups = security_group_api.describe_security_groups( context, filter=[{ 'name': 'vpc-id', 'value': [vpc_id] }, { 'name': 'group-name', 'value': ['default'] }])['securityGroupInfo'] security_group_id = [ default_group['groupId'] for default_group in default_groups ] security_groups = db_api.get_items_by_ids(context, security_group_id) if any(security_group['vpc_id'] != vpc['id'] for security_group in security_groups): msg = _('You have specified two resources that belong to ' 'different networks.') raise exception.InvalidGroupNotFound(msg) os_groups = [security_group['os_id'] for security_group in security_groups] with common.OnCrashCleaner() as cleaner: os_port_body = { 'port': { 'network_id': os_subnet['network_id'], 'security_groups': os_groups } } os_port_body['port']['fixed_ips'] = fixed_ips try: os_port = neutron.create_port(os_port_body)['port'] except (neutron_exception.IpAddressGenerationFailureClient, neutron_exception.OverQuotaClient): raise exception.InsufficientFreeAddressesInSubnet() except (neutron_exception.IpAddressInUseClient, neutron_exception.BadRequest) as ex: # NOTE(ft): AWS returns InvalidIPAddress.InUse for a primary IP # address, but InvalidParameterValue for secondary one. # 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) cleaner.addCleanup(neutron.delete_port, os_port['id']) if primary_ip is None: primary_ip = os_port['fixed_ips'][0]['ip_address'] network_interface = db_api.add_item( context, 'eni', { 'os_id': os_port['id'], 'vpc_id': subnet['vpc_id'], 'subnet_id': subnet['id'], 'description': description, 'private_ip_address': primary_ip }) cleaner.addCleanup(db_api.delete_item, context, network_interface['id']) network_interface_id = network_interface['id'] neutron.update_port(os_port['id'], {'port': { 'name': network_interface_id }}) if dhcp_options_id: dhcp_options._add_dhcp_opts_to_port( context, db_api.get_item_by_id(context, dhcp_options_id), network_interface, os_port) security_groups = security_group_api._format_security_groups_ids_names( context) return { 'networkInterface': _format_network_interface(context, network_interface, os_port, security_groups=security_groups) }