add doc-strings for all major modules
This commit is contained in:
@@ -35,8 +35,27 @@ flags.DEFINE_string('quantum_ipam_lib',
|
||||
|
||||
|
||||
class QuantumManager(manager.FlatManager):
|
||||
""" NetworkManager class that communicates with a Quantum service
|
||||
via a web services API to provision VM network connectivity.
|
||||
|
||||
For IP Address management, QuantumManager can be configured to
|
||||
use either Nova's local DB or the Melange IPAM service.
|
||||
|
||||
Currently, the QuantumManager does NOT support any of the 'gateway'
|
||||
functionality implemented by the Nova VlanManager, including:
|
||||
* floating IPs
|
||||
* DHCP
|
||||
* NAT gateway
|
||||
|
||||
Support for these capabilities are targted for future releases.
|
||||
"""
|
||||
|
||||
def __init__(self, ipam_lib=None, *args, **kwargs):
|
||||
""" Initialize two key libraries, the connection to a
|
||||
Quantum service, and the library for implementing IPAM.
|
||||
|
||||
Calls inherited FlatManager constructor.
|
||||
"""
|
||||
|
||||
if FLAGS.fake_network:
|
||||
self.q_conn = fake.FakeQuantumClientConnection()
|
||||
@@ -53,6 +72,17 @@ class QuantumManager(manager.FlatManager):
|
||||
network_size, cidr_v6, gateway_v6, bridge,
|
||||
bridge_interface, dns1=None, dns2=None, uuid=None,
|
||||
**kwargs):
|
||||
""" Unlike other NetworkManagers, with QuantumManager, each
|
||||
create_networks calls should create only a single network.
|
||||
|
||||
Two scenarios exist:
|
||||
- no 'uuid' is specified, in which case we contact
|
||||
Quantum and create a new network.
|
||||
- an existing 'uuid' is specified, corresponding to
|
||||
a Quantum network created out of band.
|
||||
|
||||
In both cases, we initialize a subnet using the IPAM lib.
|
||||
"""
|
||||
if num_networks != 1:
|
||||
raise Exception("QuantumManager requires that only one"
|
||||
" network is created per call")
|
||||
@@ -74,27 +104,46 @@ class QuantumManager(manager.FlatManager):
|
||||
priority, cidr, gateway_v6, cidr_v6, dns1, dns2)
|
||||
|
||||
def delete_network(self, context, fixed_range):
|
||||
""" Lookup network by IPv4 cidr, delete both the IPAM
|
||||
subnet and the corresponding Quantum network.
|
||||
"""
|
||||
project_id = context.project_id
|
||||
quantum_net_id = self.ipam.get_network_id_by_cidr(
|
||||
context, fixed_range, project_id)
|
||||
self.ipam.delete_subnets_by_net_id(context, quantum_net_id,
|
||||
project_id)
|
||||
try:
|
||||
q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
|
||||
self.q_conn.delete_network(q_tenant_id, quantum_net_id)
|
||||
except Exception, e:
|
||||
raise Exception("Unable to delete Quantum Network with "
|
||||
"fixed_range = %s (ports still in use?)." % fixed_range)
|
||||
q_tenant_id = project_id or FLAGS.quantum_default_tenant_id
|
||||
self.q_conn.delete_network(q_tenant_id, quantum_net_id)
|
||||
|
||||
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)
|
||||
|
||||
# if using the create-server-networks extension, 'requested_networks'
|
||||
# will be defined, otherwise, just grab relevant nets from IPAM
|
||||
requested_networks = kwargs.get('requested_networks')
|
||||
|
||||
if requested_networks:
|
||||
@@ -116,10 +165,12 @@ class QuantumManager(manager.FlatManager):
|
||||
# updating the virtual_interfaces table to use UUIDs would
|
||||
# be one solution, but this would require significant work
|
||||
# elsewhere.
|
||||
network_ref = db.network_get_by_uuid(context, quantum_net_id)
|
||||
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'])
|
||||
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
|
||||
@@ -133,6 +184,18 @@ class QuantumManager(manager.FlatManager):
|
||||
|
||||
def get_instance_nw_info(self, context, instance_id,
|
||||
instance_type_id, host):
|
||||
""" This method is used by compute to fetch all network data
|
||||
that should be used when creating the VM.
|
||||
|
||||
The method simply loops through all virtual interfaces
|
||||
stored in the nova DB and queries the IPAM lib to get
|
||||
the associated IP data.
|
||||
|
||||
The format of returned data is 'defined' by the initial
|
||||
set of NetworkManagers found in nova/network/manager.py .
|
||||
Ideally this 'interface' will be more formally defined
|
||||
in the future.
|
||||
"""
|
||||
network_info = []
|
||||
instance = db.instance_get(context, instance_id)
|
||||
project_id = instance.project_id
|
||||
@@ -202,6 +265,11 @@ class QuantumManager(manager.FlatManager):
|
||||
return network_info
|
||||
|
||||
def deallocate_for_instance(self, context, **kwargs):
|
||||
""" Called when a VM is terminated. Loop through each virtual
|
||||
interface in the Nova DB and remove the Quantum port and
|
||||
clear the IP allocation using the IPAM. Finally, remove
|
||||
the virtual interfaces from the Nova DB.
|
||||
"""
|
||||
instance_id = kwargs.get('instance_id')
|
||||
project_id = kwargs.pop('project_id', None)
|
||||
|
||||
@@ -234,11 +302,12 @@ class QuantumManager(manager.FlatManager):
|
||||
self._do_trigger_security_group_members_refresh_for_instance(
|
||||
instance_id)
|
||||
|
||||
# validates that this tenant has quantum networks with the associated
|
||||
# UUIDs. This is called by the 'os-create-server-ext' API extension
|
||||
# code so that we can return an API error code to the caller if they
|
||||
# request an invalid network.
|
||||
def validate_networks(self, context, networks):
|
||||
""" Validates that this tenant has quantum networks with the associated
|
||||
UUIDs. This is called by the 'os-create-server-ext' API extension
|
||||
code so that we can return an API error code to the caller if they
|
||||
request an invalid network.
|
||||
"""
|
||||
if networks is None:
|
||||
return
|
||||
|
||||
|
||||
@@ -32,43 +32,54 @@ def get_ipam_lib(net_man):
|
||||
|
||||
|
||||
class QuantumMelangeIPAMLib:
|
||||
""" Implements Quantum IP Address Management (IPAM) interface
|
||||
using the Melange service, which is access using the Melange
|
||||
web services API.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
""" Initialize class used to connect to Melange server"""
|
||||
self.m_conn = melange_connection.MelangeConnection()
|
||||
|
||||
def create_subnet(self, context, label, project_id,
|
||||
quantum_net_id, priority, cidr=None,
|
||||
gateway_v6=None, cidr_v6=None,
|
||||
dns1=None, dns2=None):
|
||||
tenant_id = project_id or FLAGS.quantum_default_tenant_id
|
||||
if cidr:
|
||||
self.m_conn.create_block(quantum_net_id, cidr,
|
||||
""" Contact Melange and create a subnet for any non-NULL
|
||||
IPv4 or IPv6 subnets.
|
||||
|
||||
Also create a entry in the Nova networks DB, but only
|
||||
to store values not represented in Melange or to
|
||||
temporarily provide compatibility with Nova code that
|
||||
accesses IPAM data directly via the DB (e.g., nova-api)
|
||||
"""
|
||||
tenant_id = project_id or FLAGS.quantum_default_tenant_id
|
||||
if cidr:
|
||||
self.m_conn.create_block(quantum_net_id, cidr,
|
||||
project_id=tenant_id,
|
||||
dns1=dns1, dns2=dns2)
|
||||
if cidr_v6:
|
||||
self.m_conn.create_block(quantum_net_id, cidr_v6,
|
||||
if cidr_v6:
|
||||
self.m_conn.create_block(quantum_net_id, cidr_v6,
|
||||
project_id=tenant_id,
|
||||
dns1=dns1, dns2=dns2)
|
||||
|
||||
# create a entry in the network table, even though
|
||||
# most data is stored in melange. This is used to
|
||||
# store data not kept by melange (e.g., priority)
|
||||
# and to 'fake' other parts of nova (e.g., the API)
|
||||
# until we get get all accesses to be via the
|
||||
# network manager API.
|
||||
net = {"uuid": quantum_net_id,
|
||||
net = {"uuid": quantum_net_id,
|
||||
"project_id": project_id,
|
||||
"priority": priority,
|
||||
"label": label}
|
||||
network = self.db.network_create_safe(context, net)
|
||||
network = self.db.network_create_safe(context, net)
|
||||
|
||||
def allocate_fixed_ip(self, context, project_id, quantum_net_id, vif_ref):
|
||||
""" Pass call to allocate fixed IP on to Melange"""
|
||||
tenant_id = project_id or FLAGS.quantum_default_tenant_id
|
||||
self.m_conn.allocate_ip(quantum_net_id,
|
||||
vif_ref['uuid'], project_id=tenant_id,
|
||||
mac_address=vif_ref['address'])
|
||||
|
||||
def get_network_id_by_cidr(self, context, cidr, project_id):
|
||||
""" Find the Quantum UUID associated with a IPv4 CIDR
|
||||
address for the specified tenant.
|
||||
"""
|
||||
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']:
|
||||
@@ -77,6 +88,9 @@ class QuantumMelangeIPAMLib:
|
||||
raise Exception("No network found for cidr %s" % cidr)
|
||||
|
||||
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)
|
||||
@@ -88,9 +102,11 @@ class QuantumMelangeIPAMLib:
|
||||
if network is not None:
|
||||
db.network_delete_safe(context, network['id'])
|
||||
|
||||
# get all networks with this project_id, as well as all networks
|
||||
# where the project-id is not set (these are shared networks)
|
||||
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'.
|
||||
"""
|
||||
admin_context = context.elevated()
|
||||
id_proj_map = {}
|
||||
if project_id is None:
|
||||
@@ -115,12 +131,16 @@ class QuantumMelangeIPAMLib:
|
||||
return sorted(id_priority_map.items(),
|
||||
key=lambda x: id_priority_map[x[0]])
|
||||
|
||||
# FIXME: (danwent) Melange actually returns the subnet info
|
||||
# when we query for a particular interface. we may want to
|
||||
# reworks the ipam_manager python API to let us take advantage of
|
||||
# this, as right now we have to get all blocks and cycle through
|
||||
# them.
|
||||
def get_subnets_by_net_id(self, context, project_id, net_id):
|
||||
""" Returns information about the IPv4 and IPv6 subnets
|
||||
associated with a Quantum Network UUID.
|
||||
"""
|
||||
|
||||
# FIXME: (danwent) Melange actually returns the subnet info
|
||||
# when we query for a particular interface. we may want to
|
||||
# reworks the ipam_manager python API to let us take advantage of
|
||||
# this, as right now we have to get all blocks and cycle through
|
||||
# them.
|
||||
subnet_v4 = None
|
||||
subnet_v6 = None
|
||||
tenant_id = project_id or FLAGS.quantum_default_tenant_id
|
||||
@@ -142,26 +162,41 @@ class QuantumMelangeIPAMLib:
|
||||
return (subnet_v4, subnet_v6)
|
||||
|
||||
def get_v4_ips_by_interface(self, context, net_id, vif_id, project_id):
|
||||
return self.get_ips_by_interface(context, net_id, vif_id,
|
||||
""" Returns a list of IPv4 address strings associated with
|
||||
the specified virtual interface.
|
||||
"""
|
||||
return self._get_ips_by_interface(context, net_id, vif_id,
|
||||
project_id, 4)
|
||||
|
||||
def get_v6_ips_by_interface(self, context, net_id, vif_id, project_id):
|
||||
return self.get_ips_by_interface(context, net_id, vif_id,
|
||||
""" Returns a list of IPv6 address strings associated with
|
||||
the specified virtual interface.
|
||||
"""
|
||||
return self._get_ips_by_interface(context, net_id, vif_id,
|
||||
project_id, 6)
|
||||
|
||||
def get_ips_by_interface(self, context, net_id, vif_id, project_id,
|
||||
def _get_ips_by_interface(self, context, net_id, vif_id, project_id,
|
||||
ip_version):
|
||||
""" Helper method to fetch v4 or v6 addresses for a particular
|
||||
virtual interface.
|
||||
"""
|
||||
tenant_id = project_id or FLAGS.quantum_default_tenant_id
|
||||
ip_list = self.m_conn.get_allocated_ips(net_id, vif_id, tenant_id)
|
||||
return [ip['address'] for ip in ip_list \
|
||||
if IPNetwork(ip['address']).version == ip_version]
|
||||
|
||||
def verify_subnet_exists(self, context, project_id, quantum_net_id):
|
||||
""" Confirms that a subnet exists that is associated with the
|
||||
specified Quantum Network UUID.
|
||||
"""
|
||||
tenant_id = project_id or FLAGS.quantum_default_tenant_id
|
||||
v4_subnet, v6_subnet = self.get_subnets_by_net_id(context, tenant_id,
|
||||
quantum_net_id)
|
||||
return v4_subnet is not None
|
||||
|
||||
def deallocate_ips_by_vif(self, context, project_id, net_id, vif_ref):
|
||||
""" Deallocate all fixed IPs associated with the specified
|
||||
virtual interface.
|
||||
"""
|
||||
tenant_id = project_id or FLAGS.quantum_default_tenant_id
|
||||
self.m_conn.deallocate_ips(net_id, vif_ref['uuid'], tenant_id)
|
||||
|
||||
@@ -37,52 +37,69 @@ def get_ipam_lib(net_man):
|
||||
|
||||
|
||||
class QuantumNovaIPAMLib:
|
||||
""" Implements Quantum IP Address Management (IPAM) interface
|
||||
using the local Nova database. This implementation is inline
|
||||
with how IPAM is used by other NetworkManagers.
|
||||
"""
|
||||
|
||||
def __init__(self, net_manager):
|
||||
""" Holds a reference to the "parent" network manager, used
|
||||
to take advantage of various FlatManager methods to avoid
|
||||
code duplication.
|
||||
"""
|
||||
self.net_manager = net_manager
|
||||
|
||||
def create_subnet(self, context, label, tenant_id,
|
||||
quantum_net_id, priority, cidr=None,
|
||||
gateway_v6=None, cidr_v6=None,
|
||||
dns1=None, dns2=None):
|
||||
admin_context = context.elevated()
|
||||
subnet_size = int(math.pow(2, (32 - int(cidr.split("/")[1]))))
|
||||
networks = manager.FlatManager.create_networks(self.net_manager,
|
||||
""" Re-use the basic FlatManager create_networks method to
|
||||
initialize the networks and fixed_ips tables in Nova DB.
|
||||
|
||||
Also stores a few more fields in the networks table that
|
||||
are needed by Quantum but not the FlatManager.
|
||||
"""
|
||||
admin_context = context.elevated()
|
||||
subnet_size = int(math.pow(2, (32 - int(cidr.split("/")[1]))))
|
||||
networks = manager.FlatManager.create_networks(self.net_manager,
|
||||
admin_context, label, cidr,
|
||||
False, 1, subnet_size, cidr_v6,
|
||||
gateway_v6, quantum_net_id, None, dns1, dns2)
|
||||
|
||||
if len(networks) != 1:
|
||||
raise Exception("Error creating network entry")
|
||||
if len(networks) != 1:
|
||||
raise Exception("Error creating network entry")
|
||||
|
||||
# now grab the network and update additional fields
|
||||
network = networks[0]
|
||||
net = {"project_id": tenant_id,
|
||||
network = networks[0]
|
||||
net = {"project_id": tenant_id,
|
||||
"priority": priority,
|
||||
"uuid": quantum_net_id}
|
||||
db.network_update(admin_context, network['id'], net)
|
||||
db.network_update(admin_context, network['id'], net)
|
||||
|
||||
def get_network_id_by_cidr(self, context, cidr, project_id):
|
||||
admin_context = context.elevated()
|
||||
network = db.network_get_by_cidr(admin_context, cidr)
|
||||
if not network:
|
||||
raise Exception("No network with fixed_range = %s" \
|
||||
% fixed_range)
|
||||
return network['uuid']
|
||||
""" Grabs Quantum network UUID based on IPv4 CIDR. """
|
||||
admin_context = context.elevated()
|
||||
network = db.network_get_by_cidr(admin_context, cidr)
|
||||
if not network:
|
||||
raise Exception("No network with fixed_range = %s" % fixed_range)
|
||||
return network['uuid']
|
||||
|
||||
def delete_subnets_by_net_id(self, context, net_id, project_id):
|
||||
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,
|
||||
""" 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, network['cidr'],
|
||||
require_disassociated=False)
|
||||
|
||||
def get_project_and_global_net_ids(self, context, project_id):
|
||||
|
||||
# get all networks with this project_id, as well as all networks
|
||||
# where the project-id is not set (these are shared networks)
|
||||
""" Fetches all networks associated with this project, or
|
||||
that are "global" (i.e., have no project set).
|
||||
Returns list sorted by 'priority'.
|
||||
"""
|
||||
admin_context = context.elevated()
|
||||
networks = db.project_get_networks(admin_context, project_id, False)
|
||||
networks.extend(db.project_get_networks(admin_context, None, False))
|
||||
@@ -95,6 +112,8 @@ class QuantumNovaIPAMLib:
|
||||
return sorted(net_list, key=lambda x: id_priority_map[x[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']:
|
||||
@@ -106,6 +125,9 @@ class QuantumNovaIPAMLib:
|
||||
db.fixed_ip_update(admin_context, address, values)
|
||||
|
||||
def get_subnets_by_net_id(self, context, tenant_id, net_id):
|
||||
""" 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'],
|
||||
@@ -126,12 +148,18 @@ class QuantumNovaIPAMLib:
|
||||
return (subnet_data_v4, subnet_data_v6)
|
||||
|
||||
def get_v4_ips_by_interface(self, context, net_id, vif_id, project_id):
|
||||
""" Returns a list of IPv4 address strings associated with
|
||||
the specified virtual interface, based on the fixed_ips table.
|
||||
"""
|
||||
vif_rec = db.virtual_interface_get_by_uuid(context, vif_id)
|
||||
fixed_ips = db.fixed_ip_get_by_virtual_interface(context,
|
||||
vif_rec['id'])
|
||||
return [f['address'] for f in fixed_ips]
|
||||
|
||||
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)
|
||||
@@ -143,10 +171,17 @@ class QuantumNovaIPAMLib:
|
||||
return []
|
||||
|
||||
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()
|
||||
network = db.network_get_by_uuid(admin_context, quantum_net_id)
|
||||
db.network_get_by_uuid(admin_context, quantum_net_id)
|
||||
|
||||
def deallocate_ips_by_vif(self, context, tenant_id, net_id, vif_ref):
|
||||
""" Deallocate all fixed IPs associated with the specified
|
||||
virtual interface.
|
||||
"""
|
||||
try:
|
||||
admin_context = context.elevated()
|
||||
fixed_ips = db.fixed_ip_get_by_virtual_interface(admin_context,
|
||||
@@ -156,5 +191,5 @@ class QuantumNovaIPAMLib:
|
||||
{'allocated': False,
|
||||
'virtual_interface_id': None})
|
||||
except exception.FixedIpNotFoundForInstance:
|
||||
LOG.error(_('Failed to deallocate fixed IP for vif %s' % \
|
||||
LOG.error(_('No fixed IPs to deallocate for vif %s' % \
|
||||
vif_ref['id']))
|
||||
|
||||
@@ -38,31 +38,49 @@ flags.DEFINE_string('quantum_default_tenant_id',
|
||||
|
||||
|
||||
class QuantumClientConnection:
|
||||
""" Abstracts connection to Quantum service into higher level
|
||||
operations performed by the QuantumManager.
|
||||
|
||||
Separating this out as a class also let's us create a 'fake'
|
||||
version of this class for unit tests.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
""" Initialize Quantum client class based on flags. """
|
||||
self.client = quantum_client.Client(FLAGS.quantum_connection_host,
|
||||
FLAGS.quantum_connection_port,
|
||||
format="json",
|
||||
logger=LOG)
|
||||
|
||||
def create_network(self, tenant_id, network_name):
|
||||
""" Create network using specified name, return Quantum
|
||||
network UUID.
|
||||
"""
|
||||
data = {'network': {'name': network_name}}
|
||||
resdict = self.client.create_network(data, tenant=tenant_id)
|
||||
return resdict["network"]["id"]
|
||||
|
||||
def delete_network(self, tenant_id, net_id):
|
||||
""" Deletes Quantum network with specified UUID. """
|
||||
self.client.delete_network(net_id, tenant=tenant_id)
|
||||
|
||||
def network_exists(self, tenant_id, net_id):
|
||||
""" Determine if a Quantum network exists for the
|
||||
specified tenant.
|
||||
"""
|
||||
try:
|
||||
self.client.show_network_details(net_id, tenant=tenant_id)
|
||||
except:
|
||||
# FIXME: client lib should expose more granular exceptions
|
||||
# FIXME: (danwent) client lib should expose granular exceptions
|
||||
# so we can confirm we're getting a 404 and not some other error
|
||||
return False
|
||||
return True
|
||||
|
||||
def create_and_attach_port(self, tenant_id, net_id, interface_id):
|
||||
""" Creates a Quantum port on the specified network, sets
|
||||
status to ACTIVE to enable traffic, and attaches the
|
||||
vNIC with the specified interface-id.
|
||||
"""
|
||||
LOG.debug("Connecting interface %s to net %s for %s" % \
|
||||
(interface_id, net_id, tenant_id))
|
||||
port_data = {'port': {'state': 'ACTIVE'}}
|
||||
@@ -74,15 +92,19 @@ class QuantumClientConnection:
|
||||
tenant=tenant_id)
|
||||
|
||||
def detach_and_delete_port(self, tenant_id, net_id, port_id):
|
||||
""" Detach and delete the specified Quantum port. """
|
||||
LOG.debug("Deleting port %s on net %s for %s" % \
|
||||
(port_id, net_id, tenant_id))
|
||||
|
||||
self.client.detach_resource(net_id, port_id, tenant=tenant_id)
|
||||
self.client.delete_port(net_id, port_id, tenant=tenant_id)
|
||||
|
||||
# FIXME: (danwent) this will be inefficient until API implements querying
|
||||
def get_port_by_attachment(self, tenant_id, attachment_id):
|
||||
|
||||
""" Given a tenant, search for the Quantum network and port
|
||||
UUID that has the specified interface-id attachment.
|
||||
"""
|
||||
# FIXME: (danwent) this will be inefficient until the Quantum
|
||||
# API implements querying a port by the interface-id
|
||||
net_list_resdict = self.client.list_networks(tenant=tenant_id)
|
||||
for n in net_list_resdict["networks"]:
|
||||
net_id = n['id']
|
||||
|
||||
Reference in New Issue
Block a user