From d83afeccf1c0c055f783c63f641ac9bbcacf6e90 Mon Sep 17 00:00:00 2001 From: Dan Wendlandt Date: Sun, 31 Jul 2011 23:21:11 -0700 Subject: [PATCH] bug802772 update exception handling in OVS plugin to use API exceptions. --- quantum/db/api.py | 97 +++++++++++----- quantum/plugins/SamplePlugin.py | 10 +- .../plugins/openvswitch/ovs_quantum_plugin.py | 109 ++++++++---------- 3 files changed, 121 insertions(+), 95 deletions(-) diff --git a/quantum/db/api.py b/quantum/db/api.py index 6813d2096..0c42bda3d 100644 --- a/quantum/db/api.py +++ b/quantum/db/api.py @@ -20,6 +20,7 @@ from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker, exc +from quantum.common import exceptions as q_exc from quantum.db import models _ENGINE = None @@ -105,8 +106,8 @@ def network_get(net_id): return session.query(models.Network).\ filter_by(uuid=net_id).\ one() - except exc.NoResultFound: - raise Exception("No net found with id = %s" % net_id) + except exc.NoResultFound, e: + raise q_exc.NetworkNotFound(net_id=net_id) def network_rename(net_id, tenant_id, new_name): @@ -115,6 +116,8 @@ def network_rename(net_id, tenant_id, new_name): res = session.query(models.Network).\ filter_by(tenant_id=tenant_id, name=new_name).\ one() + if not res: + raise exc.NetworkNotFound(net_id=net_id) except exc.NoResultFound: net = network_get(net_id) net.name = new_name @@ -134,10 +137,13 @@ def network_destroy(net_id): session.flush() return net except exc.NoResultFound: - raise Exception("No network found with id = %s" % net_id) + raise q_exc.NetworkNotFound(net_id=net_id) def port_create(net_id, state=None): + # confirm network exists + network_get(net_id) + session = get_session() with session.begin(): port = models.Port(net_id) @@ -154,63 +160,90 @@ def port_list(net_id): all() -def port_get(port_id): +def port_get(port_id, net_id): + # confirm network exists + network_get(net_id) session = get_session() try: return session.query(models.Port).\ filter_by(uuid=port_id).\ + filter_by(network_id=net_id).\ one() except exc.NoResultFound: - raise Exception("No port found with id = %s " % port_id) + raise q_exc.PortNotFound(net_id=net_id, port_id=port_id) -def port_set_state(port_id, new_state): - port = port_get(port_id) - if port: - session = get_session() - port.state = new_state - session.merge(port) - session.flush() - return port +def port_set_state(port_id, net_id, new_state): + if new_state not in ('ACTIVE', 'DOWN'): + raise q_exc.StateInvalid(port_state=new_state) + + # confirm network exists + network_get(net_id) + + port = port_get(port_id, net_id) + session = get_session() + port.state = new_state + session.merge(port) + session.flush() + return port -def port_set_attachment(port_id, new_interface_id): +def port_set_attachment(port_id, net_id, new_interface_id): + # confirm network exists + network_get(net_id) + session = get_session() - ports = [] + port = port_get(port_id, net_id) + if new_interface_id != "": + # We are setting, not clearing, the attachment-id + if port['interface_id']: + raise q_exc.PortInUse(net_id=net_id, port_id=port_id, + att_id=port['interface_id']) + try: - ports = session.query(models.Port).\ + port = session.query(models.Port).\ filter_by(interface_id=new_interface_id).\ - all() + one() + raise q_exc.AlreadyAttached(net_id=net_id, + port_id=port_id, + att_id=new_interface_id, + att_port_id=port['uuid']) except exc.NoResultFound: + # this is what should happen pass - if len(ports) == 0: - port = port_get(port_id) - port.interface_id = new_interface_id - session.merge(port) - session.flush() - return port - else: - raise Exception("Port with attachment \"%s\" already exists" - % (new_interface_id)) + port.interface_id = new_interface_id + session.merge(port) + session.flush() + return port -def port_unset_attachment(port_id): +def port_unset_attachment(port_id, net_id): + # confirm network exists + network_get(net_id) + session = get_session() - port = port_get(port_id) + port = port_get(port_id, net_id) port.interface_id = None session.merge(port) session.flush -def port_destroy(port_id): +def port_destroy(port_id, net_id): + # confirm network exists + network_get(net_id) + session = get_session() try: port = session.query(models.Port).\ - filter_by(uuid=port_id).\ - one() + filter_by(uuid=port_id).\ + filter_by(network_id=net_id).\ + one() + if port['interface_id']: + raise q_exc.PortInUse(net_id=net_id, port_id=port_id, + att_id=port['interface_id']) session.delete(port) session.flush() return port except exc.NoResultFound: - raise Exception("No port found with id = %s " % port_id) + raise q_exc.PortNotFound(port_id=port_id) diff --git a/quantum/plugins/SamplePlugin.py b/quantum/plugins/SamplePlugin.py index 34573d2fe..f4aefac0a 100644 --- a/quantum/plugins/SamplePlugin.py +++ b/quantum/plugins/SamplePlugin.py @@ -240,7 +240,7 @@ class FakePlugin(object): def _get_port(self, tenant_id, network_id, port_id): net = self._get_network(tenant_id, network_id) try: - port = db.port_get(port_id) + port = db.port_get(port_id, network_id) except: raise exc.PortNotFound(net_id=network_id, port_id=port_id) # Port must exist and belong to the appropriate network. @@ -373,7 +373,7 @@ class FakePlugin(object): self._get_network(tenant_id, net_id) self._get_port(tenant_id, net_id, port_id) self._validate_port_state(new_state) - db.port_set_state(port_id, new_state) + db.port_set_state(port_id, net_id, new_state) port_item = {'port-id': port_id, 'port-state': new_state} return port_item @@ -392,7 +392,7 @@ class FakePlugin(object): raise exc.PortInUse(net_id=net_id, port_id=port_id, att_id=port['interface_id']) try: - port = db.port_destroy(port_id) + port = db.port_destroy(port_id, net_id) except Exception, e: raise Exception("Failed to delete port: %s" % str(e)) d = {} @@ -412,7 +412,7 @@ class FakePlugin(object): if port['interface_id']: raise exc.PortInUse(net_id=net_id, port_id=port_id, att_id=port['interface_id']) - db.port_set_attachment(port_id, remote_interface_id) + db.port_set_attachment(port_id, net_id, remote_interface_id) def unplug_interface(self, tenant_id, net_id, port_id): """ @@ -423,4 +423,4 @@ class FakePlugin(object): self._get_port(tenant_id, net_id, port_id) # TODO(salvatore-orlando): # Should unplug on port without attachment raise an Error? - db.port_unset_attachment(port_id) + db.port_unset_attachment(port_id, net_id) diff --git a/quantum/plugins/openvswitch/ovs_quantum_plugin.py b/quantum/plugins/openvswitch/ovs_quantum_plugin.py index 2f23517ec..3d49f62e8 100644 --- a/quantum/plugins/openvswitch/ovs_quantum_plugin.py +++ b/quantum/plugins/openvswitch/ovs_quantum_plugin.py @@ -19,12 +19,13 @@ import ConfigParser import logging as LOG +from optparse import OptionParser import os import sys import unittest +from quantum.common import exceptions as q_exc from quantum.quantum_plugin_base import QuantumPluginBase -from optparse import OptionParser import quantum.db.api as db import ovs_db @@ -111,101 +112,93 @@ class OVSQuantumPlugin(QuantumPluginBase): nets = [] for x in db.network_list(tenant_id): LOG.debug("Adding network: %s" % x.uuid) - d = {} - d["net-id"] = str(x.uuid) - d["net-name"] = x.name - nets.append(d) + nets.append(self._make_net_dict(str(x.uuid), x.name, None)) return nets + def _make_net_dict(self, net_id, net_name, ports): + res = {'net-id': net_id, + 'net-name': net_name} + if ports: + res['net-ports'] = ports + return res + def create_network(self, tenant_id, net_name): - d = {} - try: - 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 - d["net-id"] = str(res.uuid) - d["net-name"] = res.name - vlan_id = self.vmap.acquire(str(res.uuid)) - ovs_db.add_vlan_binding(vlan_id, str(res.uuid)) - return d + net = db.network_create(tenant_id, net_name) + LOG.debug("Created network: %s" % net) + vlan_id = self.vmap.acquire(str(net.uuid)) + ovs_db.add_vlan_binding(vlan_id, str(net.uuid)) + return self._make_net_dict(str(net.uuid), net.name, []) def delete_network(self, tenant_id, net_id): + net = db.network_get(net_id) + + # Verify that no attachments are plugged into the network + for port in db.port_list(net_id): + if port['interface_id']: + raise q_exc.NetworkInUse(net_id=net_id) net = db.network_destroy(net_id) - d = {} - d["net-id"] = str(net.uuid) ovs_db.remove_vlan_binding(net_id) self.vmap.release(net_id) - return d + return self._make_net_dict(str(net.uuid), net.name, []) def get_network_details(self, tenant_id, net_id): - ports = db.port_list(net_id) - ifaces = [] - for p in ports: - ifaces.append(p.interface_id) - return ifaces + net = db.network_get(net_id) + ports = self.get_all_ports(tenant_id, net_id) + return self._make_net_dict(str(net.uuid), net.name, ports) def rename_network(self, tenant_id, net_id, new_name): - try: - net = db.network_rename(net_id, tenant_id, new_name) - except Exception, e: - raise Exception("Failed to rename network: %s" % str(e)) - d = {} - d["net-id"] = str(net.uuid) - d["net-name"] = net.name - return d + net = db.network_rename(net_id, tenant_id, new_name) + return self._make_net_dict(str(net.uuid), net.name, None) + + def _make_port_dict(self, port_id, port_state, net_id, attachment): + res = {'port-id': port_id, + 'port-state': port_state} + if net_id: + res['net-id'] = net_id + if attachment: + res['attachment-id'] = attachment + return res def get_all_ports(self, tenant_id, net_id): ids = [] ports = db.port_list(net_id) - for x in ports: - LOG.debug("Appending port: %s" % x.uuid) - d = {} - d["port-id"] = str(x.uuid) + for p in ports: + LOG.debug("Appending port: %s" % p.uuid) + d = self._make_port_dict(str(p.uuid), "ACTIVE", None, None) ids.append(d) return ids def create_port(self, tenant_id, net_id, port_state=None): LOG.debug("Creating port with network_id: %s" % net_id) port = db.port_create(net_id) - d = {} - d["port-id"] = str(port.uuid) - LOG.debug("-> %s" % (port.uuid)) - return d + return self._make_port_dict(str(port.uuid), "ACTIVE", None, None) def delete_port(self, tenant_id, net_id, port_id): - try: - port = db.port_destroy(port_id) - except Exception, e: - raise Exception("Failed to delete port: %s" % str(e)) - d = {} - d["port-id"] = str(port.uuid) - return d + port = db.port_destroy(port_id, net_id) + return self._make_port_dict(str(port.uuid), "ACTIVE", None, None) def update_port(self, tenant_id, net_id, port_id, port_state): """ Updates the state of a port on the specified Virtual Network. """ LOG.debug("update_port() called\n") - port = db.port_get(port_id) - port['port-state'] = port_state - return port + port = db.port_get(port_id, net_id) + db.port_set_state(port_id, net_id, port_state) + return self._make_port_dict(str(port.uuid), "ACTIVE", None, None) def get_port_details(self, tenant_id, net_id, port_id): - port = db.port_get(port_id) - rv = {"port-id": port.uuid, "attachment": port.interface_id, - "net-id": port.network_id, "port-state": "UP"} - return rv + port = db.port_get(port_id, net_id) + return self._make_port_dict(str(port.uuid), "ACTIVE", + port.network_id, port.interface_id) def plug_interface(self, tenant_id, net_id, port_id, remote_iface_id): - db.port_set_attachment(port_id, remote_iface_id) + db.port_set_attachment(port_id, net_id, remote_iface_id) def unplug_interface(self, tenant_id, net_id, port_id): - db.port_set_attachment(port_id, "") + db.port_set_attachment(port_id, net_id, "") def get_interface_details(self, tenant_id, net_id, port_id): - res = db.port_get(port_id) + res = db.port_get(port_id, net_id) return res.interface_id -- 2.45.2