From: Somik Behera Date: Sun, 5 Jun 2011 00:45:36 +0000 (-0700) Subject: * Merged changes from Salvatore's branch - quantum-api-workinprogress X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=48f4e9aaa0d92fcb72a0c03888ef7cb8cbb91f17;p=openstack-build%2Fneutron-build.git * Merged changes from Salvatore's branch - quantum-api-workinprogress * Removed spurious methods from quantum_base_plugin class. * Updated the sample plugins to be compliant with the new QuantumBase class. --- 48f4e9aaa0d92fcb72a0c03888ef7cb8cbb91f17 diff --cc quantum/manager.py index a36e9b28f,dc3f39d75..79a5139d8 --- a/quantum/manager.py +++ b/quantum/manager.py @@@ -27,22 -29,27 +29,27 @@@ gettext.install('quantum', unicode=1 from common import utils from quantum_plugin_base import QuantumPluginBase -CONFIG_FILE = "quantum/plugins.ini" +CONFIG_FILE = "plugins.ini" + class QuantumManager(object): - - def __init__(self,config=CONFIG_FILE): + + def __init__(self,config=CONFIG_FILE): self.configuration_file = CONFIG_FILE plugin_location = utils.getPluginFromConfig(CONFIG_FILE) + print "PLUGIN LOCATION:%s" % plugin_location plugin_klass = utils.import_class(plugin_location) if not issubclass(plugin_klass, QuantumPluginBase): - raise Exception("Configured Quantum plug-in didn't pass compatibility test") + raise Exception("Configured Quantum plug-in " \ + "didn't pass compatibility test") else: - print("Successfully imported Quantum plug-in. All compatibility tests passed\n") + print("Successfully imported Quantum plug-in." \ + "All compatibility tests passed\n") self.plugin = plugin_klass() - - def get_manager(self): - return self.plugin + + def get_manager(self): + return self.plugin + # TODO(somik): rmove the main class # Added for temporary testing purposes diff --cc quantum/plugins/SamplePlugin.py index 5088b71fa,7b43b4c6d..41dd3271d --- a/quantum/plugins/SamplePlugin.py +++ b/quantum/plugins/SamplePlugin.py @@@ -89,6 -91,6 +91,12 @@@ class QuantumEchoPlugin(object) is deleted. """ print("delete_port() called\n") ++ ++ def update_port(self, tenant_id, net_id, port_id, port_state): ++ """ ++ 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): @@@ -113,22 -115,22 +121,7 @@@ specified Virtual Network. """ print("unplug_interface() called\n") -- -- -- def get_interface_details(self, tenant_id, net_id, port_id): -- """ -- Retrieves the remote interface that is attached at this -- particular port. -- """ -- print("get_interface_details() called\n") -- -- -- def get_all_attached_interfaces(self, tenant_id, net_id): -- """ -- Retrieves all remote interfaces that are attached to -- a particular Virtual Network. -- """ -- print("get_all_attached_interfaces() called\n") ++ class DummyDataPlugin(object): @@@ -202,6 -204,6 +195,12 @@@ print("create_port() called\n") #return the port id return 201 ++ ++ def update_port(self, tenant_id, net_id, port_id, port_state): ++ """ ++ 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): @@@ -240,23 -242,265 +239,226 @@@ print("unplug_interface() called\n") -- def get_interface_details(self, tenant_id, net_id, port_id): - """ - Retrieves the remote interface that is attached at this - particular port. - """ - print("get_interface_details() called\n") - #returns the remote interface UUID - return "/tenant1/networks/net_id/portid/vif2.0" - - - def get_all_attached_interfaces(self, tenant_id, net_id): - """ - Retrieves all remote interfaces that are attached to - a particular Virtual Network. - """ - print("get_all_attached_interfaces() called\n") - # returns a list of all attached remote interfaces - vifs_on_net = ["/tenant1/networks/net_id/portid/vif2.0", "/tenant1/networks/10/121/vif1.1"] - return vifs_on_net - - + class FakePlugin(object): + """ + FakePlugin is a demo plugin that provides + in-memory data structures to aid in quantum + client/cli/api development + """ + + #static data for networks and ports + _port_dict_1 = { + 1 : {'port-id': 1, + 'port-state': 'DOWN', + 'attachment': None}, + 2 : {'port-id': 2, + 'port-state':'UP', + 'attachment': None} + } + _port_dict_2 = { + 1 : {'port-id': 1, + 'port-state': 'UP', + 'attachment': 'SomeFormOfVIFID'}, + 2 : {'port-id': 2, + 'port-state':'DOWN', + 'attachment': None} + } + _networks={'001': + { + 'net-id':'001', + 'net-name':'pippotest', + 'net-ports': _port_dict_1 + }, + '002': + { + 'net-id':'002', + 'net-name':'cicciotest', + 'net-ports': _port_dict_2 + }} + + + def __init__(self): + 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'): + 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']) + + def get_all_networks(self, tenant_id): + """ + Returns a dictionary containing all + for + the specified tenant. """ - Retrieves the remote interface that is attached at this - particular port. + print("get_all_networks() called\n") + return FakePlugin._networks.values() + + def get_network_details(self, tenant_id, net_id): """ - print("get_interface_details() called\n") - #returns the remote interface UUID - return "/tenant1/networks/net_id/portid/vif2.0" + retrieved a list of all the remote vifs that + are attached to the network + """ + print("get_network_details() called\n") + return self._get_network(tenant_id, net_id) + + def create_network(self, tenant_id, net_name): + """ + Creates a new Virtual Network, and assigns it + a symbolic name. + """ + print("create_network() called\n") + FakePlugin._net_counter += 1 + 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, + 'net-ports': {}} + 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 + belonging to the specified tenant. + """ + print("delete_network() called\n") + net = FakePlugin._networks.get(net_id) + # Verify that no attachments are plugged into the network + if net: + if net['net-ports']: + for port in net['net-ports'].values(): + if port['attachment']: + raise exc.NetworkInUse(net_id=net_id) + FakePlugin._networks.pop(net_id) + return net + # Network not found + raise exc.NetworkNotFound(net_id=net_id) - def get_all_attached_interfaces(self, tenant_id, net_id): + def rename_network(self, tenant_id, net_id, new_name): """ - Retrieves all remote interfaces that are attached to - a particular Virtual Network. + Updates the symbolic name belonging to a particular + Virtual Network. """ - print("get_all_attached_interfaces() called\n") - # returns a list of all attached remote interfaces - vifs_on_net = ["/tenant1/networks/net_id/portid/vif2.0", "/tenant1/networks/10/121/vif1.1"] - return vifs_on_net + print("rename_network() called\n") + net = self._get_network(tenant_id, net_id) + net['net-name']=new_name + return net + + 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") + network = self._get_network(tenant_id, net_id) + ports_on_net = network['net-ports'].values() + return ports_on_net + + 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") + 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? + 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, + 'port-state': port_state, + 'attachment': None} + ports[new_port_id] = new_port_dict + return new_port_dict + + def update_port(self, tenant_id, net_id, port_id, port_state): + """ + Updates the state of a port on the specified Virtual Network. + """ + print("create_port() called\n") + port = self._get_port(tenant_id, net_id, port_id) + self._validate_port_state(port_state) + port['port-state'] = port_state + return port + + def delete_port(self, tenant_id, net_id, port_id): + """ + Deletes a port on a specified Virtual Network, + if the port contains a remote interface attachment, + the remote interface is first un-plugged and then the port + is deleted. + """ + print("delete_port() called\n") + 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, + att_id=port['attachment']) + try: + net['net-ports'].pop(int(port_id)) + except KeyError: + raise exc.PortNotFound(net_id=net_id, port_id=port_id) + - def get_interface_details(self, tenant_id, net_id, port_id): - """ - Retrieves the remote interface that is attached at this - particular port. - """ - print("get_interface_details() called\n") - port = self._get_port(tenant_id, net_id, port_id) - return port['attachment'] + + 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") + # Validate attachment + self._validate_attachment(tenant_id, net_id, port_id, + 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, + 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 + specified Virtual Network. + """ + print("unplug_interface() called\n") + port = self._get_port(tenant_id, net_id, port_id) + # TODO(salvatore-orlando): + # Should unplug on port without attachment raise an Error? + port['attachment'] = None - - #TODO - neeed to update methods from this point onwards - def get_all_attached_interfaces(self, tenant_id, net_id): - """ - Retrieves all remote interfaces that are attached to - a particular Virtual Network. - """ - print("get_all_attached_interfaces() called\n") - # returns a list of all attached remote interfaces - vifs_on_net = ["/tenant1/networks/net_id/portid/vif2.0", "/tenant1/networks/10/121/vif1.1"] - return vifs_on_net ++ diff --cc quantum/quantum_plugin_base.py index b84940c70,3d79d3a19..0bc156d49 --- a/quantum/quantum_plugin_base.py +++ b/quantum/quantum_plugin_base.py @@@ -119,22 -127,22 +127,7 @@@ class QuantumPluginBase(object) """ pass -- @abstractmethod -- def get_interface_details(self, tenant_id, net_id, port_id): -- """ -- Retrieves the remote interface that is attached at this -- particular port. - """ - pass - - @abstractmethod - def get_all_attached_interfaces(self, tenant_id, net_id): - """ - Retrieves all remote interfaces that are attached to - a particular Virtual Network. -- """ -- pass - @abstractmethod - def get_all_attached_interfaces(self, tenant_id, net_id): - """ - Retrieves all remote interfaces that are attached to - a particular Virtual Network. - """ - pass - @classmethod def __subclasshook__(cls, klass): """