Пример #1
0
 def verify_subnet_exists(self, context, tenant_id, quantum_net_id):
     """Confirms that a subnet exists that is associated with the
        specified Quantum Network UUID.  Raises an exception if no
        such subnet exists.
     """
     admin_context = context.elevated()
     db.network_get_by_uuid(admin_context, quantum_net_id)
Пример #2
0
 def verify_subnet_exists(self, context, tenant_id, quantum_net_id):
     """Confirms that a subnet exists that is associated with the
        specified Quantum Network UUID.  Raises an exception if no
        such subnet exists.
     """
     admin_context = context.elevated()
     db.network_get_by_uuid(admin_context, quantum_net_id)
Пример #3
0
    def test_get_network_not_in_db(self):
        context = self.mox.CreateMockAnything()
        context.elevated().AndReturn('elevated')
        self.mox.StubOutWithMock(db, 'network_get_by_uuid')
        self.net_man.context = context
        db.network_get_by_uuid('elevated', 'quantum_net_id').AndReturn(None)

        self.mox.ReplayAll()

        network = self.net_man.get_network(context,
                                           ('quantum_net_id', 'net_tenant_id'))
        self.assertEquals(network['quantum_net_id'], 'quantum_net_id')
        self.assertEquals(network['uuid'], 'quantum_net_id')
Пример #4
0
    def test_get_network_not_in_db(self):
        context = self.mox.CreateMockAnything()
        context.elevated().AndReturn('elevated')
        self.mox.StubOutWithMock(db, 'network_get_by_uuid')
        self.net_man.context = context
        db.network_get_by_uuid('elevated', 'quantum_net_id').AndReturn(None)

        self.mox.ReplayAll()

        network = self.net_man.get_network(context, ('quantum_net_id',
                                                     'net_tenant_id'))
        self.assertEquals(network['quantum_net_id'], 'quantum_net_id')
        self.assertEquals(network['uuid'], 'quantum_net_id')
Пример #5
0
    def test_get_networks_by_tenant_gets_all_networks(self):
        block_list = self._block_list(network_id='net_1')
        block_list['ip_blocks'] += self._block_list(
            network_id='net_2')['ip_blocks']

        self.m_conn.get_blocks('tenant_id').AndReturn(block_list)

        self.mox.StubOutWithMock(db, 'network_get_by_uuid')
        db.network_get_by_uuid('admin_context', 'net_1').AndReturn('network1')
        db.network_get_by_uuid('admin_context', 'net_2').AndReturn('network2')

        self.mox.ReplayAll()
        values = self.ipam.get_networks_by_tenant('admin_context', 'tenant_id')
        self.assertEquals(values, ['network1', 'network2'])
Пример #6
0
    def test_get_networks_by_tenant_gets_all_networks(self):
        block_list = self._block_list(network_id='net_1')
        block_list['ip_blocks'] += self._block_list(
                                        network_id='net_2')['ip_blocks']

        self.m_conn.get_blocks('tenant_id').AndReturn(block_list)

        self.mox.StubOutWithMock(db, 'network_get_by_uuid')
        db.network_get_by_uuid('admin_context', 'net_1').AndReturn('network1')
        db.network_get_by_uuid('admin_context', 'net_2').AndReturn('network2')

        self.mox.ReplayAll()
        values = self.ipam.get_networks_by_tenant('admin_context', 'tenant_id')
        self.assertEquals(values, ['network1', 'network2'])
Пример #7
0
    def get_project_and_global_net_ids(self, context, project_id):
        """Fetches all networks associated with this project, or
           that are "global" (i.e., have no project set).
           Returns list sorted by 'priority' (lowest integer value
           is highest priority).
        """
        if project_id is None:
            raise Exception(
                _("get_project_and_global_net_ids must be called"
                  " with a non-null project_id"))

        admin_context = context.elevated()

        # Decorate with priority
        priority_nets = []
        for tenant_id in (project_id, FLAGS.quantum_default_tenant_id):
            blocks = self.m_conn.get_blocks(tenant_id)
            for ip_block in blocks['ip_blocks']:
                network_id = ip_block['network_id']
                network = db.network_get_by_uuid(admin_context, network_id)
                if network:
                    priority = network['priority']
                    priority_nets.append((priority, network_id, tenant_id))

        # Sort by priority
        priority_nets.sort()

        # Undecorate
        return [(network_id, tenant_id)
                for priority, network_id, tenant_id in priority_nets]
Пример #8
0
    def get_project_and_global_net_ids(self, context, project_id):
        """Fetches all networks associated with this project, or
           that are "global" (i.e., have no project set).
           Returns list sorted by 'priority' (lowest integer value
           is highest priority).
        """
        if project_id is None:
            raise Exception(_("get_project_and_global_net_ids must be called"
                              " with a non-null project_id"))

        admin_context = context.elevated()

        # Decorate with priority
        priority_nets = []
        for tenant_id in (project_id, FLAGS.quantum_default_tenant_id):
            blocks = self.m_conn.get_blocks(tenant_id)
            for ip_block in blocks['ip_blocks']:
                network_id = ip_block['network_id']
                network = db.network_get_by_uuid(admin_context, network_id)
                if network:
                    priority = network['priority']
                    priority_nets.append((priority, network_id, tenant_id))

        # Sort by priority
        priority_nets.sort()

        # Undecorate
        return [(network_id, tenant_id)
                for priority, network_id, tenant_id in priority_nets]
Пример #9
0
 def get_subnets_by_net_id(self, context, tenant_id, net_id, _vif_id=None):
     """Returns information about the IPv4 and IPv6 subnets
        associated with a Quantum Network UUID.
     """
     n = db.network_get_by_uuid(context.elevated(), net_id)
     subnet_v4 = {
         'network_id': n['uuid'],
         'cidr': n['cidr'],
         'gateway': n['gateway'],
         'broadcast': n['broadcast'],
         'netmask': n['netmask'],
         'version': 4,
         'dns1': n['dns1'],
         'dns2': n['dns2']}
     #TODO(tr3buchet): I'm noticing we've assumed here that all dns is v4.
     #                 this is probably bad as there is no way to add v6
     #                 dns to nova
     subnet_v6 = {
         'network_id': n['uuid'],
         'cidr': n['cidr_v6'],
         'gateway': n['gateway_v6'],
         'broadcast': None,
         'netmask': n['netmask_v6'],
         'version': 6,
         'dns1': None,
         'dns2': None}
     return [subnet_v4, subnet_v6]
