c552626664
* This is a massive patch that aims to clean up the codebase and bring it into compliance with HACKING.rst and PEP8 in one fell swoop. * Cleaned up use of gettext. * Updated log usage for consistency. * The tests run successfully against all plugins except cisco and nicira (due to dependency issues with these plugins). * Addresses bug 981208 Change-Id: I4d8c7ab138d8f7bb906d18dc34f88f8bd0581c19
345 lines
12 KiB
Python
345 lines
12 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.api.api_common import OperationalStatus
|
|
from quantum.common import exceptions as exc
|
|
from quantum.db import api as db
|
|
|
|
|
|
LOG = logging.getLogger('quantum.plugins.sample.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, **kwargs):
|
|
"""
|
|
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 update_network(self, tenant_id, net_id, **kwargs):
|
|
print("update_network() called")
|
|
|
|
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, **kwargs):
|
|
"""
|
|
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, **kwargs):
|
|
"""
|
|
Updates the attributes 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")
|
|
|
|
supported_extension_aliases = ["FOXNSOX"]
|
|
|
|
def method_to_support_foxnsox_extension(self):
|
|
print("method_to_support_foxnsox_extension() 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):
|
|
|
|
db.validate_network_ownership(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):
|
|
|
|
db.validate_port_ownership(tenant_id, network_id, port_id)
|
|
net = self._get_network(tenant_id, network_id)
|
|
try:
|
|
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.
|
|
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, **kwargs):
|
|
"""
|
|
Returns a dictionary containing all
|
|
<network_uuid, network_name> for
|
|
the specified tenant.
|
|
"""
|
|
LOG.debug("FakePlugin.get_all_networks() called")
|
|
filter_opts = kwargs.get('filter_opts', None)
|
|
if not filter_opts is None and len(filter_opts) > 0:
|
|
LOG.debug("filtering options were passed to the plugin"
|
|
"but the Fake plugin does not support them")
|
|
nets = []
|
|
for net in db.network_list(tenant_id):
|
|
net_item = {'net-id': str(net.uuid),
|
|
'net-name': net.name,
|
|
'net-op-status': net.op_status}
|
|
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-op-status': net.op_status,
|
|
'net-ports': ports}
|
|
|
|
def create_network(self, tenant_id, net_name, **kwargs):
|
|
"""
|
|
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)
|
|
# Put operational status UP
|
|
db.network_update(new_net.uuid, net_name,
|
|
op_status=OperationalStatus.UP)
|
|
# 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 update_network(self, tenant_id, net_id, **kwargs):
|
|
"""
|
|
Updates the attributes of a particular Virtual Network.
|
|
"""
|
|
LOG.debug("FakePlugin.update_network() called")
|
|
net = db.network_update(net_id, tenant_id, **kwargs)
|
|
return net
|
|
|
|
def get_all_ports(self, tenant_id, net_id, **kwargs):
|
|
"""
|
|
Retrieves all port identifiers belonging to the
|
|
specified Virtual Network.
|
|
"""
|
|
LOG.debug("FakePlugin.get_all_ports() called")
|
|
db.validate_network_ownership(tenant_id, net_id)
|
|
filter_opts = kwargs.get('filter_opts')
|
|
if filter_opts:
|
|
LOG.debug("filtering options were passed to the plugin"
|
|
"but the Fake plugin does not support them")
|
|
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': port.interface_id,
|
|
'port-state': port.state,
|
|
'port-op-status': port.op_status}
|
|
|
|
def create_port(self, tenant_id, net_id, port_state=None, **kwargs):
|
|
"""
|
|
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)
|
|
# Put operational status UP
|
|
db.port_update(port.uuid, net_id, op_status=OperationalStatus.UP)
|
|
port_item = {'port-id': str(port.uuid)}
|
|
return port_item
|
|
|
|
def update_port(self, tenant_id, net_id, port_id, **kwargs):
|
|
"""
|
|
Updates the attributes 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)
|
|
port = db.port_update(port_id, net_id, **kwargs)
|
|
port_item = {'port-id': port_id, 'port-state': port['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, net_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")
|
|
port = self._get_port(tenant_id, net_id, port_id)
|
|
# Validate attachment
|
|
self._validate_attachment(tenant_id, net_id, port_id,
|
|
remote_interface_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, net_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, net_id)
|