gettext.install('quantum', unicode=1)
-from quantum import service
+from quantum import service
from quantum.common import config
+
def create_options(parser):
"""
Sets up the CLI and config-file options that may be
service.wait()
except RuntimeError, e:
sys.exit("ERROR: %s" % e)
-
bind_host = 0.0.0.0
# Port the bind the API server to
-bind_port = 9696
\ No newline at end of file
+bind_port = 9696
mapper.resource('port', 'ports',
controller=ports.Controller(),
parent_resource=dict(member_name='network',
- collection_name=\
- uri_prefix + 'networks'))
+ collection_name=uri_prefix +\
+ 'networks'))
+
mapper.connect("get_resource",
uri_prefix + 'networks/{network_id}/' \
'ports/{id}/attachment{.format}',
432: "portInUse",
440: "alreadyAttached",
470: "serviceUnavailable",
- 471: "pluginFault"
- }
+ 471: "pluginFault"}
def __init__(self, exception):
"""Create a Fault for the given webob.exc.exception."""
fault_data = {
fault_name: {
'code': code,
- 'message': self.wrapped_exc.explanation,
+ 'message': self.wrapped_exc.explanation,
'detail': self.wrapped_exc.detail}}
# 'code' is an attribute on the fault tag itself
metadata = {'application/xml': {'attributes': {fault_name: 'code'}}}
self._resource_name = 'network'
super(Controller, self).__init__()
- def index(self, req, tenant_id):
+ def index(self, request, tenant_id):
""" Returns a list of network ids """
#TODO: this should be for a given tenant!!!
- return self._items(req, tenant_id, is_detail=False)
+ return self._items(request, tenant_id, is_detail=False)
- def _items(self, req, tenant_id, is_detail):
+ def _items(self, request, tenant_id, is_detail):
""" Returns a list of networks. """
networks = self.network_manager.get_all_networks(tenant_id)
- builder = networks_view.get_view_builder(req)
+ builder = networks_view.get_view_builder(request)
result = [builder.build(network, is_detail)['network']
for network in networks]
return dict(networks=result)
- def show(self, req, tenant_id, id):
+ def show(self, request, tenant_id, id):
""" Returns network details for the given network id """
try:
network = self.network_manager.get_network_details(
tenant_id, id)
- builder = networks_view.get_view_builder(req)
+ builder = networks_view.get_view_builder(request)
#build response with details
result = builder.build(network, True)
return dict(networks=result)
except exception.NetworkNotFound as e:
return faults.Fault(faults.NetworkNotFound(e))
- def create(self, req, tenant_id):
+ def create(self, request, tenant_id):
""" Creates a new network for a given tenant """
#look for network name in request
try:
- req_params = \
- self._parse_request_params(req, self._network_ops_param_list)
+ request_params = \
+ self._parse_request_params(request,
+ self._network_ops_param_list)
except exc.HTTPError as e:
return faults.Fault(e)
network = self.network_manager.\
- create_network(tenant_id,req_params['network-name'])
- builder = networks_view.get_view_builder(req)
+ create_network(tenant_id,
+ request_params['network-name'])
+ builder = networks_view.get_view_builder(request)
result = builder.build(network)
return dict(networks=result)
- def update(self, req, tenant_id, id):
+ def update(self, request, tenant_id, id):
""" Updates the name for the network with the given id """
try:
- req_params = \
- self._parse_request_params(req, self._network_ops_param_list)
+ request_params = \
+ self._parse_request_params(request,
+ self._network_ops_param_list)
except exc.HTTPError as e:
return faults.Fault(e)
try:
network = self.network_manager.rename_network(tenant_id,
- id, req_params['network-name'])
+ id, request_params['network-name'])
- builder = networks_view.get_view_builder(req)
+ builder = networks_view.get_view_builder(request)
result = builder.build(network, True)
return dict(networks=result)
except exception.NetworkNotFound as e:
return faults.Fault(faults.NetworkNotFound(e))
- def delete(self, req, tenant_id, id):
+ def delete(self, request, tenant_id, id):
""" Destroys the network with the given id """
try:
self.network_manager.delete_network(tenant_id, id)
LOG = logging.getLogger('quantum.api.ports')
+
class Controller(common.QuantumController):
""" Port API controller for Quantum API """
_port_ops_param_list = [{
'param-name': 'port-state',
'default-value': 'DOWN',
- 'required': False},]
+ 'required': False}, ]
_attachment_ops_param_list = [{
'param-name': 'attachment-id',
- 'required': True},]
+ 'required': True}, ]
_serialization_metadata = {
"application/xml": {
"attributes": {
- "port": ["id","state"],
- },
- },
- }
+ "port": ["id", "state"], }, }, }
def __init__(self, plugin_conf_file=None):
self._resource_name = 'port'
super(Controller, self).__init__()
- def index(self, req, tenant_id, network_id):
+ def index(self, request, tenant_id, network_id):
""" Returns a list of port ids for a given network """
- return self._items(req, tenant_id, network_id, is_detail=False)
+ return self._items(request, tenant_id, network_id, is_detail=False)
- def _items(self, req, tenant_id, network_id, is_detail):
+ def _items(self, request, tenant_id, network_id, is_detail):
""" Returns a list of networks. """
- try :
+ try:
ports = self.network_manager.get_all_ports(tenant_id, network_id)
- builder = ports_view.get_view_builder(req)
+ builder = ports_view.get_view_builder(request)
result = [builder.build(port, is_detail)['port']
for port in ports]
return dict(ports=result)
except exception.NetworkNotFound as e:
return faults.Fault(faults.NetworkNotFound(e))
- def show(self, req, tenant_id, network_id, id):
+ def show(self, request, tenant_id, network_id, id):
""" Returns port details for given port and network """
try:
port = self.network_manager.get_port_details(
tenant_id, network_id, id)
- builder = ports_view.get_view_builder(req)
+ builder = ports_view.get_view_builder(request)
#build response with details
result = builder.build(port, True)
return dict(ports=result)
except exception.PortNotFound as e:
return faults.Fault(faults.PortNotFound(e))
- def create(self, req, tenant_id, network_id):
+ def create(self, request, tenant_id, network_id):
""" Creates a new port for a given network """
#look for port state in request
try:
- req_params = \
- self._parse_request_params(req, self._port_ops_param_list)
+ request_params = \
+ self._parse_request_params(request, self._port_ops_param_list)
except exc.HTTPError as e:
return faults.Fault(e)
try:
port = self.network_manager.create_port(tenant_id,
- network_id,
- req_params['port-state'])
- builder = ports_view.get_view_builder(req)
+ network_id,
+ request_params['port-state'])
+ builder = ports_view.get_view_builder(request)
result = builder.build(port)
return dict(ports=result)
except exception.NetworkNotFound as e:
except exception.StateInvalid as e:
return faults.Fault(faults.RequestedStateInvalid(e))
- def update(self, req, tenant_id, network_id, id):
+ def update(self, request, tenant_id, network_id, id):
""" Updates the state of a port for a given network """
#look for port state in request
try:
- req_params = \
- self._parse_request_params(req, self._port_ops_param_list)
+ request_params = \
+ self._parse_request_params(request, self._port_ops_param_list)
except exc.HTTPError as e:
return faults.Fault(e)
try:
- port = self.network_manager.update_port(tenant_id,network_id, id,
- req_params['port-state'])
- builder = ports_view.get_view_builder(req)
+ port = self.network_manager.update_port(tenant_id, network_id, id,
+ request_params['port-state'])
+ builder = ports_view.get_view_builder(request)
result = builder.build(port, True)
return dict(ports=result)
except exception.NetworkNotFound as e:
except exception.StateInvalid as e:
return faults.Fault(faults.RequestedStateInvalid(e))
- def delete(self, req, tenant_id, network_id, id):
+ def delete(self, request, tenant_id, network_id, id):
""" Destroys the port with the given id """
#look for port state in request
try:
except exception.PortInUse as e:
return faults.Fault(faults.PortInUse(e))
- def get_resource(self,req,tenant_id, network_id, id):
+ def get_resource(self, request, tenant_id, network_id, id):
try:
result = self.network_manager.get_interface_details(
tenant_id, network_id, id)
return faults.Fault(faults.PortNotFound(e))
#TODO - Complete implementation of these APIs
- def attach_resource(self,req,tenant_id, network_id, id):
- content_type = req.best_match_content_type()
- print "Content type:%s" %content_type
+ def attach_resource(self, request, tenant_id, network_id, id):
+ content_type = request.best_match_content_type()
+ print "Content type:%s" % content_type
try:
- req_params = \
- self._parse_request_params(req,
+ request_params = \
+ self._parse_request_params(request,
self._attachment_ops_param_list)
except exc.HTTPError as e:
return faults.Fault(e)
try:
self.network_manager.plug_interface(tenant_id,
- network_id,id,
- req_params['attachment-id'])
+ network_id, id,
+ request_params['attachment-id'])
return exc.HTTPAccepted()
except exception.NetworkNotFound as e:
return faults.Fault(faults.NetworkNotFound(e))
return faults.Fault(faults.AlreadyAttached(e))
#TODO - Complete implementation of these APIs
- def detach_resource(self,req,tenant_id, network_id, id):
+ def detach_resource(self, request, tenant_id, network_id, id):
try:
self.network_manager.unplug_interface(tenant_id,
- network_id,id)
+ network_id, id)
return exc.HTTPAccepted()
except exception.NetworkNotFound as e:
return faults.Fault(faults.NetworkNotFound(e))
# 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: Somik Behera, Nicira Networks, Inc.
\ No newline at end of file
+# @author: Somik Behera, Nicira Networks, Inc.
def build(self, network_data, is_detail=False):
"""Generic method used to generate a network entity."""
- print "NETWORK-DATA:%s" %network_data
+ print "NETWORK-DATA:%s" % network_data
if is_detail:
network = self._build_detail(network_data)
else:
network = self._build_simple(network_data)
return network
-
+
def _build_simple(self, network_data):
"""Return a simple model of a server."""
return dict(network=dict(id=network_data['net-id']))
-
+
def _build_detail(self, network_data):
"""Return a simple model of a server."""
return dict(network=dict(id=network_data['net-id'],
def build(self, port_data, is_detail=False):
"""Generic method used to generate a port entity."""
- print "PORT-DATA:%s" %port_data
+ print "PORT-DATA:%s" % port_data
if is_detail:
port = self._build_detail(port_data)
else:
FORMAT = "json"
CONTENT_TYPE = "application/" + FORMAT
+
### --- Miniclient (taking from the test directory)
### TODO(bgh): move this to a library within quantum
class MiniClient(object):
"""A base client class - derived from Glance.BaseClient"""
action_prefix = '/v0.1/tenants/{tenant_id}'
+
def __init__(self, host, port, use_ssl):
self.host = host
self.port = port
self.use_ssl = use_ssl
self.connection = None
+
def get_connection_type(self):
if self.use_ssl:
return httplib.HTTPSConnection
else:
return httplib.HTTPConnection
+
def do_request(self, tenant, method, action, body=None,
headers=None, params=None):
action = MiniClient.action_prefix + action
- action = action.replace('{tenant_id}',tenant)
+ action = action.replace('{tenant_id}', tenant)
if type(params) is dict:
action += '?' + urllib.urlencode(params)
try:
raise Exception("Server returned error: %s" % res.read())
except (socket.error, IOError), e:
raise Exception("Unable to connect to server. Got error: %s" % e)
+
def get_status_code(self, response):
if hasattr(response, 'status_int'):
return response.status_int
### -- Core CLI functions
+
def list_nets(manager, *args):
tenant_id = args[0]
networks = manager.get_all_networks(tenant_id)
name = net["net-name"]
print "\tNetwork ID:%s \n\tNetwork Name:%s \n" % (id, name)
+
def api_list_nets(client, *args):
tenant_id = args[0]
res = client.do_request(tenant_id, 'GET', "/networks." + FORMAT)
# name = n["net-name"]
# LOG.info("\tNetwork ID:%s \n\tNetwork Name:%s \n" % (id, name))
+
def create_net(manager, *args):
tid, name = args
new_net_id = manager.create_network(tid, name)
print "Created a new Virtual Network with ID:%s\n" % new_net_id
+
def api_create_net(client, *args):
tid, name = args
data = {'network': {'network-name': '%s' % name}}
return
print "Created a new Virtual Network with ID:%s\n" % nid
+
def delete_net(manager, *args):
tid, nid = args
manager.delete_network(tid, nid)
print "Deleted Virtual Network with ID:%s" % nid
+
def api_delete_net(client, *args):
tid, nid = args
res = client.do_request(tid, 'DELETE', "/networks/" + nid + "." + FORMAT)
else:
print "Deleted Virtual Network with ID:%s" % nid
+
def detail_net(manager, *args):
tid, nid = args
iface_list = manager.get_network_details(tid, nid)
for iface in iface_list:
print "\tRemote interface:%s" % iface
+
def api_detail_net(client, *args):
tid, nid = args
res = client.do_request(tid, 'GET',
remote_iface = rd["attachment"]
print "\tRemote interface:%s" % remote_iface
+
def rename_net(manager, *args):
tid, nid, name = args
manager.rename_network(tid, nid, name)
print "Renamed Virtual Network with ID:%s" % nid
+
def api_rename_net(client, *args):
tid, nid, name = args
data = {'network': {'network-name': '%s' % name}}
LOG.debug(resdict)
print "Renamed Virtual Network with ID:%s" % nid
+
def list_ports(manager, *args):
tid, nid = args
ports = manager.get_all_ports(tid, nid)
for port in ports:
print "\tVirtual Port:%s" % port["port-id"]
+
def api_list_ports(client, *args):
tid, nid = args
res = client.do_request(tid, 'GET',
for port in rd["ports"]:
print "\tVirtual Port:%s" % port["id"]
+
def create_port(manager, *args):
tid, nid = args
new_port = manager.create_port(tid, nid)
print "Created Virtual Port:%s " \
"on Virtual Network:%s" % (new_port, nid)
+
def api_create_port(client, *args):
tid, nid = args
res = client.do_request(tid, 'POST',
print "Created Virtual Port:%s " \
"on Virtual Network:%s" % (new_port, nid)
+
def delete_port(manager, *args):
tid, nid, pid = args
LOG.info("Deleted Virtual Port:%s " \
"on Virtual Network:%s" % (pid, nid))
+
def api_delete_port(client, *args):
tid, nid, pid = args
res = client.do_request(tid, 'DELETE',
LOG.info("Deleted Virtual Port:%s " \
"on Virtual Network:%s" % (pid, nid))
+
def detail_port(manager, *args):
tid, nid, pid = args
port_detail = manager.get_port_details(tid, nid, pid)
print "Virtual Port:%s on Virtual Network:%s " \
"contains remote interface:%s" % (pid, nid, port_detail)
+
def api_detail_port(client, *args):
tid, nid, pid = args
res = client.do_request(tid, 'GET',
print "Virtual Port:%s on Virtual Network:%s " \
"contains remote interface:%s" % (pid, nid, attachment)
+
def plug_iface(manager, *args):
tid, nid, pid, vid = args
manager.plug_interface(tid, nid, pid, vid)
print "Plugged remote interface:%s " \
"into Virtual Network:%s" % (vid, nid)
+
def api_plug_iface(client, *args):
tid, nid, pid, vid = args
data = {'port': {'attachment-id': '%s' % vid}}
return
print "Plugged interface \"%s\" to port:%s on network:%s" % (vid, pid, nid)
-def unplug_iface(manager, *args):
+
+def unplug_iface(manager, *args):
tid, nid, pid = args
manager.unplug_interface(tid, nid, pid)
print "UnPlugged remote interface " \
"from Virtual Port:%s Virtual Network:%s" % (pid, nid)
+
def api_unplug_iface(client, *args):
tid, nid, pid = args
data = {'port': {'attachment-id': ''}}
return
print "Unplugged interface from port:%s on network:%s" % (pid, nid)
+
commands = {
"list_nets": {
"func": list_nets,
"api_func": api_list_nets,
- "args": ["tenant-id"]
- },
+ "args": ["tenant-id"]},
"create_net": {
"func": create_net,
"api_func": api_create_net,
- "args": ["tenant-id", "net-name"]
- },
+ "args": ["tenant-id", "net-name"]},
"delete_net": {
"func": delete_net,
"api_func": api_delete_net,
- "args": ["tenant-id", "net-id"]
- },
+ "args": ["tenant-id", "net-id"]},
"detail_net": {
"func": detail_net,
"api_func": api_detail_net,
- "args": ["tenant-id", "net-id"]
- },
+ "args": ["tenant-id", "net-id"]},
"rename_net": {
"func": rename_net,
"api_func": api_rename_net,
- "args": ["tenant-id", "net-id", "new-name"]
- },
+ "args": ["tenant-id", "net-id", "new-name"]},
"list_ports": {
"func": list_ports,
"api_func": api_list_ports,
- "args": ["tenant-id", "net-id"]
- },
+ "args": ["tenant-id", "net-id"]},
"create_port": {
"func": create_port,
"api_func": api_create_port,
- "args": ["tenant-id", "net-id"]
- },
+ "args": ["tenant-id", "net-id"]},
"delete_port": {
"func": delete_port,
"api_func": api_delete_port,
- "args": ["tenant-id", "net-id", "port-id"]
- },
+ "args": ["tenant-id", "net-id", "port-id"]},
"detail_port": {
"func": detail_port,
"api_func": api_detail_port,
- "args": ["tenant-id", "net-id", "port-id"]
- },
+ "args": ["tenant-id", "net-id", "port-id"]},
"plug_iface": {
"func": plug_iface,
"api_func": api_plug_iface,
- "args": ["tenant-id", "net-id", "port-id", "iface-id"]
- },
+ "args": ["tenant-id", "net-id", "port-id", "iface-id"]},
"unplug_iface": {
"func": unplug_iface,
"api_func": api_unplug_iface,
- "args": ["tenant-id", "net-id", "port-id"]
- },
- }
+ "args": ["tenant-id", "net-id", "port-id"]}, }
+
def help():
print "\nCommands:"
print " %s %s" % (k,
" ".join(["<%s>" % y for y in commands[k]["args"]]))
+
def build_args(cmd, cmdargs, arglist):
args = []
orig_arglist = arglist[:]
return None
return args
+
if __name__ == "__main__":
usagestr = "Usage: %prog [OPTIONS] <command> [args]"
parser = OptionParser(usage=usagestr)
LOG.debug("Executing command \"%s\" with args: %s" % (cmd, args))
if not options.load_plugin:
client = MiniClient(options.host, options.port, options.ssl)
- if not commands[cmd].has_key("api_func"):
+ if "api_func" not in commands[cmd]:
LOG.error("API version of \"%s\" is not yet implemented" % cmd)
sys.exit(1)
commands[cmd]["api_func"](client, *args)
from quantum.common import flags
from quantum.common import exceptions as exception
+from quantum.common import extensions
DEFAULT_LOG_FORMAT = "%(asctime)s %(levelname)8s [%(name)s] %(message)s"
DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
fix_path(os.path.join('~', '.quantum')),
fix_path('~'),
os.path.join(FLAGS.state_path, 'etc'),
- os.path.join(FLAGS.state_path, 'etc','quantum'),
+ os.path.join(FLAGS.state_path, 'etc', 'quantum'),
'/etc/quantum/',
'/etc']
for cfg_dir in config_file_dirs:
problem loading the configuration file.
"""
conf_file = find_config_file(options, args)
- print "Conf_file:%s" %conf_file
if not conf_file:
raise RuntimeError("Unable to locate any configuration file. "
"Cannot load application %s" % app_name)
try:
- print "App_name:%s" %app_name
conf = deploy.appconfig("config:%s" % conf_file, name=app_name)
return conf_file, conf
except Exception, e:
% (conf_file, e))
-def load_paste_app(conf_file, app_name):
+def load_paste_app(app_name, options, args):
"""
Builds and returns a WSGI app from a paste config file.
:raises RuntimeError when config file cannot be located or application
cannot be loaded from config file
"""
- #conf_file, conf = load_paste_config(app_name, options, args)
+ conf_file, conf = load_paste_config(app_name, options, args)
try:
- conf_file = os.path.abspath(conf_file)
app = deploy.loadapp("config:%s" % conf_file, name=app_name)
except (LookupError, ImportError), e:
raise RuntimeError("Unable to load %(app_name)s from "
"configuration file %(conf_file)s."
"\nGot: %(e)r" % locals())
- return app
+ return conf, app
def get_option(options, option, **kwargs):
class QuantumException(Exception):
"""Base Quantum Exception
-
+
Taken from nova.exception.NovaException
To correctly use this class, inherit from it and define
a 'message' property. That message will get printf'd
def __str__(self):
return self._error_string
+
class ProcessExecutionError(IOError):
def __init__(self, stdout=None, stderr=None, exit_code=None, cmd=None,
description=None):
class PortNotFound(NotFound):
message = _("Port %(port_id)s could not be found " \
"on network %(net_id)s")
-
+
class StateInvalid(QuantumException):
message = _("Unsupported port state: %(port_state)s")
-
+
class NetworkInUse(QuantumException):
message = _("Unable to complete operation on network %(net_id)s. " \
"for network %(net_id)s. The attachment '%(att_id)s" \
"is plugged into the logical port.")
+
class AlreadyAttached(QuantumException):
message = _("Unable to plug the attachment %(att_id)s into port " \
"%(port_id)s for network %(net_id)s. The attachment is " \
"already plugged into port %(att_port_id)s")
-
+
+
class Duplicate(Error):
pass
"""
import getopt
-import os
+import os
import string
import sys
DEFINE_string('state_path', os.path.join(os.path.dirname(__file__), '../../'),
"Top-level directory for maintaining quantum's state")
-
TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
FLAGS = flags.FLAGS
+
def int_from_bool_as_string(subject):
"""
Interpret a string as a boolean and return either 1 or 0.
def parse_isotime(timestr):
return datetime.datetime.strptime(timestr, TIME_FORMAT)
+
def getPluginFromConfig(file="config.ini"):
Config = ConfigParser.ConfigParser()
Config.read(file)
LOG = logging.getLogger('quantum.common.wsgi')
+
class WritableLogger(object):
"""A thin wrapper that responds to `write` and logs."""
"""
parts = self.path.rsplit('.', 1)
- LOG.debug("Request parts:%s",parts)
+ LOG.debug("Request parts:%s", parts)
if len(parts) > 1:
format = parts[1]
if format in ['json', 'xml']:
ctypes = ['application/json', 'application/xml']
bm = self.accept.best_match(ctypes)
- LOG.debug("BM:%s",bm)
+ LOG.debug("BM:%s", bm)
return bm or 'application/json'
def get_content_type(self):
arg_dict = req.environ['wsgiorg.routing_args'][1]
action = arg_dict['action']
method = getattr(self, action)
- LOG.debug("ARG_DICT:%s",arg_dict)
- LOG.debug("Action:%s",action)
- LOG.debug("Method:%s",method)
+ LOG.debug("ARG_DICT:%s", arg_dict)
+ LOG.debug("Action:%s", action)
+ LOG.debug("Method:%s", method)
LOG.debug("%s %s" % (req.method, req.url))
del arg_dict['controller']
del arg_dict['action']
if 'format' in arg_dict:
del arg_dict['format']
- arg_dict['req'] = req
+ arg_dict['request'] = req
result = method(**arg_dict)
if type(result) is dict:
content_type = req.best_match_content_type()
- LOG.debug("Content type:%s",content_type)
- LOG.debug("Result:%s",result)
+ LOG.debug("Content type:%s", content_type)
+ LOG.debug("Result:%s", result)
default_xmlns = self.get_default_xmlns(req)
body = self._serialize(result, content_type, default_xmlns)
xmlns = metadata.get('xmlns', None)
if xmlns:
result.setAttribute('xmlns', xmlns)
- LOG.debug("DATA:%s",data)
+ LOG.debug("DATA:%s", data)
if type(data) is list:
LOG.debug("TYPE IS LIST")
collections = metadata.get('list_collections', {})
result.appendChild(node)
else:
# Type is atom
- LOG.debug("TYPE IS ATOM:%s",data)
+ LOG.debug("TYPE IS ATOM:%s", data)
node = doc.createTextNode(str(data))
result.appendChild(node)
return result
-
_MAKER = None
BASE = models.BASE
+
def configure_db(options):
"""
Establish the database, create an engine if needed, and
pool_recycle=3600)
register_models()
+
def get_session(autocommit=True, expire_on_commit=False):
"""Helper method to grab session"""
global _MAKER, _ENGINE
expire_on_commit=expire_on_commit)
return _MAKER()
+
def register_models():
"""Register Models and create properties"""
global _ENGINE
assert _ENGINE
BASE.metadata.create_all(_ENGINE)
+
def unregister_models():
"""Unregister Models, useful clearing out data before testing"""
global _ENGINE
assert _ENGINE
BASE.metadata.drop_all(_ENGINE)
+
def network_create(tenant_id, name):
session = get_session()
net = None
session.flush()
return net
+
def network_list(tenant_id):
session = get_session()
return session.query(models.Network).\
filter_by(tenant_id=tenant_id).\
all()
+
def network_get(net_id):
session = get_session()
try:
except exc.NoResultFound:
raise Exception("No net found with id = %s" % net_id)
+
def network_rename(net_id, tenant_id, new_name):
session = get_session()
try:
return net
raise Exception("A network with name \"%s\" already exists" % new_name)
+
def network_destroy(net_id):
session = get_session()
try:
except exc.NoResultFound:
raise Exception("No network found with id = %s" % net_id)
+
def port_create(net_id):
session = get_session()
with session.begin():
session.flush()
return port
+
def port_list(net_id):
session = get_session()
return session.query(models.Port).\
filter_by(network_id=net_id).\
all()
+
def port_get(port_id):
session = get_session()
try:
except exc.NoResultFound:
raise Exception("No port found with id = %s " % port_id)
+
def port_set_attachment(port_id, new_interface_id):
session = get_session()
ports = None
session.flush()
return port
else:
- raise Exception("Port with attachment \"%s\" already exists" % (new_interface_id))
+ raise Exception("Port with attachment \"%s\" already exists"
+ % (new_interface_id))
+
def port_destroy(port_id):
session = get_session()
return port
except exc.NoResultFound:
raise Exception("No port found with id = %s " % port_id)
-
BASE = declarative_base()
+
class Port(BASE):
"""Represents a port on a quantum network"""
__tablename__ = 'ports'
uuid = Column(String(255), primary_key=True)
- network_id = Column(String(255), ForeignKey("networks.uuid"), nullable=False)
+ network_id = Column(String(255), ForeignKey("networks.uuid"),
+ nullable=False)
interface_id = Column(String(255))
def __init__(self, network_id):
self.network_id = network_id
def __repr__(self):
- return "<Port(%s,%s,%s)>" % (self.uuid, self.network_id, self.interface_id)
+ return "<Port(%s,%s,%s)>" % (self.uuid, self.network_id,
+ self.interface_id)
+
class Network(BASE):
"""Represents a quantum network"""
def __repr__(self):
return "<Network(%s,%s,%s)>" % \
- (self.uuid,self.name,self.tenant_id)
+ (self.uuid, self.name, self.tenant_id)
"""
-Quantum's Manager class is responsible for parsing a config file and instantiating the correct
-plugin that concretely implement quantum_plugin_base class
+Quantum's Manager class is responsible for parsing a config file and
+instantiating the correct plugin that concretely implement quantum_plugin_base
+class.
The caller should make sure that QuantumManager is a singleton.
"""
import gettext
+import os
gettext.install('quantum', unicode=1)
import os
CONFIG_FILE = "plugins.ini"
+
def find_config(basepath):
for root, dirs, files in os.walk(basepath):
if CONFIG_FILE in files:
return os.path.join(root, CONFIG_FILE)
return None
+
class QuantumManager(object):
def __init__(self, config=None):
if config == None:
- self.configuration_file = find_config(os.path.abspath(os.path.dirname(__file__)))
+ self.configuration_file = find_config(
+ os.path.abspath(os.path.dirname(__file__)))
else:
self.configuration_file = config
plugin_location = utils.getPluginFromConfig(self.configuration_file)
def get_manager(self):
return self.plugin
-
from quantum.common import exceptions as exc
+
class QuantumEchoPlugin(object):
"""
QuantumEchoPlugin is a demo plugin that doesn't
do anything but demonstrated the concept of a
concrete Quantum Plugin. Any call to this plugin
- will result in just a "print" to std. out with
+ will result in just a "print" to std. out with
the name of the method that was called.
"""
-
+
def get_all_networks(self, tenant_id):
"""
Returns a dictionary containing all
<network_uuid, network_name> for
- the specified tenant.
+ the specified tenant.
"""
print("get_all_networks() called\n")
-
-
+
def create_network(self, tenant_id, net_name):
"""
Creates a new Virtual Network, and assigns it
a symbolic name.
"""
print("create_network() called\n")
-
-
+
def delete_network(self, tenant_id, net_id):
"""
Deletes the network with the specified network identifier
"""
print("delete_network() called\n")
-
def get_network_details(self, tenant_id, net_id):
"""
Deletes the Virtual Network belonging to a the
spec
"""
print("get_network_details() called\n")
-
-
+
def rename_network(self, tenant_id, net_id, new_name):
"""
Updates the symbolic name belonging to a particular
Virtual Network.
"""
print("rename_network() called\n")
-
-
+
def get_all_ports(self, tenant_id, net_id):
"""
Retrieves all port identifiers belonging to the
specified Virtual Network.
"""
print("get_all_ports() called\n")
-
-
+
def create_port(self, tenant_id, net_id):
"""
Creates a port on the specified Virtual Network.
"""
print("create_port() called\n")
-
-
+
def delete_port(self, tenant_id, net_id, port_id):
"""
Deletes a port on a specified Virtual Network,
Updates the state of a port on the specified Virtual Network.
"""
print("update_port() called\n")
-
-
+
def get_port_details(self, tenant_id, net_id, port_id):
"""
This method allows the user to retrieve a remote interface
that is attached to this particular port.
"""
print("get_port_details() called\n")
-
-
+
def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id):
"""
Attaches a remote interface to the specified port on the
specified Virtual Network.
"""
print("plug_interface() called\n")
-
-
+
def unplug_interface(self, tenant_id, net_id, port_id):
"""
Detaches a remote interface from the specified port on the
hard-coded data structures to aid in quantum
client/cli development
"""
-
+
def get_all_networks(self, tenant_id):
"""
Returns a dictionary containing all
<network_uuid, network_name> for
- the specified tenant.
+ the specified tenant.
"""
- nets = {"001": "lNet1", "002": "lNet2" , "003": "lNet3"}
+ nets = {"001": "lNet1", "002": "lNet2", "003": "lNet3"}
print("get_all_networks() called\n")
return nets
-
-
+
def create_network(self, tenant_id, net_name):
"""
Creates a new Virtual Network, and assigns it
print("create_network() called\n")
# return network_id of the created network
return 101
-
-
+
def delete_network(self, tenant_id, net_id):
"""
Deletes the network with the specified network identifier
"""
print("delete_network() called\n")
-
def get_network_details(self, tenant_id, net_id):
"""
retrieved a list of all the remote vifs that
print("get_network_details() called\n")
vifs_on_net = ["/tenant1/networks/net_id/portid/vif2.0"]
return vifs_on_net
-
-
+
def rename_network(self, tenant_id, net_id, new_name):
"""
Updates the symbolic name belonging to a particular
Virtual Network.
"""
print("rename_network() called\n")
-
-
+
def get_all_ports(self, tenant_id, net_id):
"""
Retrieves all port identifiers belonging to the
print("get_all_ports() called\n")
port_ids_on_net = ["2", "3", "4"]
return port_ids_on_net
-
-
+
def create_port(self, tenant_id, net_id):
"""
Creates a port on the specified Virtual Network.
Updates the state of a port on the specified Virtual Network.
"""
print("update_port() called\n")
-
-
+
def delete_port(self, tenant_id, net_id, port_id):
"""
Deletes a port on a specified Virtual Network,
is deleted.
"""
print("delete_port() called\n")
-
-
+
def get_port_details(self, tenant_id, net_id, port_id):
"""
This method allows the user to retrieve a remote interface
print("get_port_details() called\n")
#returns the remote interface UUID
return "/tenant1/networks/net_id/portid/vif2.1"
-
-
+
def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id):
"""
Attaches a remote interface to the specified port on the
specified Virtual Network.
"""
print("plug_interface() called\n")
-
-
+
def unplug_interface(self, tenant_id, net_id, port_id):
"""
Detaches a remote interface from the specified port on the
specified Virtual Network.
"""
print("unplug_interface() called\n")
-
-
+
+
class FakePlugin(object):
"""
FakePlugin is a demo plugin that provides
#static data for networks and ports
_port_dict_1 = {
- 1 : {'port-id': 1,
+ 1: {'port-id': 1,
'port-state': 'DOWN',
'attachment': None},
- 2 : {'port-id': 2,
- 'port-state':'UP',
- 'attachment': None}
- }
+ 2: {'port-id': 2,
+ 'port-state': 'UP',
+ 'attachment': None}}
_port_dict_2 = {
- 1 : {'port-id': 1,
+ 1: {'port-id': 1,
'port-state': 'UP',
'attachment': 'SomeFormOfVIFID'},
- 2 : {'port-id': 2,
- 'port-state':'DOWN',
- 'attachment': None}
- }
- _networks={'001':
+ 2: {'port-id': 2,
+ 'port-state': 'DOWN',
+ 'attachment': None}}
+ _networks = {'001':
{
- 'net-id':'001',
- 'net-name':'pippotest',
- 'net-ports': _port_dict_1
- },
+ 'net-id': '001',
+ 'net-name': 'pippotest',
+ 'net-ports': _port_dict_1},
'002':
{
- 'net-id':'002',
- 'net-name':'cicciotest',
- 'net-ports': _port_dict_2
- }}
-
-
+ 'net-id': '002',
+ 'net-name': 'cicciotest',
+ 'net-ports': _port_dict_2}}
+
def __init__(self):
- FakePlugin._net_counter=len(FakePlugin._networks)
-
+ FakePlugin._net_counter = len(FakePlugin._networks)
+
def _get_network(self, tenant_id, network_id):
network = FakePlugin._networks.get(network_id)
if not network:
raise exc.NetworkNotFound(net_id=network_id)
return network
-
def _get_port(self, tenant_id, network_id, port_id):
net = self._get_network(tenant_id, network_id)
port = net['net-ports'].get(int(port_id))
if not port:
raise exc.PortNotFound(net_id=network_id, port_id=port_id)
return port
-
+
def _validate_port_state(self, port_state):
- if port_state.upper() not in ('UP','DOWN'):
+ if port_state.upper() not in ('UP', 'DOWN'):
raise exc.StateInvalid(port_state=port_state)
return True
-
+
def _validate_attachment(self, tenant_id, network_id, port_id,
remote_interface_id):
network = self._get_network(tenant_id, network_id)
for port in network['net-ports'].values():
if port['attachment'] == remote_interface_id:
- raise exc.AlreadyAttached(net_id = network_id,
- port_id = port_id,
- att_id = port['attachment'],
- att_port_id = port['port-id'])
-
+ raise exc.AlreadyAttached(net_id=network_id,
+ port_id=port_id,
+ att_id=port['attachment'],
+ att_port_id=port['port-id'])
+
def get_all_networks(self, tenant_id):
"""
Returns a dictionary containing all
<network_uuid, network_name> for
- the specified tenant.
+ the specified tenant.
"""
print("get_all_networks() called\n")
return FakePlugin._networks.values()
"""
print("create_network() called\n")
FakePlugin._net_counter += 1
- new_net_id=("0" * (3 - len(str(FakePlugin._net_counter)))) + \
+ new_net_id = ("0" * (3 - len(str(FakePlugin._net_counter)))) + \
str(FakePlugin._net_counter)
print new_net_id
- new_net_dict={'net-id':new_net_id,
- 'net-name':net_name,
+ new_net_dict = {'net-id': new_net_id,
+ 'net-name': net_name,
'net-ports': {}}
- FakePlugin._networks[new_net_id]=new_net_dict
+ FakePlugin._networks[new_net_id] = new_net_dict
# return network_id of the created network
return new_net_dict
-
+
def delete_network(self, tenant_id, net_id):
"""
Deletes the network with the specified network identifier
return net
# Network not found
raise exc.NetworkNotFound(net_id=net_id)
-
+
def rename_network(self, tenant_id, net_id, new_name):
"""
Updates the symbolic name belonging to a particular
"""
print("rename_network() called\n")
net = self._get_network(tenant_id, net_id)
- net['net-name']=new_name
+ net['net-name'] = new_name
return net
def get_all_ports(self, tenant_id, net_id):
"""
print("get_port_details() called\n")
return self._get_port(tenant_id, net_id, port_id)
-
+
def create_port(self, tenant_id, net_id, port_state=None):
"""
Creates a port on the specified Virtual Network.
print("create_port() called\n")
net = self._get_network(tenant_id, net_id)
# check port state
- # TODO(salvatore-orlando): Validate port state in API?
+ # TODO(salvatore-orlando): Validate port state in API?
self._validate_port_state(port_state)
ports = net['net-ports']
- new_port_id = max(ports.keys())+1
- new_port_dict = {'port-id':new_port_id,
+ new_port_id = max(ports.keys()) + 1
+ new_port_dict = {'port-id': new_port_id,
'port-state': port_state,
'attachment': None}
ports[new_port_id] = new_port_dict
- return new_port_dict
+ return new_port_dict
def update_port(self, tenant_id, net_id, port_id, port_state):
"""
port = self._get_port(tenant_id, net_id, port_id)
self._validate_port_state(port_state)
port['port-state'] = port_state
- return port
-
+ return port
+
def delete_port(self, tenant_id, net_id, port_id):
"""
Deletes a port on a specified Virtual Network,
net = self._get_network(tenant_id, net_id)
port = self._get_port(tenant_id, net_id, port_id)
if port['attachment']:
- raise exc.PortInUse(net_id=net_id,port_id=port_id,
+ raise exc.PortInUse(net_id=net_id, port_id=port_id,
att_id=port['attachment'])
try:
net['net-ports'].pop(int(port_id))
- except KeyError:
+ except KeyError:
raise exc.PortNotFound(net_id=net_id, port_id=port_id)
-
def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id):
"""
Attaches a remote interface to the specified port on the
remote_interface_id)
port = self._get_port(tenant_id, net_id, port_id)
if port['attachment']:
- raise exc.PortInUse(net_id=net_id,port_id=port_id,
+ raise exc.PortInUse(net_id=net_id, port_id=port_id,
att_id=port['attachment'])
port['attachment'] = remote_interface_id
-
+
def unplug_interface(self, tenant_id, net_id, port_id):
"""
Detaches a remote interface from the specified port on the
# TODO(salvatore-orlando):
# Should unplug on port without attachment raise an Error?
port['attachment'] = None
-
-
\ No newline at end of file
# 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: Somik Behera, Nicira Networks, Inc.
\ No newline at end of file
+# @author: Somik Behera, Nicira Networks, Inc.
from optparse import OptionParser
from subprocess import *
+
# A class to represent a VIF (i.e., a port that has 'iface-id' and 'vif-mac'
# attributes set).
class VifPort:
self.vif_id = vif_id
self.vif_mac = vif_mac
self.switch = switch
+
def __str__(self):
return "iface-id=" + self.vif_id + ", vif_mac=" + \
self.vif_mac + ", port_name=" + self.port_name + \
", ofport=" + self.ofport + ", bridge name = " + self.switch.br_name
+
class OVSBridge:
def __init__(self, br_name):
self.br_name = br_name
return Popen(args, stdout=PIPE).communicate()[0]
def run_vsctl(self, args):
- full_args = ["ovs-vsctl" ] + args
+ full_args = ["ovs-vsctl"] + args
return self.run_cmd(full_args)
def reset_bridge(self):
- self.run_vsctl([ "--" , "--if-exists", "del-br", self.br_name])
+ self.run_vsctl(["--", "--if-exists", "del-br", self.br_name])
self.run_vsctl(["add-br", self.br_name])
def delete_port(self, port_name):
- self.run_vsctl([ "--" , "--if-exists", "del-port", self.br_name,
+ self.run_vsctl(["--", "--if-exists", "del-port", self.br_name,
port_name])
def set_db_attribute(self, table_name, record, column, value):
- args = [ "set", table_name, record, "%s=%s" % (column,value) ]
+ args = ["set", table_name, record, "%s=%s" % (column, value)]
self.run_vsctl(args)
- def clear_db_attribute(self, table_name,record, column):
- args = [ "clear", table_name, record, column ]
+ def clear_db_attribute(self, table_name, record, column):
+ args = ["clear", table_name, record, column]
self.run_vsctl(args)
def run_ofctl(self, cmd, args):
- full_args = ["ovs-ofctl", cmd, self.br_name ] + args
+ full_args = ["ovs-ofctl", cmd, self.br_name] + args
return self.run_cmd(full_args)
def remove_all_flows(self):
def get_port_ofport(self, port_name):
return self.db_get_val("Interface", port_name, "ofport")
- def add_flow(self,**dict):
+ def add_flow(self, **dict):
if "actions" not in dict:
raise Exception("must specify one or more actions")
if "priority" not in dict:
if "match" in dict:
flow_str += "," + dict["match"]
flow_str += ",actions=%s" % (dict["actions"])
- self.run_ofctl("add-flow", [ flow_str ] )
+ self.run_ofctl("add-flow", [flow_str])
- def delete_flows(self,**dict):
+ def delete_flows(self, **dict):
all_args = []
if "priority" in dict:
all_args.append("priority=%s" % dict["priority"])
if "actions" in dict:
all_args.append("actions=%s" % (dict["actions"]))
flow_str = ",".join(all_args)
- self.run_ofctl("del-flows", [ flow_str ] )
+ self.run_ofctl("del-flows", [flow_str])
def db_get_map(self, table, record, column):
- str = self.run_vsctl([ "get" , table, record, column ]).rstrip("\n\r")
+ str = self.run_vsctl(["get", table, record, column]).rstrip("\n\r")
return self.db_str_to_map(str)
def db_get_val(self, table, record, column):
- return self.run_vsctl([ "get" , table, record, column ]).rstrip("\n\r")
+ return self.run_vsctl(["get", table, record, column]).rstrip("\n\r")
def db_str_to_map(self, full_str):
list = full_str.strip("{}").split(", ")
return ret
def get_port_name_list(self):
- res = self.run_vsctl([ "list-ports", self.br_name])
+ res = self.run_vsctl(["list-ports", self.br_name])
return res.split("\n")[0:-1]
def get_port_stats(self, port_name):
edge_ports = []
port_names = self.get_port_name_list()
for name in port_names:
- external_ids = self.db_get_map("Interface",name,"external_ids")
+ external_ids = self.db_get_map("Interface", name, "external_ids")
if "iface-id" in external_ids and "attached-mac" in external_ids:
- ofport = self.db_get_val("Interface",name,"ofport")
+ ofport = self.db_get_val("Interface", name, "ofport")
p = VifPort(name, ofport, external_ids["iface-id"],
external_ids["attached-mac"], self)
edge_ports.append(p)
else:
# iface-id might not be set. See if we can figure it out and
# set it here.
- external_ids = self.db_get_map("Interface",name,"external_ids")
+ external_ids = self.db_get_map("Interface", name,
+ "external_ids")
if "attached-mac" not in external_ids:
continue
vif_uuid = external_ids.get("xs-vif-uuid", "")
if len(vif_uuid) == 0:
continue
LOG.debug("iface-id not set, got vif-uuid: %s" % vif_uuid)
- res = os.popen("xe vif-param-get param-name=other-config uuid=%s | grep nicira-iface-id | awk '{print $2}'" % vif_uuid).readline()
+ res = os.popen("xe vif-param-get param-name=other-config "
+ "uuid=%s | grep nicira-iface-id | "
+ "awk '{print $2}'"
+ % vif_uuid).readline()
res = res.strip()
if len(res) == 0:
continue
external_ids["iface-id"] = res
- LOG.info("Setting interface \"%s\" iface-id to \"%s\"" % (name, res))
+ LOG.info("Setting interface \"%s\" iface-id to \"%s\""
+ % (name, res))
self.set_db_attribute("Interface", name,
- "external-ids:iface-id", res)
- ofport = self.db_get_val("Interface",name,"ofport")
+ "external-ids:iface-id", res)
+ ofport = self.db_get_val("Interface", name, "ofport")
p = VifPort(name, ofport, external_ids["iface-id"],
- external_ids["attached-mac"], self)
+ external_ids["attached-mac"], self)
edge_ports.append(p)
return edge_ports
+
class OVSNaaSPlugin:
def __init__(self, integ_br):
self.setup_integration_br(integ_br)
def port_bound(self, port, vlan_id):
- self.int_br.set_db_attribute("Port", port.port_name,"tag",
+ self.int_br.set_db_attribute("Port", port.port_name, "tag",
str(vlan_id))
def port_unbound(self, port, still_exists):
if still_exists:
- self.int_br.clear_db_attribute("Port", port.port_name,"tag")
+ self.int_br.clear_db_attribute("Port", port.port_name, "tag")
def setup_integration_br(self, integ_br):
self.int_br = OVSBridge(integ_br)
# switch all other traffic using L2 learning
self.int_br.add_flow(priority=1, actions="normal")
# FIXME send broadcast everywhere, regardless of tenant
- #int_br.add_flow(priority=3, match="dl_dst=ff:ff:ff:ff:ff:ff", actions="normal")
+ #int_br.add_flow(priority=3, match="dl_dst=ff:ff:ff:ff:ff:ff",
+ # actions="normal")
def daemon_loop(self, conn):
self.local_vlan_map = {}
else:
# no binding, put him on the 'dead vlan'
self.int_br.set_db_attribute("Port", p.port_name, "tag",
- "4095")
- old_b = old_local_bindings.get(p.vif_id,None)
- new_b = new_local_bindings.get(p.vif_id,None)
+ "4095")
+ old_b = old_local_bindings.get(p.vif_id, None)
+ new_b = new_local_bindings.get(p.vif_id, None)
if old_b != new_b:
if old_b is not None:
LOG.info("Removing binding to net-id = %s for %s"
import quantum.db.models as models
import ovs_models
+
def get_vlans():
session = db.get_session()
try:
return []
res = []
for x in bindings:
- res.append((x.vlan_id, x.network_id))
+ res.append((x.vlan_id, x.network_id))
return res
+
def add_vlan_binding(vlanid, netid):
session = db.get_session()
binding = ovs_models.VlanBinding(vlanid, netid)
session.flush()
return binding.vlan_id
+
def remove_vlan_binding(netid):
session = db.get_session()
try:
pass
session.flush()
+
def update_network_binding(netid, ifaceid):
session = db.get_session()
# Add to or delete from the bindings table
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relation
-
from quantum.db.models import BASE
+
class NetworkBinding(BASE):
"""Represents a binding of network_id, vif_id"""
__tablename__ = 'network_bindings'
return "<NetworkBinding(%s,%s)>" % \
(self.network_id, self.vif_id)
+
class VlanBinding(BASE):
"""Represents a binding of network_id, vlan_id"""
__tablename__ = 'vlan_bindings'
import quantum.db.api as db
import ovs_db
-CONF_FILE="ovs_quantum_plugin.ini"
+CONF_FILE = "ovs_quantum_plugin.ini"
LOG.basicConfig(level=LOG.WARN)
LOG.getLogger("ovs_quantum_plugin")
+
def find_config(basepath):
for root, dirs, files in os.walk(basepath):
if CONF_FILE in files:
return os.path.join(root, CONF_FILE)
return None
+
class VlanMap(object):
vlans = {}
+
def __init__(self):
for x in xrange(2, 4094):
self.vlans[x] = None
+
def set(self, vlan_id, network_id):
self.vlans[vlan_id] = network_id
+
def acquire(self, network_id):
for x in xrange(2, 4094):
if self.vlans[x] == None:
# LOG.debug("VlanMap::acquire %s -> %s" % (x, network_id))
return x
raise Exception("No free vlans..")
+
def get(self, vlan_id):
return self.vlans[vlan_id]
+
def release(self, network_id):
for x in self.vlans.keys():
if self.vlans[x] == network_id:
return
LOG.error("No vlan found with network \"%s\"" % network_id)
+
class OVSQuantumPlugin(QuantumPluginBase):
+
def __init__(self, configfile=None):
config = ConfigParser.ConfigParser()
if configfile == None:
if os.path.exists(CONF_FILE):
configfile = CONF_FILE
else:
- configfile = find_config(os.path.abspath(os.path.dirname(__file__)))
+ configfile = find_config(os.path.abspath(
+ os.path.dirname(__file__)))
if configfile == None:
raise Exception("Configuration file \"%s\" doesn't exist" %
(configfile))
vlans = ovs_db.get_vlans()
for x in vlans:
vlan_id, network_id = x
- # LOG.debug("Adding already populated vlan %s -> %s" % (vlan_id, network_id))
+ # LOG.debug("Adding already populated vlan %s -> %s"
+ # % (vlan_id, network_id))
self.vmap.set(vlan_id, network_id)
def get_all_networks(self, tenant_id):
def create_network(self, tenant_id, net_name):
d = {}
try:
- res = db.network_create(tenant_id, net_name)
- LOG.debug("Created newtork: %s" % res)
+ res = db.network_create(tenant_id, net_name)
+ LOG.debug("Created newtork: %s" % res)
except Exception, e:
LOG.error("Error: %s" % str(e))
return d
res = db.port_get(port_id)
return res.interface_id
+
class VlanMapTest(unittest.TestCase):
+
def setUp(self):
self.vmap = VlanMap()
+
def tearDown(self):
pass
+
def testAddVlan(self):
vlan_id = self.vmap.acquire("foobar")
self.assertTrue(vlan_id == 2)
+
def testReleaseVlan(self):
vlan_id = self.vmap.acquire("foobar")
self.vmap.release("foobar")
self.assertTrue(self.vmap.get(vlan_id) == None)
+
# TODO(bgh): Make the tests use a sqlite database instead of mysql
class OVSPluginTest(unittest.TestCase):
+
def setUp(self):
self.quantum = OVSQuantumPlugin()
self.tenant_id = "testtenant"
self.quantum.delete_port(self.tenant_id, id, p["port-id"])
self.quantum.delete_network(self.tenant_id, id)
+
if __name__ == "__main__":
usagestr = "Usage: %prog [OPTIONS] <command> [args]"
parser = OptionParser(usage=usagestr)
import socket
import urllib
+
class MiniClient(object):
"""A base client class - derived from Glance.BaseClient"""
def do_request(self, tenant, method, action, body=None,
headers=None, params=None):
"""
- Connects to the server and issues a request.
+ Connects to the server and issues a request.
Returns the result data, or raises an appropriate exception if
HTTP status code is not 2xx
"""
action = MiniClient.action_prefix + action
- action = action.replace('{tenant_id}',tenant)
+ action = action.replace('{tenant_id}', tenant)
if type(params) is dict:
action += '?' + urllib.urlencode(params)
try:
connection_type = self.get_connection_type()
headers = headers or {}
-
+
# Open connection and send request
c = connection_type(self.host, self.port)
c.request(method, action, body, headers)
if hasattr(response, 'status_int'):
return response.status_int
else:
- return response.status
\ No newline at end of file
+ return response.status
FORMAT = "json"
test_network1_data = \
- {'network': {'network-name': 'test1' }}
+ {'network': {'network-name': 'test1'}}
test_network2_data = \
- {'network': {'network-name': 'test2' }}
+ {'network': {'network-name': 'test2'}}
+
def print_response(res):
content = res.read()
- print "Status: %s" %res.status
- print "Content: %s" %content
+ print "Status: %s" % res.status
+ print "Content: %s" % content
return content
+
class QuantumTest(unittest.TestCase):
def setUp(self):
self.client = MiniClient(HOST, PORT, USE_SSL)
def test_listNetworks(self):
self.create_network(test_network1_data)
self.create_network(test_network2_data)
- res = self.client.do_request(TENANT_ID,'GET', "/networks." + FORMAT)
+ res = self.client.do_request(TENANT_ID, 'GET', "/networks." + FORMAT)
self.assertEqual(res.status, 200, "bad response: %s" % res.read())
def test_createNetwork(self):
resdict = simplejson.loads(res.read())
self.assertTrue(resdict["networks"]["network"]["id"] == net_id,
"Network_rename: renamed network has a different uuid")
- self.assertTrue(resdict["networks"]["network"]["name"] == "test_renamed",
- "Network rename didn't take effect")
+ self.assertTrue(
+ resdict["networks"]["network"]["name"] == "test_renamed",
+ "Network rename didn't take effect")
def delete_networks(self):
# Remove all the networks created on the tenant