Пример #10
0
 def test_create_net_external_uuid_and_host_is_set(self):
     """Make sure network['host'] is set when creating a network via the
        network manager"""
     project_id = "foo_project"
     ctx = context.RequestContext('user1', project_id)
     net_id = self.net_man.q_conn.create_network(project_id, 'net2')
     self.net_man.create_networks(ctx,
                                  label='achtungbaby2',
                                  cidr="9.9.8.0/24",
                                  multi_host=False,
                                  num_networks=1,
                                  network_size=256,
                                  cidr_v6=None,
                                  gateway="9.9.8.1",
                                  gateway_v6=None,
                                  bridge=None,
                                  bridge_interface=None,
                                  dns1="8.8.8.8",
                                  project_id=project_id,
                                  priority=8,
                                  uuid=net_id)
     net = db.network_get_by_uuid(ctx.elevated(), net_id)
     self.assertTrue(net is not None)
     self.assertEquals(net['uuid'], net_id)
     self.assertTrue(net['host'] != None)
Пример #11
0
 def test_create_net_external_uuid(self):
     """Tests use case where network can be created directly via
        Quantum API, then the UUID is passed in via nova-manage"""
     project_id = "foo_project"
     ctx = context.RequestContext('user1', project_id)
     net_id = self.net_man.q_conn.create_network(project_id, 'net1')
     self.net_man.create_networks(
         ctx,
         label='achtungbaby',
         cidr="9.9.9.0/24",
         multi_host=False,
         num_networks=1,
         network_size=256,
         cidr_v6=None,
         gateway="9.9.9.1",
         gateway_v6=None,
         bridge=None,
         bridge_interface=None,
         dns1="8.8.8.8",
         project_id=project_id,
         priority=9,
         uuid=net_id)
     net = db.network_get_by_uuid(ctx.elevated(), net_id)
     self.assertTrue(net is not None)
     self.assertEquals(net['uuid'], net_id)
Пример #12
0
 def get_subnets_by_net_id(self, context, tenant_id, net_id, _vif_id=None):
     """Returns information about the IPv4 and IPv6 subnets
        associated with a Quantum Network UUID.
     """
     n = db.network_get_by_uuid(context.elevated(), net_id)
     subnet_v4 = {
         "network_id": n["uuid"],
         "cidr": n["cidr"],
         "gateway": n["gateway"],
         "broadcast": n["broadcast"],
         "netmask": n["netmask"],
         "version": 4,
         "dns1": n["dns1"],
         "dns2": n["dns2"],
     }
     # TODO(tr3buchet): I'm noticing we've assumed here that all dns is v4.
     #                 this is probably bad as there is no way to add v6
     #                 dns to nova
     subnet_v6 = {
         "network_id": n["uuid"],
         "cidr": n["cidr_v6"],
         "gateway": n["gateway_v6"],
         "broadcast": None,
         "netmask": n["netmask_v6"],
         "version": 6,
         "dns1": None,
         "dns2": None,
     }
     return [subnet_v4, subnet_v6]
Пример #13
0
 def test_create_net_external_uuid(self):
     """Tests use case where network can be created directly via
        Quantum API, then the UUID is passed in via nova-manage"""
     project_id = "foo_project"
     ctx = context.RequestContext('user1', project_id)
     net_id = self.net_man.q_conn.create_network(project_id, 'net1')
     self.net_man.create_networks(
         ctx,
         label='achtungbaby',
         cidr="9.9.9.0/24",
         multi_host=False,
         num_networks=1,
         network_size=256,
         cidr_v6=None,
         gateway="9.9.9.1",
         gateway_v6=None,
         bridge=None,
         bridge_interface=None,
         dns1="8.8.8.8",
         project_id=project_id,
         priority=9,
         uuid=net_id)
     net = db.network_get_by_uuid(ctx.elevated(), net_id)
     self.assertTrue(net is not None)
     self.assertEquals(net['uuid'], net_id)
 def get_subnets_by_net_id(self, context, tenant_id, net_id, _vif_id=None):
     """Returns information about the IPv4 and IPv6 subnets
        associated with a Neutron Network UUID.
     """
     n = db.network_get_by_uuid(context.elevated(), net_id)
     subnet_v4 = {
         'network_id': n['uuid'],
         'cidr': n['cidr'],
         'gateway': n['gateway'],
         'broadcast': n['broadcast'],
         'netmask': n['netmask'],
         'version': 4,
         'dns1': n['dns1'],
         'dns2': n['dns2']}
     #TODO(tr3buchet): I'm noticing we've assumed here that all dns is v4.
     #                 this is probably bad as there is no way to add v6
     #                 dns to nova
     subnet_v6 = {
         'network_id': n['uuid'],
         'cidr': n['cidr_v6'],
         'gateway': n['gateway_v6'],
         'broadcast': None,
         'netmask': n['netmask_v6'],
         'version': 6,
         'dns1': None,
         'dns2': None}
     return [subnet_v4, subnet_v6]
Пример #15
0
 def _update_network_host(self, context, net_uuid):
     """Set the host column in the networks table: note that this won't
        work with multi-host but QuantumManager doesn't support that
        anyways.  The floating IPs mixin required network['host'] to be
        set."""
     entry = db.network_get_by_uuid(context.elevated(), net_uuid)
     entry['host'] = self.host
     db.network_update(context.elevated(), entry['id'], entry)
Пример #16
0
 def get_networks_by_tenant(self, admin_context, tenant_id):
     nets = {}
     blocks = self.m_conn.get_blocks(tenant_id)
     for ip_block in blocks['ip_blocks']:
         network_id = ip_block['network_id']
         network = db.network_get_by_uuid(admin_context, network_id)
         nets[network_id] = network
     return nets.values()
Пример #17
0
 def _update_network_host(self, context, net_uuid):
     """Set the host column in the networks table: note that this won't
        work with multi-host but QuantumManager doesn't support that
        anyways.  The floating IPs mixin required network['host'] to be
        set."""
     entry = db.network_get_by_uuid(context.elevated(), net_uuid)
     entry['host'] = self.host
     db.network_update(context.elevated(), entry['id'], entry)
Пример #18
0
 def get_networks_by_tenant(self, admin_context, tenant_id):
     nets = []
     blocks = self.m_conn.get_blocks(tenant_id)
     for ip_block in blocks['ip_blocks']:
         network_id = ip_block['network_id']
         network = db.network_get_by_uuid(admin_context, network_id)
         nets.append(network)
     return nets
Пример #19
0
 def get_networks_by_tenant(self, admin_context, tenant_id):
     nets = []
     blocks = self.m_conn.get_blocks(tenant_id)
     for ip_block in blocks['ip_blocks']:
         network_id = ip_block['network_id']
         network = db.network_get_by_uuid(admin_context, network_id)
         nets.append(network)
     return nets
Пример #20
0
 def get_networks_by_tenant(self, admin_context, tenant_id):
     nets = {}
     blocks = self.m_conn.get_blocks(tenant_id)
     for ip_block in blocks['ip_blocks']:
         network_id = ip_block['network_id']
         network = db.network_get_by_uuid(admin_context, network_id)
         nets[network_id] = network
     return nets.values()
