
Adapting assertions in unit tests merged from trunk to reflect changes in the API due to RFE requested by Erik Carlin
427 lines
14 KiB
Python
427 lines
14 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright 2011, Nicira Networks, Inc.
|
|
#
|
|
# 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: Somik Behera, Nicira Networks, Inc.
|
|
# @author: Salvatore Orlando, Citrix
|
|
|
|
import logging
|
|
|
|
from quantum.common import exceptions as exc
|
|
from quantum.db import api as db
|
|
|
|
LOG = logging.getLogger('quantum.plugins.SamplePlugin')
|
|
|
|
|
|
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
|
|
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.
|
|
"""
|
|
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
|
|
belonging to the specified tenant.
|
|
"""
|
|
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,
|
|
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")
|
|
|
|
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):
|
|
"""
|
|
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
|
|
specified Virtual Network.
|
|
"""
|
|
print("unplug_interface() called\n")
|
|
|
|
|
|
class DummyDataPlugin(object):
|
|
|
|
"""
|
|
DummyDataPlugin is a demo plugin that provides
|
|
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.
|
|
"""
|
|
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
|
|
a symbolic name.
|
|
"""
|
|
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
|
|
belonging to the specified tenant.
|
|
"""
|
|
print("delete_network() called\n")
|
|
|
|
def get_network_details(self, tenant_id, net_id):
|
|
"""
|
|
retrieved a list of all the remote vifs that
|
|
are attached to the network
|
|
"""
|
|
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
|
|
specified Virtual Network.
|
|
"""
|
|
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.
|
|
"""
|
|
print("create_port() called\n")
|
|
#return the port id
|
|
return 201
|
|
|
|
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")
|
|
|
|
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")
|
|
#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
|
|
in-memory data structures to aid in quantum
|
|
client/cli/api development
|
|
"""
|
|
|
|
def __init__(self):
|
|
db.configure_db({'sql_connection': 'sqlite:///:memory:'})
|
|
FakePlugin._net_counter = 0
|
|
|
|
def _get_network(self, tenant_id, network_id):
|
|
try:
|
|
network = db.network_get(network_id)
|
|
except:
|
|
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)
|
|
try:
|
|
port = db.port_get(port_id)
|
|
except:
|
|
raise exc.PortNotFound(net_id=network_id, port_id=port_id)
|
|
# Port must exist and belong to the appropriate network.
|
|
if port['network_id'] != net['uuid']:
|
|
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 ('ACTIVE', 'DOWN'):
|
|
raise exc.StateInvalid(port_state=port_state)
|
|
return True
|
|
|
|
def _validate_attachment(self, tenant_id, network_id, port_id,
|
|
remote_interface_id):
|
|
for port in db.port_list(network_id):
|
|
if port['interface_id'] == remote_interface_id:
|
|
raise exc.AlreadyAttached(net_id=network_id,
|
|
port_id=port_id,
|
|
att_id=port['interface_id'],
|
|
att_port_id=port['uuid'])
|
|
|
|
def get_all_networks(self, tenant_id):
|
|
"""
|
|
Returns a dictionary containing all
|
|
<network_uuid, network_name> for
|
|
the specified tenant.
|
|
"""
|
|
LOG.debug("FakePlugin.get_all_networks() called")
|
|
nets = []
|
|
for net in db.network_list(tenant_id):
|
|
net_item = {'net-id': str(net.uuid),
|
|
'net-name': net.name}
|
|
nets.append(net_item)
|
|
return nets
|
|
|
|
def get_network_details(self, tenant_id, net_id):
|
|
"""
|
|
retrieved a list of all the remote vifs that
|
|
are attached to the network
|
|
"""
|
|
LOG.debug("FakePlugin.get_network_details() called")
|
|
net = self._get_network(tenant_id, net_id)
|
|
# Retrieves ports for network
|
|
ports = self.get_all_ports(tenant_id, net_id)
|
|
return {'net-id': str(net.uuid),
|
|
'net-name': net.name,
|
|
'net-ports': ports}
|
|
|
|
def create_network(self, tenant_id, net_name):
|
|
"""
|
|
Creates a new Virtual Network, and assigns it
|
|
a symbolic name.
|
|
"""
|
|
LOG.debug("FakePlugin.create_network() called")
|
|
new_net = db.network_create(tenant_id, net_name)
|
|
# Return uuid for newly created network as net-id.
|
|
return {'net-id': new_net['uuid']}
|
|
|
|
def delete_network(self, tenant_id, net_id):
|
|
"""
|
|
Deletes the network with the specified network identifier
|
|
belonging to the specified tenant.
|
|
"""
|
|
LOG.debug("FakePlugin.delete_network() called")
|
|
net = self._get_network(tenant_id, net_id)
|
|
# Verify that no attachments are plugged into the network
|
|
if net:
|
|
for port in db.port_list(net_id):
|
|
if port['interface_id']:
|
|
raise exc.NetworkInUse(net_id=net_id)
|
|
db.network_destroy(net_id)
|
|
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
|
|
Virtual Network.
|
|
"""
|
|
LOG.debug("FakePlugin.rename_network() called")
|
|
try:
|
|
db.network_rename(net_id, tenant_id, new_name)
|
|
except:
|
|
raise exc.NetworkNotFound(net_id=net_id)
|
|
net = self._get_network(tenant_id, net_id)
|
|
return net
|
|
|
|
def get_all_ports(self, tenant_id, net_id):
|
|
"""
|
|
Retrieves all port identifiers belonging to the
|
|
specified Virtual Network.
|
|
"""
|
|
LOG.debug("FakePlugin.get_all_ports() called")
|
|
port_ids = []
|
|
ports = db.port_list(net_id)
|
|
for x in ports:
|
|
d = {'port-id': str(x.uuid)}
|
|
port_ids.append(d)
|
|
return port_ids
|
|
|
|
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.
|
|
"""
|
|
LOG.debug("FakePlugin.get_port_details() called")
|
|
port = self._get_port(tenant_id, net_id, port_id)
|
|
return {'port-id': str(port.uuid),
|
|
'attachment-id': port.interface_id,
|
|
'port-state': port.state}
|
|
|
|
def create_port(self, tenant_id, net_id, port_state=None):
|
|
"""
|
|
Creates a port on the specified Virtual Network.
|
|
"""
|
|
LOG.debug("FakePlugin.create_port() called")
|
|
# verify net_id
|
|
self._get_network(tenant_id, net_id)
|
|
port = db.port_create(net_id, port_state)
|
|
port_item = {'port-id': str(port.uuid)}
|
|
return port_item
|
|
|
|
def update_port(self, tenant_id, net_id, port_id, new_state):
|
|
"""
|
|
Updates the state of a port on the specified Virtual Network.
|
|
"""
|
|
LOG.debug("FakePlugin.update_port() called")
|
|
#validate port and network ids
|
|
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)
|
|
port_item = {'port-id': port_id,
|
|
'port-state': new_state}
|
|
return port_item
|
|
|
|
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.
|
|
"""
|
|
LOG.debug("FakePlugin.delete_port() called")
|
|
net = self._get_network(tenant_id, net_id)
|
|
port = self._get_port(tenant_id, net_id, port_id)
|
|
if port['interface_id']:
|
|
raise exc.PortInUse(net_id=net_id, port_id=port_id,
|
|
att_id=port['interface_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
|
|
|
|
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.
|
|
"""
|
|
LOG.debug("FakePlugin.plug_interface() called")
|
|
# 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['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)
|
|
|
|
def unplug_interface(self, tenant_id, net_id, port_id):
|
|
"""
|
|
Detaches a remote interface from the specified port on the
|
|
specified Virtual Network.
|
|
"""
|
|
LOG.debug("FakePlugin.unplug_interface() called")
|
|
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)
|