Changes to incorporate reviwer's comments. Also changed client.py to handle extension URLs.

This commit is contained in:
Sumit Naiksatam 2011-08-24 03:15:54 -07:00
parent 9c805ac851
commit ec9c06cf84
4 changed files with 83 additions and 50 deletions

View File

@ -63,8 +63,6 @@ class Client(object):
"""A base client class - derived from Glance.BaseClient""" """A base client class - derived from Glance.BaseClient"""
action_prefix = '/v0.1/tenants/{tenant_id}'
# Action query strings # Action query strings
networks_path = "/networks" networks_path = "/networks"
network_path = "/networks/%s" network_path = "/networks/%s"
@ -74,7 +72,7 @@ class Client(object):
def __init__(self, host="127.0.0.1", port=9696, use_ssl=False, tenant=None, def __init__(self, host="127.0.0.1", port=9696, use_ssl=False, tenant=None,
format="xml", testingStub=None, key_file=None, cert_file=None, format="xml", testingStub=None, key_file=None, cert_file=None,
logger=None): logger=None, action_prefix="/v0.1/tenants/{tenant_id}"):
""" """
Creates a new client to some service. Creates a new client to some service.
@ -97,6 +95,7 @@ class Client(object):
self.key_file = key_file self.key_file = key_file
self.cert_file = cert_file self.cert_file = cert_file
self.logger = logger self.logger = logger
self.action_prefix = action_prefix
def get_connection_type(self): def get_connection_type(self):
""" """
@ -130,7 +129,7 @@ class Client(object):
# Add format and tenant_id # Add format and tenant_id
action += ".%s" % self.format action += ".%s" % self.format
action = Client.action_prefix + action action = self.action_prefix + action
action = action.replace('{tenant_id}', self.tenant) action = action.replace('{tenant_id}', self.tenant)
if type(params) is dict: if type(params) is dict:

View File

@ -1,18 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#

View File