Пример #21
0
    def test_delete_subnets_by_net_id_deletes_block(self):
        context = self.mox.CreateMockAnything()
        context.elevated().AndReturn('elevated')

        self.m_conn.get_blocks('project_id').AndReturn(
            self._block_list(id='block_id'))
        self.m_conn.delete_block('block_id', 'project_id')

        self.mox.StubOutWithMock(db, 'network_get_by_uuid')
        db.network_get_by_uuid('elevated',
                               'network_id').AndReturn({'id': 'network_id'})

        self.mox.StubOutWithMock(db, 'network_delete_safe')
        db.network_delete_safe(context, 'network_id')

        self.mox.ReplayAll()
        self.ipam.delete_subnets_by_net_id(context, 'network_id', 'project_id')
Пример #22
0
    def test_delete_subnets_by_net_id_deletes_block(self):
        context = self.mox.CreateMockAnything()
        context.elevated().AndReturn('elevated')

        self.m_conn.get_blocks('project_id').AndReturn(
                                        self._block_list(id='block_id'))
        self.m_conn.delete_block('block_id', 'project_id')

        self.mox.StubOutWithMock(db, 'network_get_by_uuid')
        db.network_get_by_uuid('elevated', 'network_id').AndReturn(
                                                         {'id': 'network_id'})

        self.mox.StubOutWithMock(db, 'network_delete_safe')
        db.network_delete_safe(context, 'network_id')

        self.mox.ReplayAll()
        self.ipam.delete_subnets_by_net_id(context, 'network_id', 'project_id')
Пример #23
0
 def get_networks_by_tenant(self, context, tenant_id):
     nets = []
     admin_context = context.get_admin_context()
     blocks = self.m_conn.get_blocks(tenant_id)
     for ip_block in blocks["ip_blocks"]:
         network_id = ip_block["network_id"]
         network = db.network_get_by_uuid(admin_context, network_id)
         nets.append(network)
     return nets
Пример #24
0
 def allocate_fixed_ip(self, context, tenant_id, quantum_net_id, vif_rec):
     """Allocates a single fixed IPv4 address for a virtual interface."""
     admin_context = context.elevated()
     network = db.network_get_by_uuid(admin_context, quantum_net_id)
     if network['cidr']:
         address = db.fixed_ip_associate_pool(admin_context, network['id'],
                                              vif_rec['instance_id'])
         values = {'allocated': True, 'virtual_interface_id': vif_rec['id']}
         db.fixed_ip_update(admin_context, address, values)
Пример #25
0
 def allocate_fixed_ips(self, context, tenant_id, quantum_net_id, network_tenant_id, vif_rec):
     """Allocates a single fixed IPv4 address for a virtual interface."""
     admin_context = context.elevated()
     network = db.network_get_by_uuid(admin_context, quantum_net_id)
     address = None
     if network["cidr"]:
         address = db.fixed_ip_associate_pool(admin_context, network["id"], vif_rec["instance_id"])
         values = {"allocated": True, "virtual_interface_id": vif_rec["id"]}
         db.fixed_ip_update(admin_context, address, values)
     return [address]
Пример #26
0
 def allocate_fixed_ip(self, context, tenant_id, quantum_net_id, vif_rec):
     """Allocates a single fixed IPv4 address for a virtual interface."""
     admin_context = context.elevated()
     network = db.network_get_by_uuid(admin_context, quantum_net_id)
     if network['cidr']:
         address = db.fixed_ip_associate_pool(admin_context,
                                              network['id'],
                                              vif_rec['instance_id'])
         values = {'allocated': True,
                   'virtual_interface_id': vif_rec['id']}
         db.fixed_ip_update(admin_context, address, values)
Пример #27
0
 def get_v6_ips_by_interface(self, context, net_id, vif_id, project_id):
     """Returns a list containing a single IPv6 address strings
        associated with the specified virtual interface.
     """
     admin_context = context.elevated()
     network = db.network_get_by_uuid(admin_context, net_id)
     vif_rec = db.virtual_interface_get_by_uuid(context, vif_id)
     if network["cidr_v6"]:
         ip = ipv6.to_global(network["cidr_v6"], vif_rec["address"], project_id)
         return [ip]
     return []
Пример #28
0
 def delete_subnets_by_net_id(self, context, net_id, project_id):
     """Deletes a network based on Quantum UUID.  Uses FlatManager
        delete_network to avoid duplication.
     """
     admin_context = context.elevated()
     network = db.network_get_by_uuid(admin_context, net_id)
     if not network:
         raise Exception(_("No network with net_id = %s" % net_id))
     manager.FlatManager.delete_network(
         self.net_manager, admin_context, None, network["uuid"], require_disassociated=False
     )
Пример #29
0
    def delete_network(self, context, fixed_range, uuid):
        """Lookup network by uuid, delete both the IPAM
           subnet and the corresponding Quantum network.

           The fixed_range parameter is kept here for interface compatibility
           but is not used.
        """
        net_ref = db.network_get_by_uuid(context.elevated(), uuid)
        project_id = net_ref['project_id']
        q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
        net_uuid = net_ref['uuid']

        # Check for any attached ports on the network and fail the deletion if
        # there is anything but the gateway port attached.  If it is only the
        # gateway port, unattach and delete it.
        ports = self.q_conn.get_attached_ports(q_tenant_id, net_uuid)
        num_ports = len(ports)
        gw_interface_id = self.driver.get_dev(net_ref)
        gw_port_uuid = None
        if gw_interface_id is not None:
            gw_port_uuid = self.q_conn.get_port_by_attachment(
                q_tenant_id, net_uuid, gw_interface_id)

        if gw_port_uuid:
            num_ports -= 1

        if num_ports > 0:
            raise exception.NetworkBusy(network=net_uuid)

        # only delete gw ports if we are going to finish deleting network
        if gw_port_uuid:
            self.q_conn.detach_and_delete_port(q_tenant_id, net_uuid,
                                               gw_port_uuid)
            self.l3driver.remove_gateway(net_ref)

        # Now we can delete the network
        self.q_conn.delete_network(q_tenant_id, net_uuid)
        LOG.debug("Deleting network %s for tenant: %s" % \
                                    (net_uuid, q_tenant_id))
        self.ipam.delete_subnets_by_net_id(context, net_uuid, project_id)
        # Get rid of dnsmasq
        if FLAGS.quantum_use_dhcp:
            if net_ref['host'] == self.host:
                self.kill_dhcp(net_ref)
            else:
                topic = self.db.queue_get_for(context, FLAGS.network_topic,
                                              net_ref['host'])

                rpc.call(context, topic, {
                    'method': 'kill_dhcp',
                    'args': {
                        'net_ref': net_ref
                    }
                })
Пример #30
0
 def get_v6_ips_by_interface(self, context, net_id, vif_id, project_id):
     """Returns a list containing a single IPv6 address strings
        associated with the specified virtual interface.
     """
     admin_context = context.elevated()
     network = db.network_get_by_uuid(admin_context, net_id)
     vif_rec = db.virtual_interface_get_by_uuid(context, vif_id)
     if network['cidr_v6']:
         ip = ipv6.to_global(network['cidr_v6'], vif_rec['address'],
                             project_id)
         return [ip]
     return []
