Bug #956559
VIF driver and scheduler for UCS plugin are broken since the flag configuration mechanism in nova is changed. Fixing that and also fixing some property names, along changes to how the quantum client code is invoked. Change-Id: I757cc149f08673ce24d35ee0bfffae8e5b1a4afc
This commit is contained in:
parent
98419e1fa4
commit
8009f0fc27
@ -41,8 +41,9 @@ If you plan to just leverage the plugin framework, you do not need these.)
|
||||
Palo adapters) installed.
|
||||
* UCSM 2.0 (Capitola) Build 230 or above.
|
||||
* OpenStack Diablo D3 or later (should have VIF-driver support)
|
||||
* RHEL 6.1 (as of this writing, UCS only officially supports RHEL, but
|
||||
it should be noted that Ubuntu support is planned in coming releases as well)
|
||||
* OS supported:
|
||||
** RHEL 6.1 or above
|
||||
** Ubuntu 11.10 or above
|
||||
** Package: python-configobj-4.6.0-3.el6.noarch (or newer)
|
||||
** Package: python-routes-1.12.3-2.el6.noarch (or newer)
|
||||
|
||||
@ -50,7 +51,6 @@ If you are using a Nexus switch in your topology, you'll need the following
|
||||
NX-OS version and packages to enable Nexus support:
|
||||
* NX-OS 5.2.1 (Delhi) Build 69 or above.
|
||||
* paramiko library - SSHv2 protocol library for python
|
||||
** To install on RHEL 6.1, run: yum install python-paramiko
|
||||
* ncclient v0.3.1 - Python library for NETCONF clients
|
||||
** You need a version of ncclient modifed by Cisco Systems.
|
||||
To get it, from your shell prompt do:
|
||||
@ -61,25 +61,6 @@ NX-OS version and packages to enable Nexus support:
|
||||
** For more information of ncclient, see:
|
||||
http://schmizz.net/ncclient/
|
||||
|
||||
To verify the version of any package you have installed on your system,
|
||||
run "rpm -qav | grep <package name>", where <package name> is the
|
||||
package you want to query (for example: python-routes).
|
||||
|
||||
Note that you can get access to recent versions of the packages above
|
||||
and other OpenStack software packages by adding a new repository to
|
||||
your yum configuration. To do so, edit or create
|
||||
/etc/yum.repos.d/openstack.repo and add the following:
|
||||
|
||||
[openstack-deps]
|
||||
name=OpenStack Nova Compute Dependencies
|
||||
baseurl=http://yum.griddynamics.net/yum/cactus/deps
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-OPENSTACK
|
||||
|
||||
Then run "yum install python-routes".
|
||||
|
||||
|
||||
Module Structure:
|
||||
-----------------
|
||||
* quantum/plugins/cisco/ - Contains the L2-Network Plugin Framework
|
||||
@ -93,15 +74,17 @@ Module Structure:
|
||||
/nexus - Nexus-specific modules
|
||||
/segmentation - Implementation of segmentation manager,
|
||||
e.g. VLAN Manager
|
||||
/services - Set of orchestration libraries to insert
|
||||
In-path Networking Services
|
||||
/tests - Tests specific to this plugin
|
||||
/ucs - UCS-specific modules
|
||||
|
||||
|
||||
Plugin Installation Instructions
|
||||
----------------------------------
|
||||
1. Make a backup copy of quantum/quantum/plugins.ini.
|
||||
1. Make a backup copy of quantum/etc/plugins.ini.
|
||||
|
||||
2. Edit quantum/quantum/plugins.ini and edit the "provider" entry to point
|
||||
2. Edit quantum/etc/plugins.ini and edit the "provider" entry to point
|
||||
to the L2Network-plugin:
|
||||
|
||||
provider = quantum.plugins.cisco.l2network_plugin.L2Network
|
||||
@ -130,18 +113,18 @@ provider = quantum.plugins.cisco.l2network_plugin.L2Network
|
||||
4. To support the above configuration, you will need some Quantum modules. It's easiest
|
||||
to copy the entire quantum directory from your quantum installation into:
|
||||
|
||||
/usr/lib/python2.6/site-packages/
|
||||
/usr/lib/python2.7/site-packages/
|
||||
|
||||
This needs to be done for each nova compute node.
|
||||
|
||||
5. If you want to turn on support for Cisco Nexus switches:
|
||||
5a. Uncomment the nexus_plugin property in
|
||||
quantum/plugins/cisco/conf/plugins.ini to read:
|
||||
etc/quantum/plugins/cisco/cisco_plugins.ini to read:
|
||||
|
||||
nexus_plugin=quantum.plugins.cisco.nexus.cisco_nexus_plugin.NexusPlugin
|
||||
|
||||
5b. Enter the relevant configuration in the
|
||||
quantum/plugins/cisco/conf/nexus.ini file. Example:
|
||||
etc/quantum/plugins/cisco/nexus.ini file. Example:
|
||||
|
||||
[SWITCH]
|
||||
# Change the following to reflect the IP address of the Nexus switch.
|
||||
@ -252,7 +235,7 @@ networks. That implies -
|
||||
(2) Before each VM is instantiated, you should create Quantum ports on each of those
|
||||
networks. These ports need to be created using the following rest call:
|
||||
|
||||
POST /v1.0/extensions/csco/tenants/{tenant_id}/multiport/
|
||||
POST /1.0/extensions/csco/tenants/{tenant_id}/multiport/
|
||||
|
||||
with request body:
|
||||
|
||||
@ -269,7 +252,7 @@ and value should be used.
|
||||
|
||||
The corresponding CLI for this operation is as follows:
|
||||
|
||||
PYTHONPATH=. python plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py create_multiport <tenant_id> <net_id1,net_id2,...>
|
||||
PYTHONPATH=. python quantum/plugins/cisco/client/cli.py create_multiport <tenant_id> <net_id1,net_id2,...>
|
||||
|
||||
(Note that you should not be using the create port core API in the above case.)
|
||||
|
||||
@ -282,18 +265,18 @@ to switch between different CLI modules (it internally invokes the Quantum
|
||||
CLI module for the core APIs to ensure consistency when using either). This
|
||||
command line client can be invoked as follows:
|
||||
|
||||
PYTHONPATH=.:tools python plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py
|
||||
PYTHONPATH=.:tools python quantum/plugins/cisco/client/cli.py
|
||||
|
||||
1. Creating the network
|
||||
|
||||
# PYTHONPATH=. python plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py create_net -H 10.10.2.6 demo net1
|
||||
# PYTHONPATH=. python quantum/plugins/cisco/client/cli.py create_net -H 10.10.2.6 demo net1
|
||||
Created a new Virtual Network with ID: c4a2bea7-a528-4caf-b16e-80397cd1663a
|
||||
for Tenant demo
|
||||
|
||||
|
||||
2. Listing the networks
|
||||
|
||||
# PYTHONPATH=. python plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py list_nets -H 10.10.2.6 demo
|
||||
# PYTHONPATH=. python quantum/plugins/cisco/client/cli.py list_nets -H 10.10.2.6 demo
|
||||
Virtual Networks for Tenant demo
|
||||
Network ID: 0e85e924-6ef6-40c1-9f7a-3520ac6888b3
|
||||
Network ID: c4a2bea7-a528-4caf-b16e-80397cd1663a
|
||||
@ -301,13 +284,13 @@ Virtual Networks for Tenant demo
|
||||
|
||||
3. Creating one port on each of the networks
|
||||
|
||||
# PYTHONPATH=. python plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py create_multiport -H 10.10.2.6 demo c4a2bea7-a528-4caf-b16e-80397cd1663a,0e85e924-6ef6-40c1-9f7a-3520ac6888b3
|
||||
# PYTHONPATH=. python quantum/plugins/cisco/client/cli.py create_multiport -H 10.10.2.6 demo c4a2bea7-a528-4caf-b16e-80397cd1663a,0e85e924-6ef6-40c1-9f7a-3520ac6888b3
|
||||
Created ports: {u'ports': [{u'id': u'118ac473-294d-480e-8f6d-425acbbe81ae'}, {u'id': u'996e84b8-2ed3-40cf-be75-de17ff1214c4'}]}
|
||||
|
||||
|
||||
4. List all the ports on a network
|
||||
|
||||
# PYTHONPATH=. python plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py list_ports -H 10.10.2.6 demo c4a2bea7-a528-4caf-b16e-80397cd1663a
|
||||
# PYTHONPATH=. python quantum/plugins/cisco/client/cli.py list_ports -H 10.10.2.6 demo c4a2bea7-a528-4caf-b16e-80397cd1663a
|
||||
Ports on Virtual Network: c4a2bea7-a528-4caf-b16e-80397cd1663a
|
||||
for Tenant: demo
|
||||
Logical Port: 118ac473-294d-480e-8f6d-425acbbe81ae
|
||||
@ -315,7 +298,7 @@ for Tenant: demo
|
||||
|
||||
5. Show the details of a port
|
||||
|
||||
# PYTHONPATH=. python plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py show_port -H 10.10.2.6 demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae
|
||||
# PYTHONPATH=. python quantum/plugins/cisco/client/cli.py show_port -H 10.10.2.6 demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae
|
||||
Logical Port ID: 118ac473-294d-480e-8f6d-425acbbe81ae
|
||||
administrative State: ACTIVE
|
||||
interface: <none>
|
||||
@ -335,7 +318,7 @@ for Tenant: demo
|
||||
will be established only after the plug/attach operation is performed (as
|
||||
described in the next step).
|
||||
|
||||
# PYTHONPATH=. python plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py show_port demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae
|
||||
# PYTHONPATH=. python quantum/plugins/cisco/client/cli.py show_port demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae
|
||||
Logical Port ID: 118ac473-294d-480e-8f6d-425acbbe81ae
|
||||
administrative State: ACTIVE
|
||||
interface: b73e3585-d074-4379-8dde-931c0fc4db0e(detached)
|
||||
@ -347,7 +330,7 @@ for Tenant: demo
|
||||
Use the interface information obtained in step 6 to plug the interface into
|
||||
the network.
|
||||
|
||||
# PYTHONPATH=. python plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py plug_iface demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae b73e3585-d074-4379-8dde-931c0fc4db0e
|
||||
# PYTHONPATH=. python quantum/plugins/cisco/client/cli.py plug_iface demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae b73e3585-d074-4379-8dde-931c0fc4db0e
|
||||
Plugged interface b73e3585-d074-4379-8dde-931c0fc4db0e
|
||||
into Logical Port: 118ac473-294d-480e-8f6d-425acbbe81ae
|
||||
on Virtual Network: c4a2bea7-a528-4caf-b16e-80397cd1663a
|
||||
@ -356,7 +339,7 @@ for Tenant: demo
|
||||
|
||||
8. Unplug an interface and port from the network
|
||||
|
||||
# PYTHONPATH=. python plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py unplug_iface demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae
|
||||
# PYTHONPATH=. python quantum/plugins/cisco/client/cli.py unplug_iface demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae
|
||||
Unplugged interface from Logical Port: 118ac473-294d-480e-8f6d-425acbbe81ae
|
||||
on Virtual Network: c4a2bea7-a528-4caf-b16e-80397cd1663a
|
||||
for Tenant: demo
|
||||
|
@ -17,33 +17,48 @@
|
||||
# @author: Sumit Naiksatam, Cisco Systems, Inc.
|
||||
#
|
||||
|
||||
|
||||
"""
|
||||
Quantum Port Aware Scheduler Implementation
|
||||
"""
|
||||
|
||||
from nova import exception as excp
|
||||
from nova import flags
|
||||
from nova import log as logging
|
||||
from nova.openstack.common import cfg
|
||||
from nova.scheduler import driver
|
||||
from nova.scheduler import chance
|
||||
from quantum.client import Client
|
||||
from quantum.common.wsgi import Serializer
|
||||
|
||||
LOG = logging.getLogger('quantum.plugins.cisco.nova.quantum_aware_scheduler')
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
quantum_opts = [
|
||||
cfg.StrOpt('quantum_connection_host',
|
||||
default='127.0.0.1',
|
||||
help='HOST for connecting to quantum'),
|
||||
cfg.StrOpt('quantum_connection_port',
|
||||
default='9696',
|
||||
help='PORT for connecting to quantum'),
|
||||
cfg.StrOpt('quantum_default_tenant_id',
|
||||
default="default",
|
||||
help='Default tenant id when creating quantum networks'),
|
||||
]
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
flags.DEFINE_string('quantum_host', "127.0.0.1",
|
||||
'IP address of the quantum network service.')
|
||||
flags.DEFINE_integer('quantum_port', 9696,
|
||||
'Listening port for Quantum network service')
|
||||
FLAGS.register_opts(quantum_opts)
|
||||
|
||||
HOST = FLAGS.quantum_host
|
||||
PORT = FLAGS.quantum_port
|
||||
HOST = FLAGS.quantum_connection_host
|
||||
PORT = FLAGS.quantum_connection_port
|
||||
USE_SSL = False
|
||||
ACTION_PREFIX_EXT = '/v1.0'
|
||||
ACTION_PREFIX_CSCO = ACTION_PREFIX_EXT + \
|
||||
'/extensions/csco/tenants/{tenant_id}'
|
||||
VERSION = '1.0'
|
||||
URI_PREFIX_CSCO = '/extensions/csco/tenants/{tenant_id}'
|
||||
TENANT_ID = 'nova'
|
||||
CSCO_EXT_NAME = 'Cisco Nova Tenant'
|
||||
ACTION = '/schedule_host'
|
||||
|
||||
|
||||
class QuantumPortAwareScheduler(driver.Scheduler):
|
||||
class QuantumPortAwareScheduler(chance.ChanceScheduler):
|
||||
"""
|
||||
Quantum network service dependent scheduler
|
||||
Obtains the hostname from Quantum using an extension API
|
||||
@ -52,8 +67,9 @@ class QuantumPortAwareScheduler(driver.Scheduler):
|
||||
# We have to send a dummy tenant name here since the client
|
||||
# needs some tenant name, but the tenant name will not be used
|
||||
# since the extensions URL does not require it
|
||||
client = Client(HOST, PORT, USE_SSL, format='json',
|
||||
action_prefix=ACTION_PREFIX_EXT, tenant="dummy")
|
||||
LOG.debug("Initializing Cisco Quantum Port-aware Scheduler...")
|
||||
client = Client(HOST, PORT, USE_SSL, format='json', version=VERSION,
|
||||
uri_prefix="", tenant="dummy", logger=LOG)
|
||||
request_url = "/extensions"
|
||||
data = client.do_request('GET', request_url)
|
||||
LOG.debug("Obtained supported extensions from Quantum: %s" % data)
|
||||
@ -63,17 +79,19 @@ class QuantumPortAwareScheduler(driver.Scheduler):
|
||||
LOG.debug("Quantum plugin supports required \"%s\" extension"
|
||||
"for the scheduler." % name)
|
||||
return
|
||||
|
||||
LOG.error("Quantum plugin does not support required \"%s\" extension"
|
||||
" for the scheduler. Scheduler will quit." % CSCO_EXT_NAME)
|
||||
raise excp.ServiceUnavailable()
|
||||
|
||||
def schedule(self, context, topic, *args, **kwargs):
|
||||
def _schedule(self, context, topic, request_spec, **kwargs):
|
||||
"""Gets the host name from the Quantum service"""
|
||||
instance_id = kwargs['instance_id']
|
||||
LOG.debug("Cisco Quantum Port-aware Scheduler is scheduling...")
|
||||
instance_id = request_spec['instance_properties']['uuid']
|
||||
user_id = \
|
||||
kwargs['request_spec']['instance_properties']['user_id']
|
||||
request_spec['instance_properties']['user_id']
|
||||
project_id = \
|
||||
kwargs['request_spec']['instance_properties']['project_id']
|
||||
request_spec['instance_properties']['project_id']
|
||||
|
||||
instance_data_dict = \
|
||||
{'novatenant': \
|
||||
@ -82,14 +100,15 @@ class QuantumPortAwareScheduler(driver.Scheduler):
|
||||
{'user_id': user_id,
|
||||
'project_id': project_id}}}
|
||||
|
||||
client = Client(HOST, PORT, USE_SSL, format='json', tenant=TENANT_ID,
|
||||
action_prefix=ACTION_PREFIX_CSCO)
|
||||
client = Client(HOST, PORT, USE_SSL, format='json', version=VERSION,
|
||||
uri_prefix=URI_PREFIX_CSCO, tenant=TENANT_ID,
|
||||
logger=LOG)
|
||||
request_url = "/novatenants/" + project_id + ACTION
|
||||
data = client.do_request('PUT', request_url, body=instance_data_dict)
|
||||
|
||||
hostname = data["host_list"]["host_1"]
|
||||
if not hostname:
|
||||
raise driver.NoValidHost(_("Scheduler was unable to locate a host"
|
||||
raise excp.NoValidHost(_("Scheduler was unable to locate a host"
|
||||
" for this request. Is the appropriate"
|
||||
" service running?"))
|
||||
|
||||
|
@ -18,31 +18,37 @@
|
||||
|
||||
"""VIF drivers for interface type direct."""
|
||||
|
||||
|
||||
from nova import exception as excp
|
||||
from nova import flags
|
||||
from nova import log as logging
|
||||
from nova.network import linux_net
|
||||
from nova.virt.libvirt import netutils
|
||||
from nova import utils
|
||||
from nova.openstack.common import cfg
|
||||
from nova.virt.vif import VIFDriver
|
||||
from quantum.client import Client
|
||||
from quantum.common.wsgi import Serializer
|
||||
|
||||
LOG = logging.getLogger('quantum.plugins.cisco.nova.vifdirect')
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
quantum_opts = [
|
||||
cfg.StrOpt('quantum_connection_host',
|
||||
default='127.0.0.1',
|
||||
help='HOST for connecting to quantum'),
|
||||
cfg.StrOpt('quantum_connection_port',
|
||||
default='9696',
|
||||
help='PORT for connecting to quantum'),
|
||||
cfg.StrOpt('quantum_default_tenant_id',
|
||||
default="default",
|
||||
help='Default tenant id when creating quantum networks'),
|
||||
]
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
flags.DEFINE_string('quantum_host', "127.0.0.1",
|
||||
'IP address of the quantum network service.')
|
||||
flags.DEFINE_integer('quantum_port', 9696,
|
||||
'Listening port for Quantum network service')
|
||||
FLAGS.register_opts(quantum_opts)
|
||||
|
||||
HOST = FLAGS.quantum_host
|
||||
PORT = FLAGS.quantum_port
|
||||
HOST = FLAGS.quantum_connection_host
|
||||
PORT = FLAGS.quantum_connection_port
|
||||
USE_SSL = False
|
||||
TENANT_ID = 'nova'
|
||||
ACTION_PREFIX_EXT = '/v1.0'
|
||||
ACTION_PREFIX_CSCO = ACTION_PREFIX_EXT + \
|
||||
'/extensions/csco/tenants/{tenant_id}'
|
||||
VERSION = '1.0'
|
||||
URI_PREFIX_CSCO = '/extensions/csco/tenants/{tenant_id}'
|
||||
TENANT_ID = 'nova'
|
||||
CSCO_EXT_NAME = 'Cisco Nova Tenant'
|
||||
ASSOCIATE_ACTION = '/associate_port'
|
||||
@ -55,8 +61,9 @@ class Libvirt802dot1QbhDriver(VIFDriver):
|
||||
# We have to send a dummy tenant name here since the client
|
||||
# needs some tenant name, but the tenant name will not be used
|
||||
# since the extensions URL does not require it
|
||||
client = Client(HOST, PORT, USE_SSL, format='json',
|
||||
action_prefix=ACTION_PREFIX_EXT, tenant="dummy")
|
||||
LOG.debug("Initializing Cisco Quantum VIF driver...")
|
||||
client = Client(HOST, PORT, USE_SSL, format='json', version=VERSION,
|
||||
uri_prefix="", tenant="dummy", logger=LOG)
|
||||
request_url = "/extensions"
|
||||
data = client.do_request('GET', request_url)
|
||||
LOG.debug("Obtained supported extensions from Quantum: %s" % data)
|
||||
@ -73,8 +80,8 @@ class Libvirt802dot1QbhDriver(VIFDriver):
|
||||
|
||||
def _update_configurations(self, instance, network, mapping, action):
|
||||
"""Gets the device name and the profile name from Quantum"""
|
||||
|
||||
instance_id = instance['id']
|
||||
LOG.debug("Cisco Quantum VIF driver performing: %s" % (action))
|
||||
instance_id = instance['uuid']
|
||||
user_id = instance['user_id']
|
||||
project_id = instance['project_id']
|
||||
vif_id = mapping['vif_uuid']
|
||||
@ -87,8 +94,9 @@ class Libvirt802dot1QbhDriver(VIFDriver):
|
||||
'project_id': project_id,
|
||||
'vif_id': vif_id}}}
|
||||
|
||||
client = Client(HOST, PORT, USE_SSL, format='json', tenant=TENANT_ID,
|
||||
action_prefix=ACTION_PREFIX_CSCO)
|
||||
client = Client(HOST, PORT, USE_SSL, format='json', version=VERSION,
|
||||
uri_prefix=URI_PREFIX_CSCO, tenant=TENANT_ID,
|
||||
logger=LOG)
|
||||
request_url = "/novatenants/" + project_id + action
|
||||
data = client.do_request('PUT', request_url, body=instance_data_dict)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user