@ -1,4 +1,3 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4 # vim: tabstop=4 shiftwidth=4 softtabstop=4
# #
# Copyright 2011 Cisco Systems, Inc. All rights reserved. # Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -17,15 +16,15 @@
# #
# @author: Sumit Naiksatam, Cisco Systems, Inc. # @author: Sumit Naiksatam, Cisco Systems, Inc.
# #
"""
from nova import exception as excp
from nova import flags from nova import flags
from nova import log as logging from nova import log as logging
from nova.scheduler import driver from nova.scheduler import driver
from quantum.client import Client from quantum.client import Client
from quantum.common.wsgi import Serializer from quantum.common.wsgi import Serializer
LOG = logging.getLogger('nova.scheduler.quantum_aware_scheduler') LOG = logging.getLogger('quantum.plugins.cisco.nova.quantum_aware_scheduler')
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
flags.DEFINE_string('quantum_host', "127.0.0.1", flags.DEFINE_string('quantum_host', "127.0.0.1",
@ -36,7 +35,11 @@ flags.DEFINE_integer('quantum_port', 9696,
HOST = FLAGS.quantum_host HOST = FLAGS.quantum_host
PORT = FLAGS.quantum_port PORT = FLAGS.quantum_port
USE_SSL = False USE_SSL = False
ACTION_PREFIX_EXT = '/v0.1'
ACTION_PREFIX_CSCO = ACTION_PREFIX_EXT + \
'/extensions/csco/tenants/{tenant_id}'
TENANT_ID = 'nova' TENANT_ID = 'nova'
CSCO_EXT_NAME = 'Cisco Nova Tenant'
class QuantumScheduler(driver.Scheduler): class QuantumScheduler(driver.Scheduler):
@ -44,26 +47,47 @@ class QuantumScheduler(driver.Scheduler):
Quantum network service dependent scheduler Quantum network service dependent scheduler
Obtains the hostname from Quantum using an extension API Obtains the hostname from Quantum using an extension API
""" """
def __init__(self):
# 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")
request_url = "/extensions"
data = client.do_request('GET', request_url)
LOG.debug("Obtained supported extensions from Quantum: %s" % data)
for ext in data['extensions']:
name = ext['name']
if name == CSCO_EXT_NAME:
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, *args, **kwargs):
"""Gets the host name from the Quantum service""" """Gets the host name from the Quantum service"""
instance_id = _kwargs['instance_id'] instance_id = kwargs['instance_id']
user_id = \ user_id = \
_kwargs['request_spec']['instance_properties']['user_id'] kwargs['request_spec']['instance_properties']['user_id']
project_id = \ project_id = \
_kwargs['request_spec']['instance_properties']['project_id'] kwargs['request_spec']['instance_properties']['project_id']
instance_data_dict = \ instance_data_dict = \
{'novatenant': \ {'novatenant': \
{'instance-id': instance_id, {'instance_id': instance_id,
'instance-desc': \ 'instance_desc': \
{'user_id': user_id, 'project_id': project_id}}} {'user_id': user_id,
client = Client(HOST, PORT, USE_SSL, format='json') 'project_id': project_id
request_url = "/novatenants/" + project_id + "/get_host" }}}
data = client.do_request(TENANT_ID, 'PUT', request_url,
body=instance_data_dict)
hostname = data["host_list"]["host_1"]
client = Client(HOST, PORT, USE_SSL, format='json', tenant=TENANT_ID,
action_prefix=ACTION_PREFIX_CSCO)
request_url = "/novatenants/" + project_id + "/get_host"
data = client.do_request('PUT', request_url, body=instance_data_dict)
hostname = data["host_list"]["host_1"]
if not hostname: if not hostname:
raise driver.NoValidHost(_("Scheduler was unable to locate a host" raise driver.NoValidHost(_("Scheduler was unable to locate a host"
" for this request. Is the appropriate" " for this request. Is the appropriate"

View File

@ -1,4 +1,3 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4 # vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 Cisco Systems, Inc. All rights reserved. # Copyright 2011 Cisco Systems, Inc. All rights reserved.
# #
@ -16,19 +15,20 @@
# #
# @author: Sumit Naiksatam, Cisco Systems, Inc. # @author: Sumit Naiksatam, Cisco Systems, Inc.
# #
"""
"""VIF drivers for interface type direct.""" """VIF drivers for interface type direct."""
from nova import exception as excp
from nova import flags from nova import flags
from nova import log as logging from nova import log as logging
from nova import utils
from nova.network import linux_net from nova.network import linux_net
from nova.virt.libvirt import netutils from nova.virt.libvirt import netutils
from nova import utils
from nova.virt.vif import VIFDriver from nova.virt.vif import VIFDriver
from quantum.client import Client from quantum.client import Client
from quantum.common.wsgi import Serializer from quantum.common.wsgi import Serializer
LOG = logging.getLogger('nova.virt.libvirt.vif') LOG = logging.getLogger('quantum.plugins.cisco.nova.vifdirect')
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
flags.DEFINE_string('quantum_host', "127.0.0.1", flags.DEFINE_string('quantum_host', "127.0.0.1",
@ -40,10 +40,34 @@ HOST = FLAGS.quantum_host
PORT = FLAGS.quantum_port PORT = FLAGS.quantum_port
USE_SSL = False USE_SSL = False
TENANT_ID = 'nova' TENANT_ID = 'nova'
ACTION_PREFIX_EXT = '/v0.1'
ACTION_PREFIX_CSCO = ACTION_PREFIX_EXT + \
'/extensions/csco/tenants/{tenant_id}'
TENANT_ID = 'nova'
CSCO_EXT_NAME = 'Cisco Nova Tenant'
class Libvirt802dot1QbhDriver(VIFDriver): class Libvirt802dot1QbhDriver(VIFDriver):
"""VIF driver for Linux bridge.""" """VIF driver for Linux bridge."""
def __init__(self):
# 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")
request_url = "/extensions"
data = client.do_request('GET', request_url)
LOG.debug("Obtained supported extensions from Quantum: %s" % data)
for ext in data['extensions']:
name = ext['name']
if name == CSCO_EXT_NAME:
LOG.debug("Quantum plugin supports required \"%s\" extension"
"for the VIF driver." % name)
return
LOG.error("Quantum plugin does not support required \"%s\" extension"
" for the VIF driver. nova-compute will quit." \
% CSCO_EXT_NAME)
raise excp.ServiceUnavailable()
def _get_configurations(self, instance, network, mapping): def _get_configurations(self, instance, network, mapping):
"""Gets the device name and the profile name from Quantum""" """Gets the device name and the profile name from Quantum"""
@ -51,22 +75,26 @@ class Libvirt802dot1QbhDriver(VIFDriver):
instance_id = instance['id'] instance_id = instance['id']
user_id = instance['user_id'] user_id = instance['user_id']
project_id = instance['project_id'] project_id = instance['project_id']
vif_id = mapping['vif_uuid']
instance_data_dict = \ instance_data_dict = \
{'novatenant': \ {'novatenant': \
{'instance-id': instance_id, {'instance_id': instance_id,
'instance-desc': \ 'instance_desc': \
{'user_id': user_id, 'project_id': project_id}}} {'user_id': user_id,
'project_id': project_id,
'vif_id': vif_id
}}}
client = Client(HOST, PORT, USE_SSL, format='json') client = Client(HOST, PORT, USE_SSL, format='json', tenant=TENANT_ID,
action_prefix=ACTION_PREFIX_CSCO)
request_url = "/novatenants/" + project_id + "/get_instance_port" request_url = "/novatenants/" + project_id + "/get_instance_port"
data = client.do_request(TENANT_ID, 'PUT', request_url, data = client.do_request('PUT', request_url, body=instance_data_dict)
body=instance_data_dict)
device = data['vif_desc']['device'] device = data['vif_desc']['device']
portprofile = data['vif_desc']['portprofile'] portprofile = data['vif_desc']['portprofile']
LOG.debug(_("Quantum provided the device: %s") % device)
LOG.debug(_("Quantum returned device: %s\n") % device) LOG.debug(_("Quantum provided the portprofile: %s") % portprofile)
LOG.debug(_("Quantum returned portprofile: %s\n") % portprofile)
mac_id = mapping['mac'].replace(':', '') mac_id = mapping['mac'].replace(':', '')
result = { result = {