Пример #31
0
 def delete_subnets_by_net_id(self, context, net_id, project_id):
     """Deletes a network based on Quantum UUID.  Uses FlatManager
        delete_network to avoid duplication.
     """
     admin_context = context.elevated()
     network = db.network_get_by_uuid(admin_context, net_id)
     if not network:
         raise Exception(_("No network with net_id = %s") % net_id)
     manager.FlatManager.delete_network(self.net_manager,
                                        admin_context, None,
                                        network['uuid'],
                                        require_disassociated=False)
Пример #32
0
    def delete_network(self, context, fixed_range, uuid):
        """Lookup network by uuid, delete both the IPAM
           subnet and the corresponding Quantum network.

           The fixed_range parameter is kept here for interface compatibility
           but is not used.
        """
        net_ref = db.network_get_by_uuid(context.elevated(), uuid)
        project_id = net_ref['project_id']
        q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
        net_uuid = net_ref['uuid']

        # Check for any attached ports on the network and fail the deletion if
        # there is anything but the gateway port attached.  If it is only the
        # gateway port, unattach and delete it.
        ports = self.q_conn.get_attached_ports(q_tenant_id, net_uuid)
        num_ports = len(ports)
        gw_interface_id = self.driver.get_dev(net_ref)
        gw_port_uuid = None
        if gw_interface_id is not None:
            gw_port_uuid = self.q_conn.get_port_by_attachment(q_tenant_id,
                                        net_uuid, gw_interface_id)

        if gw_port_uuid:
            num_ports -= 1

        if num_ports > 0:
            raise exception.NetworkBusy(network=net_uuid)

        # only delete gw ports if we are going to finish deleting network
        if gw_port_uuid:
            self.q_conn.detach_and_delete_port(q_tenant_id,
                                                   net_uuid,
                                                   gw_port_uuid)
            self.l3driver.remove_gateway(net_ref)

        # Now we can delete the network
        self.q_conn.delete_network(q_tenant_id, net_uuid)
        LOG.debug("Deleting network %s for tenant: %s" %
                  (net_uuid, q_tenant_id))
        self.ipam.delete_subnets_by_net_id(context, net_uuid, project_id)
        # Get rid of dnsmasq
        if FLAGS.quantum_use_dhcp:
            if net_ref['host'] == self.host:
                self.kill_dhcp(net_ref)
            else:
                topic = rpc.queue_get_for(context,
                        FLAGS.network_topic,
                        net_ref['host'])

                rpc.call(context, topic, {'method': 'kill_dhcp',
                        'args': {'net_ref': net_ref}})
Пример #33
0
    def delete_subnets_by_net_id(self, context, net_id, project_id):
        """Find Melange block associated with the Quantum UUID,
           then tell Melange to delete that block.
        """
        admin_context = context.elevated()
        tenant_id = project_id or FLAGS.quantum_default_tenant_id
        all_blocks = self.m_conn.get_blocks(tenant_id)
        for b in all_blocks['ip_blocks']:
            if b['network_id'] == net_id:
                self.m_conn.delete_block(b['id'], tenant_id)

        network = db.network_get_by_uuid(admin_context, net_id)
        db.network_delete_safe(context, network['id'])
Пример #34
0
 def get_allocated_ips(self, context, subnet_id, project_id):
     """Returns a list of (ip, vif_id) pairs"""
     admin_context = context.elevated()
     ips = db.fixed_ip_get_all(admin_context)
     allocated_ips = []
     # Get all allocated IPs that are part of this subnet
     network = db.network_get_by_uuid(admin_context, subnet_id)
     for ip in ips:
         # Skip unallocated IPs
         if not ip["allocated"] == 1:
             continue
         if ip["network_id"] == network["id"]:
             vif = db.virtual_interface_get(admin_context, ip["virtual_interface_id"])
             allocated_ips.append((ip["address"], vif["uuid"]))
     return allocated_ips
Пример #35
0
 def test_create_net_external_uuid_and_host_is_set(self):
     """Make sure network['host'] is set when creating a network via the
        network manager"""
     project_id = "foo_project"
     ctx = context.RequestContext('user1', project_id)
     net_id = self.net_man.q_conn.create_network(project_id, 'net2')
     self.net_man.create_networks(
         ctx, label='achtungbaby2', cidr="9.9.8.0/24", multi_host=False,
         num_networks=1, network_size=256, cidr_v6=None,
         gateway="9.9.8.1", gateway_v6=None, bridge=None,
         bridge_interface=None, dns1="8.8.8.8", project_id=project_id,
         priority=8, uuid=net_id)
     net = db.network_get_by_uuid(ctx.elevated(), net_id)
     self.assertTrue(net is not None)
     self.assertEquals(net['uuid'], net_id)
     self.assertTrue(net['host'] is not None)
Пример #36
0
 def get_allocated_ips(self, context, subnet_id, project_id):
     """Returns a list of (ip, vif_id) pairs"""
     admin_context = context.elevated()
     ips = db.fixed_ip_get_all(admin_context)
     allocated_ips = []
     # Get all allocated IPs that are part of this subnet
     network = db.network_get_by_uuid(admin_context, subnet_id)
     for ip in ips:
         # Skip unallocated IPs
         if not ip['allocated'] == 1:
             continue
         if ip['network_id'] == network['id']:
             vif = db.virtual_interface_get(admin_context,
                                            ip['virtual_interface_id'])
             allocated_ips.append((ip['address'], vif['uuid']))
     return allocated_ips
Пример #37
0
    def delete_network(self, context, fixed_range, uuid):
        """Lookup network by uuid, delete both the IPAM
           subnet and the corresponding Quantum network.

           The fixed_range parameter is kept here for interface compatibility
           but is not used.
        """
        net_ref = db.network_get_by_uuid(context.elevated(), uuid)
        project_id = net_ref['project_id']
        q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
        net_uuid = net_ref['uuid']

        # Check for any attached ports on the network and fail the deletion if
        # there is anything but the gateway port attached.  If it is only the
        # gateway port, unattach and delete it.
        ports = self.q_conn.get_attached_ports(q_tenant_id, net_uuid)
        num_ports = len(ports)
        gw_interface_id = self.driver.get_dev(net_ref)
        gw_port_uuid = None
        if gw_interface_id is not None:
            gw_port_uuid = self.q_conn.get_port_by_attachment(q_tenant_id,
                                        net_uuid, gw_interface_id)

        if gw_port_uuid:
            num_ports -= 1

        if num_ports > 0:
            raise Exception(_("Network %s has active ports, cannot delete"
                                                            % (net_uuid)))

        # only delete gw ports if we are going to finish deleting network
        if gw_port_uuid:
            self.q_conn.detach_and_delete_port(q_tenant_id,
                                                   net_uuid,
                                                   gw_port_uuid)

        # Now we can delete the network
        self.q_conn.delete_network(q_tenant_id, net_uuid)
        LOG.debug("Deleting network %s for tenant: %s" % \
                                    (net_uuid, q_tenant_id))
        self.ipam.delete_subnets_by_net_id(context, net_uuid, project_id)
        # Get rid of dnsmasq
        if FLAGS.quantum_use_dhcp:
            dev = self.driver.get_dev(net_ref)
            if self.driver._device_exists(dev):
                self.driver.kill_dhcp(dev)
