Example #1
0
    def test_get_items_by_ids(self):
        self._setup_items()
        fake_kind_items = db_api.get_items(self.context, 'fake')
        fake1_kind_items = db_api.get_items(self.context, 'fake1')
        item_id = fake_kind_items[0]['id']
        other_item_id = db_api.get_items(self.other_context, 'fake')[0]['id']

        items = db_api.get_items_by_ids(self.context, [])
        self.assertEqual(0, len(items))
        items = db_api.get_items_by_ids(self.context, set([]))
        self.assertEqual(0, len(items))
        items = db_api.get_items_by_ids(self.context,
                                        [i['id'] for i in fake_kind_items])
        self.assertEqual(2, len(items))
        items = db_api.get_items_by_ids(
            self.context,
            (fake_kind_items[0]['id'], fake1_kind_items[0]['id']))
        self.assertEqual(2, len(items))
        items = db_api.get_items_by_ids(self.context, (item_id, ))
        self.assertEqual(1, len(items))
        self.assertEqual(item_id, items[0]['id'])
        items = db_api.get_items_by_ids(self.context, (other_item_id, ))
        self.assertEqual(0, len(items))
        items = db_api.get_items_by_ids(self.context, (item_id, other_item_id))
        self.assertEqual(1, len(items))
        items = db_api.get_items_by_ids(
            self.context,
            (fakes.random_ec2_id('fake')),
        )
        self.assertEqual(0, len(items))
        items = db_api.get_items_by_ids(self.context,
                                        (item_id, fakes.random_ec2_id('fake')))
        self.assertEqual(1, len(items))
Example #2
0
    def test_get_items_by_ids(self):
        self._setup_items()
        fake_kind_items = db_api.get_items(self.context, 'fake')
        fake1_kind_items = db_api.get_items(self.context, 'fake1')
        item_id = fake_kind_items[0]['id']
        other_item_id = db_api.get_items(self.other_context, 'fake')[0]['id']

        items = db_api.get_items_by_ids(self.context, [])
        self.assertEqual(0, len(items))
        items = db_api.get_items_by_ids(self.context, set([]))
        self.assertEqual(0, len(items))
        items = db_api.get_items_by_ids(self.context,
                                        [i['id'] for i in fake_kind_items])
        self.assertEqual(2, len(items))
        items = db_api.get_items_by_ids(
            self.context, (fake_kind_items[0]['id'],
                           fake1_kind_items[0]['id']))
        self.assertEqual(2, len(items))
        items = db_api.get_items_by_ids(self.context, (item_id,))
        self.assertEqual(1, len(items))
        self.assertEqual(item_id, items[0]['id'])
        items = db_api.get_items_by_ids(self.context, (other_item_id,))
        self.assertEqual(0, len(items))
        items = db_api.get_items_by_ids(self.context,
                                        (item_id, other_item_id))
        self.assertEqual(1, len(items))
        items = db_api.get_items_by_ids(self.context,
                                        (fakes.random_ec2_id('fake')),)
        self.assertEqual(0, len(items))
        items = db_api.get_items_by_ids(self.context,
                                        (item_id, fakes.random_ec2_id('fake')))
        self.assertEqual(1, len(items))
Example #3
0
def get_db_items(context, kind, ec2_ids):
    if not ec2_ids:
        return db_api.get_items(context, kind)

    if not isinstance(ec2_ids, set):
        ec2_ids = set(ec2_ids)
    items = db_api.get_items_by_ids(context, ec2_ids)
    if len(items) < len(ec2_ids):
        missed_ids = ec2_ids - set((item['id'] for item in items))
        params = {'id': next(iter(missed_ids))}
        raise NOT_FOUND_EXCEPTION_MAP[kind](**params)
    return items
Example #4
0
def _get_active_route_destinations(context, route_table):
    vpn_connections = {vpn['vpn_gateway_id']: vpn
                       for vpn in db_api.get_items(context, 'vpn')}
    dst_ids = [route[id_key]
               for route in route_table['routes']
               for id_key in ('gateway_id', 'network_interface_id')
               if route.get(id_key) is not None]
    dst_ids.extend(route_table.get('propagating_gateways', []))
    destinations = {item['id']: item
                    for item in db_api.get_items_by_ids(context, dst_ids)
                    if (item['vpc_id'] == route_table['vpc_id'] and
                        (ec2utils.get_ec2_id_kind(item['id']) != 'vgw' or
                         item['id'] in vpn_connections))}
    for vpn in six.itervalues(vpn_connections):
        if vpn['vpn_gateway_id'] in destinations:
            destinations[vpn['vpn_gateway_id']]['vpn_connection'] = vpn
    return destinations