Пример #38
0
    def delete_network(self, context, fixed_range, uuid):
        """Lookup network by uuid, delete both the IPAM
           subnet and the corresponding Quantum network.

           The fixed_range parameter is kept here for interface compatibility
           but is not used.
        """
        net_ref = db.network_get_by_uuid(context.elevated(), uuid)
        project_id = net_ref['project_id']
        q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
        net_uuid = net_ref['uuid']

        # Check for any attached ports on the network and fail the deletion if
        # there is anything but the gateway port attached.  If it is only the
        # gateway port, unattach and delete it.
        ports = self.q_conn.get_attached_ports(q_tenant_id, net_uuid)
        num_ports = len(ports)
        gw_interface_id = self.driver.get_dev(net_ref)
        gw_port_uuid = None
        if gw_interface_id is not None:
            gw_port_uuid = self.q_conn.get_port_by_attachment(q_tenant_id,
                                        net_uuid, gw_interface_id)

        if gw_port_uuid:
            num_ports -= 1

        if num_ports > 0:
            raise Exception(_("Network %s has active ports, cannot delete"
                                                            % (net_uuid)))

        # only delete gw ports if we are going to finish deleting network
        if gw_port_uuid:
            self.q_conn.detach_and_delete_port(q_tenant_id,
                                                   net_uuid,
                                                   gw_port_uuid)

        # Now we can delete the network
        self.q_conn.delete_network(q_tenant_id, net_uuid)
        LOG.debug("Deleting network %s for tenant: %s" % \
                                    (net_uuid, q_tenant_id))
        self.ipam.delete_subnets_by_net_id(context, net_uuid, project_id)
        # Get rid of dnsmasq
        if FLAGS.quantum_use_dhcp:
            dev = self.driver.get_dev(net_ref)
            if self.driver._device_exists(dev):
                self.driver.kill_dhcp(dev)
Пример #39
0
    def get_network(self, context, proj_pair):
        (quantum_net_id, net_tenant_id) = proj_pair

        net_tenant_id = net_tenant_id or FLAGS.quantum_default_tenant_id
        # FIXME(danwent): We'd like to have the manager be
        # completely decoupled from the nova networks table.
        # However, other parts of nova sometimes go behind our
        # back and access network data directly from the DB.  So
        # for now, the quantum manager knows that there is a nova
        # networks DB table and accesses it here.  updating the
        # virtual_interfaces table to use UUIDs would be one
        # solution, but this would require significant work
        # elsewhere.
        admin_context = context.elevated()

        # We may not be able to get a network_ref here if this network
        # isn't in the database (i.e. it came from Quantum).
        network_ref = db.network_get_by_uuid(admin_context, quantum_net_id)

        if network_ref is None:
            network_ref = {}
            network_ref = {
                "uuid": quantum_net_id,
                "project_id": net_tenant_id,
                # NOTE(bgh): We need to document this somewhere but since
                # we don't know the priority of any networks we get from
                # quantum we just give them a priority of 0.  If its
                # necessary to specify the order of the vifs and what
                # network they map to then the user will have to use the
                # OSCreateServer extension and specify them explicitly.
                #
                # In the future users will be able to tag quantum networks
                # with a priority .. and at that point we can update the
                # code here to reflect that.
                "priority": 0,
                "id": 'NULL',
                "label": "quantum-net-%s" % quantum_net_id
            }
        network_ref['net_tenant_id'] = net_tenant_id
        network_ref['quantum_net_id'] = quantum_net_id
        return network_ref
Пример #40
0
    def get_network(self, context, proj_pair):
        (quantum_net_id, net_tenant_id) = proj_pair

        net_tenant_id = net_tenant_id or FLAGS.quantum_default_tenant_id
        # FIXME(danwent): We'd like to have the manager be
        # completely decoupled from the nova networks table.
        # However, other parts of nova sometimes go behind our
        # back and access network data directly from the DB.  So
        # for now, the quantum manager knows that there is a nova
        # networks DB table and accesses it here.  updating the
        # virtual_interfaces table to use UUIDs would be one
        # solution, but this would require significant work
        # elsewhere.
        admin_context = context.elevated()

        # We may not be able to get a network_ref here if this network
        # isn't in the database (i.e. it came from Quantum).
        network_ref = db.network_get_by_uuid(admin_context, quantum_net_id)

        if network_ref is None:
            network_ref = {}
            network_ref = {
                "uuid": quantum_net_id,
                "project_id": net_tenant_id,
                # NOTE(bgh): We need to document this somewhere but since
                # we don't know the priority of any networks we get from
                # quantum we just give them a priority of 0.  If its
                # necessary to specify the order of the vifs and what
                # network they map to then the user will have to use the
                # OSCreateServer extension and specify them explicitly.
                #
                # In the future users will be able to tag quantum networks
                # with a priority .. and at that point we can update the
                # code here to reflect that.
                "priority": 0,
                "id": "NULL",
                "label": "quantum-net-%s" % quantum_net_id,
            }
        network_ref["net_tenant_id"] = net_tenant_id
        network_ref["quantum_net_id"] = quantum_net_id
        return network_ref
Пример #41
0
 def get_subnets_by_net_id(self, context, tenant_id, net_id, _vif_id=None):
     """Returns information about the IPv4 and IPv6 subnets
        associated with a Quantum Network UUID.
     """
     n = db.network_get_by_uuid(context.elevated(), net_id)
     subnet_data_v4 = {
         'network_id': n['uuid'],
         'cidr': n['cidr'],
         'gateway': n['gateway'],
         'broadcast': n['broadcast'],
         'netmask': n['netmask'],
         'dns1': n['dns1'],
         'dns2': n['dns2']}
     subnet_data_v6 = {
         'network_id': n['uuid'],
         'cidr': n['cidr_v6'],
         'gateway': n['gateway_v6'],
         'broadcast': None,
         'netmask': None,
         'dns1': None,
         'dns2': None}
     return (subnet_data_v4, subnet_data_v6)
Пример #42
0
 def get_subnets_by_net_id(self, context, tenant_id, net_id, _vif_id=None):
     """Returns information about the IPv4 and IPv6 subnets
        associated with a Quantum Network UUID.
     """
     n = db.network_get_by_uuid(context.elevated(), net_id)
     subnet_data_v4 = {
         'network_id': n['uuid'],
         'cidr': n['cidr'],
         'gateway': n['gateway'],
         'broadcast': n['broadcast'],
         'netmask': n['netmask'],
         'dns1': n['dns1'],
         'dns2': n['dns2']
     }
     subnet_data_v6 = {
         'network_id': n['uuid'],
         'cidr': n['cidr_v6'],
         'gateway': n['gateway_v6'],
         'broadcast': None,
         'netmask': None,
         'dns1': None,
         'dns2': None
     }
     return ([subnet_data_v4], [subnet_data_v6])
Пример #43
0
 def get_subnets_by_net_id(self, context, tenant_id, net_id, _vif_id=None):
     """Returns information about the IPv4 and IPv6 subnets
        associated with a Quantum Network UUID.
     """
     n = db.network_get_by_uuid(context.elevated(), net_id)
     subnet_data_v4 = {
         "network_id": n["uuid"],
         "cidr": n["cidr"],
         "gateway": n["gateway"],
         "broadcast": n["broadcast"],
         "netmask": n["netmask"],
         "dns1": n["dns1"],
         "dns2": n["dns2"],
     }
     subnet_data_v6 = {
         "network_id": n["uuid"],
         "cidr": n["cidr_v6"],
         "gateway": n["gateway_v6"],
         "broadcast": None,
         "netmask": None,
         "dns1": None,
         "dns2": None,
     }
     return ([subnet_data_v4], [subnet_data_v6])
Пример #44
0
    def allocate_for_instance(self, context, **kwargs):
        """Called by compute when it is creating a new VM.

           There are three key tasks:
                - Determine the number and order of vNICs to create
                - Allocate IP addresses
                - Create ports on a Quantum network and attach vNICs.

           We support two approaches to determining vNICs:
                - By default, a VM gets a vNIC for any network belonging
                  to the VM's project, and a vNIC for any "global" network
                  that has a NULL project_id.  vNIC order is determined
                  by the network's 'priority' field.
                - If the 'os-create-server-ext' was used to create the VM,
                  only the networks in 'requested_networks' are used to
                  create vNICs, and the vNIC order is determiend by the
                  order in the requested_networks array.

           For each vNIC, use the FlatManager to create the entries
           in the virtual_interfaces table, contact Quantum to
           create a port and attachment the vNIC, and use the IPAM
           lib to allocate IP addresses.
        """
        instance_id = kwargs['instance_id']
        rxtx_factor = kwargs['rxtx_factor']
        host = kwargs['host']
        project_id = kwargs['project_id']
        LOG.debug(_("network allocations for instance %s"), project_id)
        requested_networks = kwargs.get('requested_networks')

        if requested_networks:
            net_proj_pairs = [(net_id, project_id)
                              for (net_id, _i) in requested_networks]
        else:
            net_proj_pairs = self.ipam.get_project_and_global_net_ids(context,
                                                                project_id)

        # Create a port via quantum and attach the vif
        for (quantum_net_id, net_tenant_id) in net_proj_pairs:
            net_tenant_id = net_tenant_id or FLAGS.quantum_default_tenant_id
            # FIXME(danwent): We'd like to have the manager be
            # completely decoupled from the nova networks table.
            # However, other parts of nova sometimes go behind our
            # back and access network data directly from the DB.  So
            # for now, the quantum manager knows that there is a nova
            # networks DB table and accesses it here.  updating the
            # virtual_interfaces table to use UUIDs would be one
            # solution, but this would require significant work
            # elsewhere.
            admin_context = context.elevated()

            # We may not be able to get a network_ref here if this network
            # isn't in the database (i.e. it came from Quantum).
            network_ref = db.network_get_by_uuid(admin_context,
                                                 quantum_net_id)
            if network_ref is None:
                network_ref = {}
                network_ref = {"uuid": quantum_net_id,
                    "project_id": net_tenant_id,
                    # NOTE(bgh): We need to document this somewhere but since
                    # we don't know the priority of any networks we get from
                    # quantum we just give them a priority of 0.  If its
                    # necessary to specify the order of the vifs and what
                    # network they map to then the user will have to use the
                    # OSCreateServer extension and specify them explicitly.
                    #
                    # In the future users will be able to tag quantum networks
                    # with a priority .. and at that point we can update the
                    # code here to reflect that.
                    "priority": 0,
                    "id": 'NULL',
                    "label": "quantum-net-%s" % quantum_net_id}

            # TODO(tr3buchet): broken. Virtual interfaces require an integer
            #                  network ID and it is not nullable
            vif_rec = self.add_virtual_interface(context,
                                                 instance_id,
                                                 network_ref['id'])

            # talk to Quantum API to create and attach port.
            instance = db.instance_get(context, instance_id)
            nova_id = self._get_nova_id(instance)
            # Tell the ipam library to allocate an IP
            ips = self.ipam.allocate_fixed_ips(context, project_id,
                    quantum_net_id, net_tenant_id, vif_rec)
            pairs = []
            # Set up port security if enabled
            if FLAGS.quantum_use_port_security:
                if FLAGS.quantum_port_security_include_link_local:
                    mac = netaddr.EUI(vif_rec['address'])
                    ips.append(str(mac.ipv6_link_local()))

                pairs = [{'mac_address': vif_rec['address'],
                          'ip_address': ip} for ip in ips]

            self.q_conn.create_and_attach_port(net_tenant_id, quantum_net_id,
                                               vif_rec['uuid'],
                                               vm_id=instance['uuid'],
                                               rxtx_factor=rxtx_factor,
                                               nova_id=nova_id,
                                               allowed_address_pairs=pairs)
            # Set up/start the dhcp server for this network if necessary
            if FLAGS.quantum_use_dhcp:
                self.enable_dhcp(context, quantum_net_id, network_ref,
                    vif_rec, net_tenant_id)
        return self.get_instance_nw_info(context, instance_id,
                                         instance['uuid'],
                                         rxtx_factor, host)
Пример #45
0
 def delete_subnets_by_net_id(self, context, net_id, project_id):
     admin_context = context.elevated()
     tenant_id = project_id or FLAGS.quantum_default_tenant_id
     network = db.network_get_by_uuid(admin_context, net_id)
     db.network_delete_safe(context, network['id'])
Пример #46
0
 def delete_subnets_by_net_id(self, context, net_id, project_id):
     admin_context = context.elevated()
     tenant_id = project_id or FLAGS.quantum_default_tenant_id
     network = db.network_get_by_uuid(admin_context, net_id)
     db.network_delete_safe(context, network["id"])