Example #5
0
def _get_active_route_destinations(context, route_table):
    vpn_connections = {vpn['vpn_gateway_id']: vpn
                       for vpn in db_api.get_items(context, 'vpn')}
    dst_ids = [route[id_key]
               for route in route_table['routes']
               for id_key in ('gateway_id', 'network_interface_id')
               if route.get(id_key) is not None]
    dst_ids.extend(route_table.get('propagating_gateways', []))
    destinations = {item['id']: item
                    for item in db_api.get_items_by_ids(context, dst_ids)
                    if (item['vpc_id'] == route_table['vpc_id'] and
                        (ec2utils.get_ec2_id_kind(item['id']) != 'vgw' or
                         item['id'] in vpn_connections))}
    for vpn in six.itervalues(vpn_connections):
        if vpn['vpn_gateway_id'] in destinations:
            destinations[vpn['vpn_gateway_id']]['vpn_connection'] = vpn
    return destinations
Example #6
0
    def get_db_items(self):
        # TODO(ft): we can't get all images from DB per one request due
        # different kinds. It's need to refactor DB API and ec2utils functions
        # to work with kind smarter
        if self.ids:
            local_images = db_api.get_items_by_ids(self.context, self.ids)
        else:
            local_images = sum((db_api.get_items(self.context, kind)
                                for kind in ('ami', 'ari', 'aki')), [])
        public_images = sum(
            (db_api.get_public_items(self.context, kind, self.ids)
             for kind in ('ami', 'ari', 'aki')), [])

        mapped_ids = []
        if self.ids:
            mapped_ids = [{
                'id': item_id,
                'os_id': os_id
            } for kind in ('ami', 'ari', 'aki')
                          for item_id, os_id in db_api.get_items_ids(
                              self.context, kind, item_ids=self.ids)]

        # NOTE(ft): mapped_ids must be the first to let complete items from
        # next lists to override mappings, which do not have item body data
        images = sum((mapped_ids, local_images, public_images), [])
        if self.ids:
            # NOTE(ft): public images, owned by a current user, appear in both
            # local and public lists of images. Therefore it's not enough to
            # just compare length of requested and retrieved lists to make sure
            # that all requested images are retrieved.
            images_ids = set(i['id'] for i in images)
            if len(images_ids) < len(self.ids):
                missed_ids = self.ids - images_ids
                raise exception.InvalidAMIIDNotFound(id=next(iter(missed_ids)))
        self.pending_images = {
            i['id']: i
            for i in local_images if not i['os_id']
        }
        self.snapshot_ids = dict(
            (s['os_id'], s['id'])
            for s in db_api.get_items(self.context, 'snap'))
        self.local_images_os_ids = set(i['os_id'] for i in local_images)
        self.ids_dict = {}
        return images
Example #7
0
    def get_db_items(self):
        # TODO(ft): we can't get all images from DB per one request due
        # different kinds. It's need to refactor DB API and ec2utils functions
        # to work with kind smarter
        if self.ids:
            local_images = db_api.get_items_by_ids(self.context, self.ids)
        else:
            local_images = sum((db_api.get_items(self.context, kind)
                                for kind in ('ami', 'ari', 'aki')), [])
        public_images = sum((db_api.get_public_items(self.context, kind,
                                                     self.ids)
                             for kind in ('ami', 'ari', 'aki')), [])

        mapped_ids = []
        if self.ids:
            mapped_ids = [{'id': item_id,
                           'os_id': os_id}
                          for kind in ('ami', 'ari', 'aki')
                          for item_id, os_id in db_api.get_items_ids(
                              self.context, kind, item_ids=self.ids)]

        # NOTE(ft): mapped_ids must be the first to let complete items from
        # next lists to override mappings, which do not have item body data
        images = sum((mapped_ids, local_images, public_images), [])
        if self.ids:
            # NOTE(ft): public images, owned by a current user, appear in both
            # local and public lists of images. Therefore it's not enough to
            # just compare length of requested and retrieved lists to make sure
            # that all requested images are retrieved.
            images_ids = set(i['id'] for i in images)
            if len(images_ids) < len(self.ids):
                missed_ids = self.ids - images_ids
                raise exception.InvalidAMIIDNotFound(id=next(iter(missed_ids)))
        self.pending_images = {i['id']: i for i in local_images
                               if not i['os_id']}
        self.snapshot_ids = dict(
            (s['os_id'], s['id'])
            for s in db_api.get_items(self.context, 'snap'))
        self.local_images_os_ids = set(i['os_id'] for i in local_images)
        self.ids_dict = {}
        return images
Example #8
0
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)
    }
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)}