Пример #47
0
    def allocate_for_instance(self, context, **kwargs):
        """Called by compute when it is creating a new VM.

           There are three key tasks:
                - Determine the number and order of vNICs to create
                - Allocate IP addresses
                - Create ports on a Quantum network and attach vNICs.

           We support two approaches to determining vNICs:
                - By default, a VM gets a vNIC for any network belonging
                  to the VM's project, and a vNIC for any "global" network
                  that has a NULL project_id.  vNIC order is determined
                  by the network's 'priority' field.
                - If the 'os-create-server-ext' was used to create the VM,
                  only the networks in 'requested_networks' are used to
                  create vNICs, and the vNIC order is determiend by the
                  order in the requested_networks array.

           For each vNIC, use the FlatManager to create the entries
           in the virtual_interfaces table, contact Quantum to
           create a port and attachment the vNIC, and use the IPAM
           lib to allocate IP addresses.
        """
        instance_id = kwargs.pop('instance_id')
        instance_type_id = kwargs['instance_type_id']
        host = kwargs.pop('host')
        project_id = kwargs.pop('project_id')
        LOG.debug(_("network allocations for instance %s"), instance_id)

        requested_networks = kwargs.get('requested_networks')

        if requested_networks:
            net_proj_pairs = [(net_id, project_id) \
                for (net_id, _i) in requested_networks]
        else:
            net_proj_pairs = self.ipam.get_project_and_global_net_ids(context,
                                                                project_id)

        # Create a port via quantum and attach the vif
        for (quantum_net_id, project_id) in net_proj_pairs:

            # FIXME(danwent): We'd like to have the manager be
            # completely decoupled from the nova networks table.
            # However, other parts of nova sometimes go behind our
            # back and access network data directly from the DB.  So
            # for now, the quantum manager knows that there is a nova
            # networks DB table and accesses it here.  updating the
            # virtual_interfaces table to use UUIDs would be one
            # solution, but this would require significant work
            # elsewhere.
            admin_context = context.elevated()
            network_ref = db.network_get_by_uuid(admin_context,
                                                 quantum_net_id)

            vif_rec = manager.FlatManager.add_virtual_interface(self,
                                  context, instance_id, network_ref['id'])

            # talk to Quantum API to create and attach port.
            q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
            self.q_conn.create_and_attach_port(q_tenant_id, quantum_net_id,
                                               vif_rec['uuid'])
            self.ipam.allocate_fixed_ip(context, project_id, quantum_net_id,
                                        vif_rec)

        return self.get_instance_nw_info(context, instance_id,
                                         instance_type_id, host)
Пример #48
0
 def get_by_uuid(cls, context, network_uuid):
     db_network = db.network_get_by_uuid(context, network_uuid)
     return cls._from_db_object(context, cls(), db_network)
Пример #49
0
 def get_by_uuid(cls, context, network_uuid):
     db_network = db.network_get_by_uuid(context, network_uuid)
     return cls._from_db_object(context, cls(), db_network)
Пример #50
0
    def allocate_for_instance(self, context, **kwargs):
        """Called by compute when it is creating a new VM.

           There are three key tasks:
                - Determine the number and order of vNICs to create
                - Allocate IP addresses
                - Create ports on a Quantum network and attach vNICs.

           We support two approaches to determining vNICs:
                - By default, a VM gets a vNIC for any network belonging
                  to the VM's project, and a vNIC for any "global" network
                  that has a NULL project_id.  vNIC order is determined
                  by the network's 'priority' field.
                - If the 'os-create-server-ext' was used to create the VM,
                  only the networks in 'requested_networks' are used to
                  create vNICs, and the vNIC order is determiend by the
                  order in the requested_networks array.

           For each vNIC, use the FlatManager to create the entries
           in the virtual_interfaces table, contact Quantum to
           create a port and attachment the vNIC, and use the IPAM
           lib to allocate IP addresses.
        """
        instance_id = kwargs.pop('instance_id')
        instance_type_id = kwargs['instance_type_id']
        host = kwargs.pop('host')
        project_id = kwargs.pop('project_id')
        LOG.debug(_("network allocations for instance %s"), project_id)

        requested_networks = kwargs.get('requested_networks')

        if requested_networks:
            net_proj_pairs = [(net_id, project_id) \
                for (net_id, _i) in requested_networks]
        else:
            net_proj_pairs = self.ipam.get_project_and_global_net_ids(
                context, project_id)

        # Quantum may also know about networks that aren't in the networks
        # table so we need to query Quanutm for any tenant networks and add
        # them to net_proj_pairs.
        qnets = self.q_conn.get_networks(project_id)
        for qn in qnets['networks']:
            pair = (qn['id'], project_id)
            if pair not in net_proj_pairs:
                net_proj_pairs.append(pair)

        # Create a port via quantum and attach the vif
        for (quantum_net_id, project_id) in net_proj_pairs:
            # FIXME(danwent): We'd like to have the manager be
            # completely decoupled from the nova networks table.
            # However, other parts of nova sometimes go behind our
            # back and access network data directly from the DB.  So
            # for now, the quantum manager knows that there is a nova
            # networks DB table and accesses it here.  updating the
            # virtual_interfaces table to use UUIDs would be one
            # solution, but this would require significant work
            # elsewhere.
            admin_context = context.elevated()

            # We may not be able to get a network_ref here if this network
            # isn't in the database (i.e. it came from Quantum).
            network_ref = db.network_get_by_uuid(admin_context, quantum_net_id)
            if network_ref is None:
                network_ref = {}
                network_ref = {
                    "uuid": quantum_net_id,
                    "project_id": project_id,
                    # NOTE(bgh): We need to document this somewhere but since
                    # we don't know the priority of any networks we get from
                    # quantum we just give them a priority of 0.  If its
                    # necessary to specify the order of the vifs and what
                    # network they map to then the user will have to use the
                    # OSCreateServer extension and specify them explicitly.
                    #
                    # In the future users will be able to tag quantum networks
                    # with a priority .. and at that point we can update the
                    # code here to reflect that.
                    "priority": 0,
                    "id": 'NULL',
                    "label": "quantum-net-%s" % quantum_net_id
                }

            vif_rec = self.add_virtual_interface(context, instance_id,
                                                 network_ref['id'])

            # talk to Quantum API to create and attach port.
            instance = db.instance_get(context, instance_id)
            instance_type = instance_types.get_instance_type(instance_type_id)
            rxtx_factor = instance_type['rxtx_factor']
            nova_id = self._get_nova_id(instance)
            q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
            # Tell the ipam library to allocate an IP
            ip = self.ipam.allocate_fixed_ip(context, project_id,
                                             quantum_net_id, vif_rec)
            pairs = []
            # Set up port security if enabled
            if FLAGS.quantum_use_port_security:
                pairs = [{'mac_address': vif_rec['address'], 'ip_address': ip}]
            self.q_conn.create_and_attach_port(q_tenant_id,
                                               quantum_net_id,
                                               vif_rec['uuid'],
                                               vm_id=instance['uuid'],
                                               rxtx_factor=rxtx_factor,
                                               nova_id=nova_id,
                                               allowed_address_pairs=pairs)
            # Set up/start the dhcp server for this network if necessary
            if FLAGS.quantum_use_dhcp:
                self.enable_dhcp(context, quantum_net_id, network_ref, vif_rec,
                                 project_id)
        return self.get_instance_nw_info(context, instance_id,
                                         instance_type_id, host)
Пример #51
0
    def allocate_for_instance(self, context, **kwargs):
        """Called by compute when it is creating a new VM.

           There are three key tasks:
                - Determine the number and order of vNICs to create
                - Allocate IP addresses
                - Create ports on a Quantum network and attach vNICs.

           We support two approaches to determining vNICs:
                - By default, a VM gets a vNIC for any network belonging
                  to the VM's project, and a vNIC for any "global" network
                  that has a NULL project_id.  vNIC order is determined
                  by the network's 'priority' field.
                - If the 'os-create-server-ext' was used to create the VM,
                  only the networks in 'requested_networks' are used to
                  create vNICs, and the vNIC order is determiend by the
                  order in the requested_networks array.

           For each vNIC, use the FlatManager to create the entries
           in the virtual_interfaces table, contact Quantum to
           create a port and attachment the vNIC, and use the IPAM
           lib to allocate IP addresses.
        """
        instance_id = kwargs.pop('instance_id')
        instance_type_id = kwargs['instance_type_id']
        host = kwargs.pop('host')
        project_id = kwargs.pop('project_id')
        LOG.debug(_("network allocations for instance %s"), instance_id)

        requested_networks = kwargs.get('requested_networks')

        if requested_networks:
            net_proj_pairs = [(net_id, project_id) \
                for (net_id, _i) in requested_networks]
        else:
            net_proj_pairs = self.ipam.get_project_and_global_net_ids(
                context, project_id)

        # Create a port via quantum and attach the vif
        for (quantum_net_id, project_id) in net_proj_pairs:

            # FIXME(danwent): We'd like to have the manager be
            # completely decoupled from the nova networks table.
            # However, other parts of nova sometimes go behind our
            # back and access network data directly from the DB.  So
            # for now, the quantum manager knows that there is a nova
            # networks DB table and accesses it here.  updating the
            # virtual_interfaces table to use UUIDs would be one
            # solution, but this would require significant work
            # elsewhere.
            admin_context = context.elevated()
            network_ref = db.network_get_by_uuid(admin_context, quantum_net_id)

            vif_rec = manager.FlatManager.add_virtual_interface(
                self, context, instance_id, network_ref['id'])

            # talk to Quantum API to create and attach port.
            q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
            self.q_conn.create_and_attach_port(q_tenant_id, quantum_net_id,
                                               vif_rec['uuid'])
            self.ipam.allocate_fixed_ip(context, project_id, quantum_net_id,
                                        vif_rec)

        return self.get_instance_nw_info(context, instance_id,
                                         instance_type_id, host)
Пример #52
0
    def allocate_for_instance(self, context, **kwargs):
        """Called by compute when it is creating a new VM.

           There are three key tasks:
                - Determine the number and order of vNICs to create
                - Allocate IP addresses
                - Create ports on a Quantum network and attach vNICs.

           We support two approaches to determining vNICs:
                - By default, a VM gets a vNIC for any network belonging
                  to the VM's project, and a vNIC for any "global" network
                  that has a NULL project_id.  vNIC order is determined
                  by the network's 'priority' field.
                - If the 'os-create-server-ext' was used to create the VM,
                  only the networks in 'requested_networks' are used to
                  create vNICs, and the vNIC order is determiend by the
                  order in the requested_networks array.

           For each vNIC, use the FlatManager to create the entries
           in the virtual_interfaces table, contact Quantum to
           create a port and attachment the vNIC, and use the IPAM
           lib to allocate IP addresses.
        """
        instance_id = kwargs.pop("instance_id")
        instance_type_id = kwargs["instance_type_id"]
        host = kwargs.pop("host")
        project_id = kwargs.pop("project_id")
        LOG.debug(_("network allocations for instance %s"), project_id)

        requested_networks = kwargs.get("requested_networks")

        if requested_networks:
            net_proj_pairs = [(net_id, project_id) for (net_id, _i) in requested_networks]
        else:
            net_proj_pairs = self.ipam.get_project_and_global_net_ids(context, project_id)

        # Quantum may also know about networks that aren't in the networks
        # table so we need to query Quanutm for any tenant networks and add
        # them to net_proj_pairs.
        qnets = self.q_conn.get_networks(project_id)
        for qn in qnets["networks"]:
            pair = (qn["id"], project_id)
            if pair not in net_proj_pairs:
                net_proj_pairs.append(pair)

        # Create a port via quantum and attach the vif
        for (quantum_net_id, project_id) in net_proj_pairs:
            # FIXME(danwent): We'd like to have the manager be
            # completely decoupled from the nova networks table.
            # However, other parts of nova sometimes go behind our
            # back and access network data directly from the DB.  So
            # for now, the quantum manager knows that there is a nova
            # networks DB table and accesses it here.  updating the
            # virtual_interfaces table to use UUIDs would be one
            # solution, but this would require significant work
            # elsewhere.
            admin_context = context.elevated()

            # We may not be able to get a network_ref here if this network
            # isn't in the database (i.e. it came from Quantum).
            network_ref = db.network_get_by_uuid(admin_context, quantum_net_id)
            if network_ref is None:
                network_ref = {}
                network_ref = {
                    "uuid": quantum_net_id,
                    "project_id": project_id,
                    # NOTE(bgh): We need to document this somewhere but since
                    # we don't know the priority of any networks we get from
                    # quantum we just give them a priority of 0.  If its
                    # necessary to specify the order of the vifs and what
                    # network they map to then the user will have to use the
                    # OSCreateServer extension and specify them explicitly.
                    #
                    # In the future users will be able to tag quantum networks
                    # with a priority .. and at that point we can update the
                    # code here to reflect that.
                    "priority": 0,
                    "id": "NULL",
                    "label": "quantum-net-%s" % quantum_net_id,
                }

            vif_rec = self.add_virtual_interface(context, instance_id, network_ref["id"])

            # talk to Quantum API to create and attach port.
            instance = db.instance_get(context, instance_id)
            instance_type = instance_types.get_instance_type(instance_type_id)
            rxtx_factor = instance_type["rxtx_factor"]
            nova_id = self._get_nova_id(context)
            q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
            self.q_conn.create_and_attach_port(
                q_tenant_id,
                quantum_net_id,
                vif_rec["uuid"],
                vm_id=instance["uuid"],
                rxtx_factor=rxtx_factor,
                nova_id=nova_id,
            )
            # Tell melange to allocate an IP
            ip = self.ipam.allocate_fixed_ip(context, project_id, quantum_net_id, vif_rec)
            # Set up/start the dhcp server for this network if necessary
            if FLAGS.quantum_use_dhcp:
                self.enable_dhcp(context, quantum_net_id, network_ref, vif_rec, project_id)
        return self.get_instance_nw_info(context, instance_id, instance_type_id, host)