Merge "Remove OneConvergence plugin from the source tree"

This commit is contained in:
Jenkins 2015-10-07 01:39:08 +00:00 committed by Gerrit Code Review
commit 371c37f2f6
20 changed files with 0 additions and 2084 deletions

View File

@ -1,35 +0,0 @@
[nvsd]
# Configure the NVSD controller. The plugin proxies the api calls using
# to NVSD controller which implements the required functionality.
# IP address of NVSD controller api server
# nvsd_ip = <ip address of nvsd controller>
# Port number of NVSD controller api server
# nvsd_port = 8082
# Authentication credentials to access the api server
# nvsd_user = <nvsd controller username>
# nvsd_passwd = <password>
# API request timeout in seconds
# request_timeout = <default request timeout>
# Maximum number of retry attempts to login to the NVSD controller
# Specify 0 to retry until success (default)
# nvsd_retries = 0
[securitygroup]
# Specify firewall_driver option, if neutron security groups are disabled,
# then NoopFirewallDriver otherwise OVSHybridIptablesFirewallDriver.
# firewall_driver = neutron.agent.firewall.NoopFirewallDriver
# Controls if neutron security group is enabled or not.
# It should be false when you use nova security group.
# enable_security_group = True
[agent]
# root_helper = sudo /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf
[database]
# connection = mysql+pymysql://root:<passwd>@127.0.0.1/<neutron_db>?charset=utf8

View File

@ -1,32 +0,0 @@
One Convergence Neutron Plugin to implement the Neutron v2.0 API. The plugin
works with One Convergence NVSD controller to provide network virtualization
functionality.
The plugin is enabled with the following configuration line in neutron.conf:
core_plugin = neutron.plugins.oneconvergence.plugin.OneConvergencePluginV2
The configuration parameters required for the plugin are specified in the file
etc/neutron/plugins/oneconvergence/nvsdplugin.ini. The configuration file contains
description of the different parameters.
To enable One Convergence Neutron Plugin with devstack and configure the required
parameters, use the following lines in localrc:
Q_PLUGIN=oneconvergence
disable_service n-net
enable_service q-agt
enable_service q-dhcp
enable_service q-svc
enable_service q-l3
enable_service q-meta
enable_service neutron
NVSD_IP=
NVSD_PORT=
NVSD_USER=
NVSD_PASSWD=
The NVSD controller configuration should be specified in nvsdplugin.ini before
invoking stack.sh.

View File

@ -1,156 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
"""NVSD agent code for security group events."""
import socket
import sys
import time
import eventlet
eventlet.monkey_patch()
from oslo_log import log as logging
import oslo_messaging
from neutron.agent.common import ovs_lib
from neutron.agent import rpc as agent_rpc
from neutron.agent import securitygroups_rpc as sg_rpc
from neutron.common import config as common_config
from neutron.common import topics
from neutron import context as n_context
from neutron.extensions import securitygroup as ext_sg
from neutron.i18n import _LE, _LI
from neutron.plugins.oneconvergence.lib import config
LOG = logging.getLogger(__name__)
class NVSDAgentRpcCallback(object):
target = oslo_messaging.Target(version='1.0')
def __init__(self, context, agent, sg_agent):
super(NVSDAgentRpcCallback, self).__init__()
self.context = context
self.agent = agent
self.sg_agent = sg_agent
def port_update(self, context, **kwargs):
LOG.debug("port_update received: %s", kwargs)
port = kwargs.get('port')
# Validate that port is on OVS
vif_port = self.agent.int_br.get_vif_port_by_id(port['id'])
if not vif_port:
return
if ext_sg.SECURITYGROUPS in port:
self.sg_agent.refresh_firewall()
class SecurityGroupAgentRpcCallback(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
target = oslo_messaging.Target(version=sg_rpc.SG_RPC_VERSION)
def __init__(self, context, sg_agent):
super(SecurityGroupAgentRpcCallback, self).__init__()
self.context = context
self.sg_agent = sg_agent
class NVSDNeutronAgent(object):
# history
# 1.0 Initial version
# 1.1 Support Security Group RPC
target = oslo_messaging.Target(version='1.1')
def __init__(self, integ_br, polling_interval):
super(NVSDNeutronAgent, self).__init__()
self.int_br = ovs_lib.OVSBridge(integ_br)
self.polling_interval = polling_interval
self.setup_rpc()
self.ports = set()
def setup_rpc(self):
self.host = socket.gethostname()
self.agent_id = 'nvsd-q-agent.%s' % self.host
LOG.info(_LI("RPC agent_id: %s"), self.agent_id)
self.topic = topics.AGENT
self.context = n_context.get_admin_context_without_session()
self.sg_plugin_rpc = sg_rpc.SecurityGroupServerRpcApi(topics.PLUGIN)
self.sg_agent = sg_rpc.SecurityGroupAgentRpc(self.context,
self.sg_plugin_rpc)
# RPC network init
# Handle updates from service
self.callback_oc = NVSDAgentRpcCallback(self.context,
self, self.sg_agent)
self.callback_sg = SecurityGroupAgentRpcCallback(self.context,
self.sg_agent)
self.endpoints = [self.callback_oc, self.callback_sg]
# Define the listening consumer for the agent
consumers = [[topics.PORT, topics.UPDATE],
[topics.SECURITY_GROUP, topics.UPDATE]]
self.connection = agent_rpc.create_consumers(self.endpoints,
self.topic,
consumers)
def _update_ports(self, registered_ports):
ports = self.int_br.get_vif_port_set()
if ports == registered_ports:
return
added = ports - registered_ports
removed = registered_ports - ports
return {'current': ports,
'added': added,
'removed': removed}
def _process_devices_filter(self, port_info):
if 'added' in port_info:
self.sg_agent.prepare_devices_filter(port_info['added'])
if 'removed' in port_info:
self.sg_agent.remove_devices_filter(port_info['removed'])
def daemon_loop(self):
"""Main processing loop for OC Plugin Agent."""
ports = set()
while True:
try:
port_info = self._update_ports(ports)
if port_info:
LOG.debug("Port list is updated")
self._process_devices_filter(port_info)
ports = port_info['current']
self.ports = ports
except Exception:
LOG.exception(_LE("Error in agent event loop"))
LOG.debug("AGENT looping.....")
time.sleep(self.polling_interval)
def main():
common_config.init(sys.argv[1:])
common_config.setup_logging()
integ_br = config.AGENT.integration_bridge
polling_interval = config.AGENT.polling_interval
agent = NVSDNeutronAgent(integ_br, polling_interval)
LOG.info(_LI("NVSD Agent initialized successfully, now running... "))
# Start everything.
agent.daemon_loop()

View File

@ -1,53 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
#
""" Register the configuration options"""
from oslo_config import cfg
NVSD_OPT = [
cfg.StrOpt('nvsd_ip',
default='127.0.0.1',
help=_("NVSD Controller IP address")),
cfg.IntOpt('nvsd_port',
default=8082,
help=_("NVSD Controller Port number")),
cfg.StrOpt('nvsd_user',
default='ocplugin',
help=_("NVSD Controller username")),
cfg.StrOpt('nvsd_passwd',
default='oc123', secret=True,
help=_("NVSD Controller password")),
cfg.IntOpt('request_timeout',
default=30,
help=_("NVSD controller REST API request timeout in seconds")),
cfg.IntOpt('nvsd_retries', default=0,
help=_("Number of login retries to NVSD controller"))
]
agent_opts = [
cfg.StrOpt('integration_bridge', default='br-int',
help=_("integration bridge")),
cfg.IntOpt('polling_interval', default=2,
help=_("The number of seconds the agent will wait between "
"polling for local device changes.")),
]
cfg.CONF.register_opts(NVSD_OPT, "nvsd")
cfg.CONF.register_opts(agent_opts, "AGENT")
CONF = cfg.CONF
AGENT = cfg.CONF.AGENT

View File

@ -1,55 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
#
"""NVSD Exception Definitions."""
from neutron.common import exceptions as n_exc
class NVSDAPIException(n_exc.NeutronException):
'''Base NVSDplugin Exception.'''
message = _("An unknown nvsd plugin exception occurred: %(reason)s")
class RequestTimeout(NVSDAPIException):
message = _("The request has timed out.")
class UnAuthorizedException(NVSDAPIException):
message = _("Invalid access credentials to the Server.")
class NotFoundException(NVSDAPIException):
message = _("A resource is not found: %(reason)s")
class BadRequestException(NVSDAPIException):
message = _("Request sent to server is invalid: %(reason)s")
class ServerException(NVSDAPIException):
message = _("Internal Server Error: %(reason)s")
class ConnectionClosedException(NVSDAPIException):
message = _("Connection is closed by the server.")
class ForbiddenException(NVSDAPIException):
message = _("The request is forbidden access to the resource: %(reason)s")
class InternalServerError(NVSDAPIException):
message = _("Internal Server Error from NVSD controller: %(reason)s")

View File

@ -1,43 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
from neutron.db import api as db
from neutron.db import models_v2
from neutron.db import securitygroups_db as sg_db
from neutron.extensions import securitygroup as ext_sg
from neutron import manager
def get_port_from_device(port_id):
session = db.get_session()
sg_binding_port = sg_db.SecurityGroupPortBinding.port_id
query = session.query(models_v2.Port,
sg_db.SecurityGroupPortBinding.security_group_id)
query = query.outerjoin(sg_db.SecurityGroupPortBinding,
models_v2.Port.id == sg_binding_port)
query = query.filter(models_v2.Port.id == port_id)
port_and_sgs = query.all()
if not port_and_sgs:
return None
port = port_and_sgs[0][0]
plugin = manager.NeutronManager.get_plugin()
port_dict = plugin._make_port_dict(port)
port_dict[ext_sg.SECURITYGROUPS] = [
sg_id for tport, sg_id in port_and_sgs if sg_id]
port_dict['security_group_rules'] = []
port_dict['security_group_source_groups'] = []
port_dict['fixed_ips'] = [ip['ip_address']
for ip in port['fixed_ips']]
return port_dict

View File

@ -1,353 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
"""Intermidiate NVSD Library."""
from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import excutils
import neutron.plugins.oneconvergence.lib.exception as nvsdexception
from neutron.plugins.oneconvergence.lib import plugin_helper
LOG = logging.getLogger(__name__)
NETWORKS_URI = "/pluginhandler/ocplugin/tenant/%s/lnetwork/"
NETWORK_URI = NETWORKS_URI + "%s"
GET_ALL_NETWORKS = "/pluginhandler/ocplugin/tenant/getallnetworks"
SUBNETS_URI = NETWORK_URI + "/lsubnet/"
SUBNET_URI = SUBNETS_URI + "%s"
GET_ALL_SUBNETS = "/pluginhandler/ocplugin/tenant/getallsubnets"
PORTS_URI = NETWORK_URI + "/lport/"
PORT_URI = PORTS_URI + "%s"
EXT_URI = "/pluginhandler/ocplugin/ext/tenant/%s"
FLOATING_IPS_URI = EXT_URI + "/floatingip/"
FLOATING_IP_URI = FLOATING_IPS_URI + "%s"
ROUTERS_URI = EXT_URI + "/lrouter/"
ROUTER_URI = ROUTERS_URI + "%s"
METHODS = {"POST": "create",
"PUT": "update",
"DELETE": "delete",
"GET": "get"}
class NVSDApi(object):
def build_error_msg(self, method, resource, tenant_id, resource_id):
if method == "POST":
msg = _("Could not create a %(resource)s under tenant "
"%(tenant_id)s") % {'resource': resource,
'tenant_id': tenant_id}
elif resource_id:
msg = _("Failed to %(method)s %(resource)s "
"id=%(resource_id)s") % {'method': METHODS[method],
'resource': resource,
'resource_id': resource_id
}
else:
msg = _("Failed to %(method)s %(resource)s") % {
'method': METHODS[method], 'resource': resource}
return msg
def set_connection(self):
self.nvsdcontroller = plugin_helper.initialize_plugin_helper()
self.nvsdcontroller.login()
def send_request(self, method, uri, body=None, resource=None,
tenant_id='', resource_id=None):
"""Issue a request to NVSD controller."""
try:
result = self.nvsdcontroller.request(method, uri, body=body)
except nvsdexception.NVSDAPIException as e:
with excutils.save_and_reraise_exception() as ctxt:
msg = self.build_error_msg(method, resource, tenant_id,
resource_id)
LOG.error(msg)
# Modifying the reason message without disturbing the exception
# info
ctxt.value = type(e)(reason=msg)
return result
def create_network(self, network):
tenant_id = network['tenant_id']
router_external = network['router:external'] is True
network_obj = {
"name": network['name'],
"tenant_id": tenant_id,
"shared": network['shared'],
"admin_state_up": network['admin_state_up'],
"router:external": router_external
}
uri = NETWORKS_URI % tenant_id
response = self.send_request("POST", uri,
body=jsonutils.dumps(network_obj),
resource='network', tenant_id=tenant_id)
nvsd_net = response.json()
LOG.debug("Network %(id)s created under tenant %(tenant_id)s",
{'id': nvsd_net['id'], 'tenant_id': tenant_id})
return nvsd_net
def update_network(self, network, network_update):
tenant_id = network['tenant_id']
network_id = network['id']
uri = NETWORK_URI % (tenant_id, network_id)
self.send_request("PUT", uri,
body=jsonutils.dumps(network_update),
resource='network', tenant_id=tenant_id,
resource_id=network_id)
LOG.debug("Network %(id)s updated under tenant %(tenant_id)s",
{'id': network_id, 'tenant_id': tenant_id})
def delete_network(self, network, subnets=[]):
tenant_id = network['tenant_id']
network_id = network['id']
ports = self._get_ports(tenant_id, network_id)
for port in ports:
self.delete_port(port['id'], port)
for subnet in subnets:
self.delete_subnet(subnet)
path = NETWORK_URI % (tenant_id, network_id)
self.send_request("DELETE", path, resource='network',
tenant_id=tenant_id, resource_id=network_id)
LOG.debug("Network %(id)s deleted under tenant %(tenant_id)s",
{'id': network_id, 'tenant_id': tenant_id})
def create_subnet(self, subnet):
tenant_id = subnet['tenant_id']
network_id = subnet['network_id']
uri = SUBNETS_URI % (tenant_id, network_id)
self.send_request("POST", uri, body=jsonutils.dumps(subnet),
resource='subnet', tenant_id=tenant_id)
LOG.debug("Subnet %(id)s created under tenant %(tenant_id)s",
{'id': subnet['id'], 'tenant_id': tenant_id})
def delete_subnet(self, subnet):
tenant_id = subnet['tenant_id']
network_id = subnet['network_id']
subnet_id = subnet['id']
uri = SUBNET_URI % (tenant_id, network_id, subnet_id)
self.send_request("DELETE", uri, resource='subnet',
tenant_id=tenant_id, resource_id=subnet_id)
LOG.debug("Subnet %(id)s deleted under tenant %(tenant_id)s",
{'id': subnet_id, 'tenant_id': tenant_id})
def update_subnet(self, subnet, subnet_update):
tenant_id = subnet['tenant_id']
network_id = subnet['network_id']
subnet_id = subnet['id']
uri = SUBNET_URI % (tenant_id, network_id, subnet_id)
self.send_request("PUT", uri,
body=jsonutils.dumps(subnet_update),
resource='subnet', tenant_id=tenant_id,
resource_id=subnet_id)
LOG.debug("Subnet %(id)s updated under tenant %(tenant_id)s",
{'id': subnet_id, 'tenant_id': tenant_id})
def create_port(self, tenant_id, port):
network_id = port["network_id"]
fixed_ips = port.get("fixed_ips")
ip_address = None
subnet_id = None
if fixed_ips:
ip_address = fixed_ips[0].get("ip_address")
subnet_id = fixed_ips[0].get("subnet_id")
lport = {
"id": port["id"],
"name": port["name"],
"device_id": port["device_id"],
"device_owner": port["device_owner"],
"mac_address": port["mac_address"],
"ip_address": ip_address,
"subnet_id": subnet_id,
"admin_state_up": port["admin_state_up"],
"network_id": network_id,
"status": port["status"]
}
path = PORTS_URI % (tenant_id, network_id)
self.send_request("POST", path, body=jsonutils.dumps(lport),
resource='port', tenant_id=tenant_id)
LOG.debug("Port %(id)s created under tenant %(tenant_id)s",
{'id': port['id'], 'tenant_id': tenant_id})
def update_port(self, tenant_id, port, port_update):
network_id = port['network_id']
port_id = port['id']
lport = {}
for k in ('admin_state_up', 'name', 'device_id', 'device_owner'):
if k in port_update:
lport[k] = port_update[k]
fixed_ips = port_update.get('fixed_ips', None)
if fixed_ips:
lport["ip_address"] = fixed_ips[0].get("ip_address")
lport["subnet_id"] = fixed_ips[0].get("subnet_id")
uri = PORT_URI % (tenant_id, network_id, port_id)
self.send_request("PUT", uri, body=jsonutils.dumps(lport),
resource='port', tenant_id=tenant_id,
resource_id=port_id)
LOG.debug("Port %(id)s updated under tenant %(tenant_id)s",
{'id': port_id, 'tenant_id': tenant_id})
def delete_port(self, port_id, port):
tenant_id = port['tenant_id']
network_id = port['network_id']
uri = PORT_URI % (tenant_id, network_id, port_id)
self.send_request("DELETE", uri, resource='port', tenant_id=tenant_id,
resource_id=port_id)
LOG.debug("Port %(id)s deleted under tenant %(tenant_id)s",
{'id': port_id, 'tenant_id': tenant_id})
def _get_ports(self, tenant_id, network_id):
uri = PORTS_URI % (tenant_id, network_id)
response = self.send_request("GET", uri, resource='ports',
tenant_id=tenant_id)
return response.json()
def create_floatingip(self, floating_ip):
tenant_id = floating_ip['tenant_id']
uri = FLOATING_IPS_URI % tenant_id
self.send_request("POST", uri, body=jsonutils.dumps(floating_ip),
resource='floating_ip',
tenant_id=tenant_id)
LOG.debug("Flatingip %(id)s created under tenant %(tenant_id)s",
{'id': floating_ip['id'], 'tenant_id': tenant_id})
def update_floatingip(self, floating_ip, floating_ip_update):
tenant_id = floating_ip['tenant_id']
floating_ip_id = floating_ip['id']
uri = FLOATING_IP_URI % (tenant_id, floating_ip_id)
self.send_request("PUT", uri,
body=jsonutils.dumps(
floating_ip_update['floatingip']),
resource='floating_ip',
tenant_id=tenant_id,
resource_id=floating_ip_id)
LOG.debug("Flatingip %(id)s updated under tenant %(tenant_id)s",
{'id': floating_ip_id, 'tenant_id': tenant_id})
def delete_floatingip(self, floating_ip):
tenant_id = floating_ip['tenant_id']
floating_ip_id = floating_ip['id']
uri = FLOATING_IP_URI % (tenant_id, floating_ip_id)
self.send_request("DELETE", uri, resource='floating_ip',
tenant_id=tenant_id, resource_id=floating_ip_id)
LOG.debug("Flatingip %(id)s deleted under tenant %(tenant_id)s",
{'id': floating_ip_id, 'tenant_id': tenant_id})
def create_router(self, router):
tenant_id = router['tenant_id']
uri = ROUTERS_URI % tenant_id
self.send_request("POST", uri, body=jsonutils.dumps(router),
resource='router',
tenant_id=tenant_id)
LOG.debug("Router %(id)s created under tenant %(tenant_id)s",
{'id': router['id'], 'tenant_id': tenant_id})
def update_router(self, router):
tenant_id = router['tenant_id']
router_id = router['id']
uri = ROUTER_URI % (tenant_id, router_id)
self.send_request("PUT", uri,
body=jsonutils.dumps(router),
resource='router', tenant_id=tenant_id,
resource_id=router_id)
LOG.debug("Router %(id)s updated under tenant %(tenant_id)s",
{'id': router_id, 'tenant_id': tenant_id})
def delete_router(self, tenant_id, router_id):
uri = ROUTER_URI % (tenant_id, router_id)
self.send_request("DELETE", uri, resource='router',
tenant_id=tenant_id, resource_id=router_id)
LOG.debug("Router %(id)s deleted under tenant %(tenant_id)s",
{'id': router_id, 'tenant_id': tenant_id})

View File

@ -1,184 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
"""Library to talk to NVSD controller."""
from six.moves import http_client as httplib
import time
from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
import requests
from six.moves.urllib import parse
from neutron.i18n import _LE, _LW
import neutron.plugins.oneconvergence.lib.exception as exception
LOG = logging.getLogger(__name__)
def initialize_plugin_helper():
nvsdcontroller = NVSDController()
return nvsdcontroller
class NVSDController(object):
"""Encapsulates the NVSD Controller details."""
def __init__(self):
self._host = cfg.CONF.nvsd.nvsd_ip
self._port = cfg.CONF.nvsd.nvsd_port
self._user = cfg.CONF.nvsd.nvsd_user
self._password = cfg.CONF.nvsd.nvsd_passwd
self._retries = cfg.CONF.nvsd.nvsd_retries
self._request_timeout = float(cfg.CONF.nvsd.request_timeout)
self.api_url = 'http://' + self._host + ':' + str(self._port)
self.pool = requests.Session()
self.auth_token = None
def do_request(self, method, url=None, headers=None, data=None):
response = self.pool.request(method, url=url,
headers=headers, data=data,
timeout=self._request_timeout)
return response
def login(self):
"""Login to NVSD Controller."""
headers = {"Content-Type": "application/json"}
login_url = parse.urljoin(self.api_url,
"/pluginhandler/ocplugin/authmgmt/login")
data = jsonutils.dumps({"user_name": self._user,
"passwd": self._password})
attempts = 0
while True:
if attempts < self._retries:
attempts += 1
elif self._retries == 0:
attempts = 0
else:
msg = _("Unable to connect to NVSD controller. Exiting after "
"%(retries)s attempts") % {'retries': self._retries}
LOG.error(msg)
raise exception.ServerException(reason=msg)
try:
response = self.do_request("POST", url=login_url,
headers=headers, data=data)
break
except Exception as e:
LOG.error(_LE("Login Failed: %s"), e)
LOG.error(_LE("Unable to establish connection"
" with Controller %s"), self.api_url)
LOG.error(_LE("Retrying after 1 second..."))
time.sleep(1)
if response.status_code == requests.codes.ok:
LOG.debug("Login Successful %(uri)s "
"%(status)s", {'uri': self.api_url,
'status': response.status_code})
self.auth_token = jsonutils.loads(response.content)["session_uuid"]
LOG.debug("AuthToken = %s", self.auth_token)
else:
LOG.error(_LE("login failed"))
return
def request(self, method, url, body="", content_type="application/json"):
"""Issue a request to NVSD controller."""
if self.auth_token is None:
LOG.warning(_LW("No Token, Re-login"))
self.login()
headers = {"Content-Type": content_type}
uri = parse.urljoin(url, "?authToken=%s" % self.auth_token)
url = parse.urljoin(self.api_url, uri)
request_ok = False
response = None
try:
response = self.do_request(method, url=url,
headers=headers, data=body)
LOG.debug("request: %(method)s %(uri)s successful",
{'method': method, 'uri': self.api_url + uri})
request_ok = True
except httplib.IncompleteRead as e:
response = e.partial
request_ok = True
except Exception as e:
LOG.error(_LE("request: Request failed from "
"Controller side :%s"), e)
if response is None:
# Timeout.
LOG.error(_LE("Response is Null, Request timed out: %(method)s to "
"%(uri)s"), {'method': method, 'uri': uri})
self.auth_token = None
raise exception.RequestTimeout()
status = response.status_code
if status == requests.codes.unauthorized:
self.auth_token = None
# Raise an exception to inform that the request failed.
raise exception.UnAuthorizedException()
if status in self.error_codes:
LOG.error(_LE("Request %(method)s %(uri)s body = %(body)s failed "
"with status %(status)s. Reason: %(reason)s)"),
{'method': method,
'uri': uri, 'body': body,
'status': status,
'reason': response.reason})
raise self.error_codes[status]()
elif status not in (requests.codes.ok, requests.codes.created,
requests.codes.no_content):
LOG.error(_LE("%(method)s to %(url)s, unexpected response code: "
"%(status)d"), {'method': method, 'url': url,
'status': status})
return
if not request_ok:
LOG.error(_LE("Request failed from Controller side with "
"Status=%s"), status)
raise exception.ServerException()
else:
LOG.debug("Success: %(method)s %(url)s status=%(status)s",
{'method': method, 'url': self.api_url + uri,
'status': status})
response.body = response.content
return response
error_codes = {
404: exception.NotFoundException,
409: exception.BadRequestException,
500: exception.InternalServerError,
503: exception.ServerException,
403: exception.ForbiddenException,
301: exception.NVSDAPIException,
307: exception.NVSDAPIException,
400: exception.NVSDAPIException,
}

View File

@ -1,438 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
"""Implementation of OneConvergence Neutron Plugin."""
from oslo_config import cfg
from oslo_log import log as logging
import oslo_messaging
from oslo_utils import excutils
from oslo_utils import importutils
from neutron.agent import securitygroups_rpc as sg_rpc
from neutron.api.rpc.agentnotifiers import dhcp_rpc_agent_api
from neutron.api.rpc.agentnotifiers import l3_rpc_agent_api
from neutron.api.rpc.handlers import dhcp_rpc
from neutron.api.rpc.handlers import l3_rpc
from neutron.api.rpc.handlers import metadata_rpc
from neutron.api.rpc.handlers import securitygroups_rpc
from neutron.common import constants as n_const
from neutron.common import exceptions as nexception
from neutron.common import rpc as n_rpc
from neutron.common import topics
from neutron.db import agents_db
from neutron.db import agentschedulers_db
from neutron.db import db_base_plugin_v2
from neutron.db import external_net_db
from neutron.db import extraroute_db
from neutron.db import l3_agentschedulers_db
from neutron.db import l3_gwmode_db
from neutron.db import portbindings_base
from neutron.db import securitygroups_rpc_base as sg_db_rpc
from neutron.extensions import portbindings
from neutron.i18n import _LE
from neutron.plugins.common import constants as svc_constants
import neutron.plugins.oneconvergence.lib.config # noqa
import neutron.plugins.oneconvergence.lib.exception as nvsdexception
import neutron.plugins.oneconvergence.lib.nvsd_db as nvsd_db
from neutron.plugins.oneconvergence.lib import nvsdlib as nvsd_lib
LOG = logging.getLogger(__name__)
IPv6 = 6
class SecurityGroupServerRpcMixin(sg_db_rpc.SecurityGroupServerRpcMixin):
@staticmethod
def get_port_from_device(context, device):
port = nvsd_db.get_port_from_device(device)
if port:
port['device'] = device
return port
class NVSDPluginV2AgentNotifierApi(sg_rpc.SecurityGroupAgentRpcApiMixin):
def __init__(self, topic):
self.topic = topic
self.topic_port_update = topics.get_topic_name(topic, topics.PORT,
topics.UPDATE)
target = oslo_messaging.Target(topic=topic, version='1.0')
self.client = n_rpc.get_client(target)
def port_update(self, context, port):
cctxt = self.client.prepare(topic=self.topic_port_update, fanout=True)
cctxt.cast(context, 'port_update', port=port)
class OneConvergencePluginV2(db_base_plugin_v2.NeutronDbPluginV2,
extraroute_db.ExtraRoute_db_mixin,
l3_agentschedulers_db.L3AgentSchedulerDbMixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin,
external_net_db.External_net_db_mixin,
l3_gwmode_db.L3_NAT_db_mixin,
portbindings_base.PortBindingBaseMixin,
SecurityGroupServerRpcMixin):
"""L2 Virtual Network Plugin.
OneConvergencePluginV2 is a Neutron plugin that provides L2 Virtual Network
functionality.
"""
__native_bulk_support = True
__native_pagination_support = True
__native_sorting_support = True
_supported_extension_aliases = ['agent',
'binding',
'dhcp_agent_scheduler',
'ext-gw-mode',
'external-net',
'extraroute',
'l3_agent_scheduler',
'quotas',
'router',
'security-group'
]
@property
def supported_extension_aliases(self):
if not hasattr(self, '_aliases'):
aliases = self._supported_extension_aliases[:]
sg_rpc.disable_security_group_extension_by_config(aliases)
self._aliases = aliases
return self._aliases
def __init__(self):
super(OneConvergencePluginV2, self).__init__()
self.oneconvergence_init()
self.base_binding_dict = {
portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS,
portbindings.VIF_DETAILS: {
portbindings.CAP_PORT_FILTER:
'security-group' in self.supported_extension_aliases}}
portbindings_base.register_port_dict_function()
self.setup_rpc()
self.network_scheduler = importutils.import_object(
cfg.CONF.network_scheduler_driver)
self.router_scheduler = importutils.import_object(
cfg.CONF.router_scheduler_driver)
self.start_periodic_dhcp_agent_status_check()
def oneconvergence_init(self):
"""Initialize the connections and set the log levels for the plugin."""
self.nvsdlib = nvsd_lib.NVSDApi()
self.nvsdlib.set_connection()
def setup_rpc(self):
# RPC support
self.service_topics = {svc_constants.CORE: topics.PLUGIN,
svc_constants.L3_ROUTER_NAT: topics.L3PLUGIN}
self.conn = n_rpc.create_connection(new=True)
self.notifier = NVSDPluginV2AgentNotifierApi(topics.AGENT)
self.agent_notifiers[n_const.AGENT_TYPE_DHCP] = (
dhcp_rpc_agent_api.DhcpAgentNotifyAPI()
)
self.agent_notifiers[n_const.AGENT_TYPE_L3] = (
l3_rpc_agent_api.L3AgentNotifyAPI()
)
self.endpoints = [securitygroups_rpc.SecurityGroupServerRpcCallback(),
dhcp_rpc.DhcpRpcCallback(),
l3_rpc.L3RpcCallback(),
agents_db.AgentExtRpcCallback(),
metadata_rpc.MetadataRpcCallback()]
for svc_topic in self.service_topics.values():
self.conn.create_consumer(svc_topic, self.endpoints, fanout=False)
# Consume from all consumers in threads
self.conn.consume_in_threads()
def create_network(self, context, network):
tenant_id = self._get_tenant_id_for_create(
context, network['network'])
self._ensure_default_security_group(context, tenant_id)
net = self.nvsdlib.create_network(network['network'])
network['network']['id'] = net['id']
with context.session.begin(subtransactions=True):
try:
neutron_net = super(OneConvergencePluginV2,
self).create_network(context, network)
#following call checks whether the network is external or not
#and if it is external then adds this network to
#externalnetworks table of neutron db
self._process_l3_create(context, neutron_net,
network['network'])
except nvsdexception.NVSDAPIException:
with excutils.save_and_reraise_exception():
self.nvsdlib.delete_network(net)
return neutron_net
def update_network(self, context, net_id, network):
with context.session.begin(subtransactions=True):
neutron_net = super(OneConvergencePluginV2,
self).update_network(context, net_id, network)
self.nvsdlib.update_network(neutron_net, network['network'])
# updates neutron database e.g. externalnetworks table.
self._process_l3_update(context, neutron_net, network['network'])
return neutron_net
def delete_network(self, context, net_id):
with context.session.begin(subtransactions=True):
network = self._get_network(context, net_id)
#get all the subnets under the network to delete them
subnets = self._get_subnets_by_network(context, net_id)
self._process_l3_delete(context, net_id)
super(OneConvergencePluginV2, self).delete_network(context,
net_id)
self.nvsdlib.delete_network(network, subnets)
def create_subnet(self, context, subnet):
if subnet['subnet']['ip_version'] == IPv6:
raise nexception.InvalidInput(
error_message="NVSDPlugin doesn't support IPv6.")
neutron_subnet = super(OneConvergencePluginV2,
self).create_subnet(context, subnet)
try:
self.nvsdlib.create_subnet(neutron_subnet)
except nvsdexception.NVSDAPIException:
with excutils.save_and_reraise_exception():
#Log the message and delete the subnet from the neutron
super(OneConvergencePluginV2,
self).delete_subnet(context, neutron_subnet['id'])
LOG.error(_LE("Failed to create subnet, "
"deleting it from neutron"))
return neutron_subnet
def delete_subnet(self, context, subnet_id):
neutron_subnet = self._get_subnet(context, subnet_id)
with context.session.begin(subtransactions=True):
super(OneConvergencePluginV2, self).delete_subnet(context,
subnet_id)
self.nvsdlib.delete_subnet(neutron_subnet)
def update_subnet(self, context, subnet_id, subnet):
with context.session.begin(subtransactions=True):
neutron_subnet = super(OneConvergencePluginV2,
self).update_subnet(context, subnet_id,
subnet)
self.nvsdlib.update_subnet(neutron_subnet, subnet)
return neutron_subnet
def create_port(self, context, port):
self._ensure_default_security_group_on_port(context, port)
sgids = self._get_security_groups_on_port(context, port)
network = {}
network_id = port['port']['network_id']
with context.session.begin(subtransactions=True):
# Invoke the Neutron API for creating port
neutron_port = super(OneConvergencePluginV2,
self).create_port(context, port)
self._process_portbindings_create_and_update(context,
port['port'],
neutron_port)
self._process_port_create_security_group(context, neutron_port,
sgids)
if port['port']['device_owner'] in ('network:router_gateway',
'network:floatingip'):
# for l3 requests, tenant_id will be None/''
network = self._get_network(context, network_id)
tenant_id = network['tenant_id']
else:
tenant_id = port['port']['tenant_id']
port_id = neutron_port['id']
try:
self.nvsdlib.create_port(tenant_id, neutron_port)
except nvsdexception.NVSDAPIException:
with excutils.save_and_reraise_exception():
LOG.error(_LE("Deleting newly created "
"neutron port %s"), port_id)
super(OneConvergencePluginV2, self).delete_port(context,
port_id)
self.notify_security_groups_member_updated(context, neutron_port)
return neutron_port
def update_port(self, context, port_id, port):
with context.session.begin(subtransactions=True):
old_port = super(OneConvergencePluginV2, self).get_port(context,
port_id)
neutron_port = super(OneConvergencePluginV2,
self).update_port(context, port_id, port)
if neutron_port['tenant_id'] == '':
network = self._get_network(context,
neutron_port['network_id'])
tenant_id = network['tenant_id']
else:
tenant_id = neutron_port['tenant_id']
self.nvsdlib.update_port(tenant_id, neutron_port, port['port'])
self._process_portbindings_create_and_update(context,
port['port'],
neutron_port)
need_port_update_notify = self.update_security_group_on_port(
context, port_id, port, old_port, neutron_port)
if need_port_update_notify:
self.notifier.port_update(context, neutron_port)
return neutron_port
def delete_port(self, context, port_id, l3_port_check=True):
if l3_port_check:
self.prevent_l3_port_deletion(context, port_id)
with context.session.begin(subtransactions=True):
neutron_port = super(OneConvergencePluginV2,
self).get_port(context, port_id)
router_ids = self.disassociate_floatingips(
context, port_id, do_notify=False)
super(OneConvergencePluginV2, self).delete_port(context, port_id)
network = self._get_network(context, neutron_port['network_id'])
neutron_port['tenant_id'] = network['tenant_id']
self.nvsdlib.delete_port(port_id, neutron_port)
# now that we've left db transaction, we are safe to notify
self.notify_routers_updated(context, router_ids)
self.notify_security_groups_member_updated(context, neutron_port)
def create_floatingip(self, context, floatingip):
neutron_floatingip = super(OneConvergencePluginV2,
self).create_floatingip(context,
floatingip)
try:
self.nvsdlib.create_floatingip(neutron_floatingip)
except nvsdexception.NVSDAPIException:
with excutils.save_and_reraise_exception():
LOG.error(_LE("Failed to create floatingip"))
super(OneConvergencePluginV2,
self).delete_floatingip(context,
neutron_floatingip['id'])
return neutron_floatingip
def update_floatingip(self, context, fip_id, floatingip):
with context.session.begin(subtransactions=True):
neutron_floatingip = super(OneConvergencePluginV2,
self).update_floatingip(context,
fip_id,
floatingip)
self.nvsdlib.update_floatingip(neutron_floatingip, floatingip)
return neutron_floatingip
def delete_floatingip(self, context, floating_ip_id):
with context.session.begin(subtransactions=True):
floating_ip = self._get_floatingip(context, floating_ip_id)
super(OneConvergencePluginV2,
self).delete_floatingip(context, floating_ip_id)
self.nvsdlib.delete_floatingip(floating_ip)
def create_router(self, context, router):
neutron_router = super(OneConvergencePluginV2,
self).create_router(context, router)
try:
self.nvsdlib.create_router(neutron_router)
except nvsdexception.NVSDAPIException:
with excutils.save_and_reraise_exception():
LOG.error(_LE("Failed to create router"))
super(OneConvergencePluginV2,
self).delete_router(context, neutron_router['id'])
return neutron_router
def update_router(self, context, router_id, router):
with context.session.begin(subtransactions=True):
neutron_router = super(OneConvergencePluginV2,
self).update_router(context, router_id,
router)
self.nvsdlib.update_router(neutron_router)
return neutron_router
def delete_router(self, context, router_id):
tenant_id = self._get_router(context, router_id)['tenant_id']
with context.session.begin(subtransactions=True):
super(OneConvergencePluginV2, self).delete_router(context,
router_id)
self.nvsdlib.delete_router(tenant_id, router_id)

View File

@ -1,176 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
import time
import mock
from oslo_config import cfg
from six import moves
import testtools
from neutron.agent.common import ovs_lib
from neutron.agent import securitygroups_rpc as sg_rpc
from neutron.common import topics
from neutron.extensions import securitygroup as ext_sg
from neutron.plugins.oneconvergence.agent import nvsd_neutron_agent
from neutron.tests import base
DAEMON_LOOP_COUNT = 5
class TestOneConvergenceAgentBase(base.BaseTestCase):
def setUp(self):
super(TestOneConvergenceAgentBase, self).setUp()
cfg.CONF.set_default('firewall_driver',
'neutron.agent.firewall.NoopFirewallDriver',
group='SECURITYGROUP')
with mock.patch('oslo_service.loopingcall.'
'FixedIntervalLoopingCall') as loopingcall:
kwargs = {'integ_br': 'integration_bridge',
'polling_interval': 5}
context = mock.Mock()
self.agent = nvsd_neutron_agent.NVSDNeutronAgent(**kwargs)
sg_plugin_rpc = sg_rpc.SecurityGroupServerRpcApi(topics.PLUGIN)
self.sg_agent = sg_rpc.SecurityGroupAgentRpc(context,
sg_plugin_rpc)
self.callback_nvsd = nvsd_neutron_agent.NVSDAgentRpcCallback(
context, self.agent, self.sg_agent)
self.loopingcall = loopingcall
class TestOneConvergenceAgentCallback(TestOneConvergenceAgentBase):
def test_port_update(self):
with mock.patch.object(ovs_lib.OVSBridge,
'get_vif_port_by_id') as get_vif_port_by_id,\
mock.patch.object(self.sg_agent,
'refresh_firewall') as refresh_firewall:
context = mock.Mock()
vifport = ovs_lib.VifPort('port1', '1', 'id-1', 'mac-1',
self.agent.int_br)
# The OVS port does not exist.
get_vif_port_by_id.return_value = None
port = {'id': 'update-port-1'}
self.callback_nvsd.port_update(context, port=port)
self.assertEqual(get_vif_port_by_id.call_count, 1)
self.assertFalse(refresh_firewall.call_count)
# The OVS port exists but no security group is associated.
get_vif_port_by_id.return_value = vifport
port = {'id': 'update-port-1'}
self.callback_nvsd.port_update(context, port=port)
self.assertEqual(get_vif_port_by_id.call_count, 2)
self.assertFalse(refresh_firewall.call_count)
# The OVS port exists but a security group is associated.
get_vif_port_by_id.return_value = vifport
port = {'id': 'update-port-1',
ext_sg.SECURITYGROUPS: ['default']}
self.callback_nvsd.port_update(context, port=port)
self.assertEqual(get_vif_port_by_id.call_count, 3)
self.assertEqual(refresh_firewall.call_count, 1)
get_vif_port_by_id.return_value = None
port = {'id': 'update-port-1',
ext_sg.SECURITYGROUPS: ['default']}
self.callback_nvsd.port_update(context, port=port)
self.assertEqual(get_vif_port_by_id.call_count, 4)
self.assertEqual(refresh_firewall.call_count, 1)
class TestNVSDAgent(TestOneConvergenceAgentBase):
def _setup_mock(self):
self.get_vif_ports = mock.patch.object(
ovs_lib.OVSBridge, 'get_vif_port_set',
return_value=set(['id-1', 'id-2'])).start()
self.prepare_devices_filter = mock.patch.object(
self.agent.sg_agent, 'prepare_devices_filter').start()
self.remove_devices_filter = mock.patch.object(
self.agent.sg_agent, 'remove_devices_filter').start()
def test_daemon_loop(self):
def state_check(index):
self.assertEqual(len(self.vif_ports_scenario[index]),
len(self.agent.ports))
# Fake time.sleep to stop the infinite loop in daemon_loop()
self.sleep_count = 0
def sleep_mock(*args, **kwargs):
state_check(self.sleep_count)
self.sleep_count += 1
if self.sleep_count >= DAEMON_LOOP_COUNT:
raise RuntimeError()
self.vif_ports_scenario = [set(), set(), set(), set(['id-1', 'id-2']),
set(['id-2', 'id-3'])]
# Ensure vif_ports_scenario is longer than DAEMON_LOOP_COUNT
if len(self.vif_ports_scenario) < DAEMON_LOOP_COUNT:
self.vif_ports_scenario.extend(
[] for _i in moves.range(DAEMON_LOOP_COUNT -
len(self.vif_ports_scenario)))
with mock.patch.object(time,
'sleep',
side_effect=sleep_mock) as sleep,\
mock.patch.object(ovs_lib.OVSBridge,
'get_vif_port_set') as get_vif_port_set,\
mock.patch.object(
self.agent.sg_agent,
'prepare_devices_filter') as prepare_devices_filter,\
mock.patch.object(
self.agent.sg_agent,
'remove_devices_filter') as remove_devices_filter:
get_vif_port_set.side_effect = self.vif_ports_scenario
with testtools.ExpectedException(RuntimeError):
self.agent.daemon_loop()
self.assertEqual(sleep.call_count, DAEMON_LOOP_COUNT)
expected = [mock.call(set(['id-1', 'id-2'])),
mock.call(set(['id-3']))]
self.assertEqual(prepare_devices_filter.call_count, 2)
prepare_devices_filter.assert_has_calls(expected)
expected = [mock.call(set([])), mock.call(set(['id-1']))]
self.assertEqual(remove_devices_filter.call_count, 2)
remove_devices_filter.assert_has_calls(expected)
sleep.assert_called_with(self.agent.polling_interval)
class TestOneConvergenceAgentMain(base.BaseTestCase):
def test_main(self):
with mock.patch.object(nvsd_neutron_agent,
'NVSDNeutronAgent') as agent,\
mock.patch.object(nvsd_neutron_agent,
'common_config') as common_config,\
mock.patch.object(nvsd_neutron_agent, 'config') as config:
config.AGENT.integration_bridge = 'br-int-dummy'
config.AGENT.polling_interval = 5
nvsd_neutron_agent.main()
self.assertTrue(common_config.setup_logging.called)
agent.assert_has_calls([
mock.call('br-int-dummy', 5),
mock.call().daemon_loop()
])

View File

@ -1,123 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
#
"""Test Library for OneConvergencePlugin."""
import uuid
import mock
from oslo_config import cfg
from neutron import context
from neutron.extensions import portbindings
from neutron import manager
from neutron.plugins.oneconvergence import plugin as nvsd_plugin
from neutron.tests.unit import _test_extension_portbindings as test_bindings
from neutron.tests.unit.db import test_db_base_plugin_v2 as test_plugin
from neutron.tests.unit.extensions import test_l3
PLUGIN_NAME = 'neutron.plugins.oneconvergence.plugin.OneConvergencePluginV2'
class OneConvergencePluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase):
_plugin_name = PLUGIN_NAME
def setUp(self):
if 'v6' in self._testMethodName:
self.skipTest("NVSD Plugin does not support IPV6.")
def mocked_oneconvergence_init(self):
def side_effect(*args, **kwargs):
return {'id': str(uuid.uuid4())}
self.nvsdlib = mock.Mock()
self.nvsdlib.create_network.side_effect = side_effect
with mock.patch.object(nvsd_plugin.OneConvergencePluginV2,
'oneconvergence_init',
new=mocked_oneconvergence_init):
super(OneConvergencePluginV2TestCase,
self).setUp(self._plugin_name)
class TestOneConvergencePluginNetworksV2(test_plugin.TestNetworksV2,
OneConvergencePluginV2TestCase):
pass
class TestOneConvergencePluginSubnetsV2(test_plugin.TestSubnetsV2,
OneConvergencePluginV2TestCase):
pass
class TestOneConvergencePluginPortsV2(test_plugin.TestPortsV2,
test_bindings.PortBindingsTestCase,
OneConvergencePluginV2TestCase):
VIF_TYPE = portbindings.VIF_TYPE_OVS
def test_port_vif_details(self):
plugin = manager.NeutronManager.get_plugin()
with self.port(name='name') as port1:
ctx = context.get_admin_context()
port = plugin.get_port(ctx, port1['port']['id'])
self.assertEqual(port['binding:vif_type'],
portbindings.VIF_TYPE_OVS)
def test_ports_vif_details(self):
cfg.CONF.set_default('allow_overlapping_ips', True)
plugin = manager.NeutronManager.get_plugin()
with self.port(), self.port():
ctx = context.get_admin_context()
ports = plugin.get_ports(ctx)
self.assertEqual(len(ports), 2)
for port in ports:
self.assertEqual(port['binding:vif_type'],
portbindings.VIF_TYPE_OVS)
class TestOneConvergenceBasicGet(test_plugin.TestBasicGet,
OneConvergencePluginV2TestCase):
pass
class TestOneConvergenceV2HTTPResponse(test_plugin.TestV2HTTPResponse,
OneConvergencePluginV2TestCase):
pass
class TestOneConvergenceL3NatTestCase(test_l3.L3NatDBIntTestCase):
_plugin_name = PLUGIN_NAME
def setUp(self):
if 'v6' in self._testMethodName:
self.skipTest("NVSD Plugin does not support IPV6.")
def mocked_oneconvergence_init(self):
def side_effect(*args, **kwargs):
return {'id': str(uuid.uuid4())}
self.nvsdlib = mock.Mock()
self.nvsdlib.create_network.side_effect = side_effect
ext_mgr = test_l3.L3TestExtensionManager()
with mock.patch.object(nvsd_plugin.OneConvergencePluginV2,
'oneconvergence_init',
new=mocked_oneconvergence_init):
super(TestOneConvergenceL3NatTestCase,
self).setUp(plugin=self._plugin_name, ext_mgr=ext_mgr)
def test_floatingip_with_invalid_create_port(self):
self._test_floatingip_with_invalid_create_port(self._plugin_name)

View File

@ -1,267 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
#
import mock
from oslo_serialization import jsonutils
from neutron.plugins.oneconvergence.lib import nvsdlib
from neutron.tests import base
NETWORKS_URI = "/pluginhandler/ocplugin/tenant/%s/lnetwork/"
NETWORK_URI = NETWORKS_URI + "%s"
GET_ALL_NETWORKS = "/pluginhandler/ocplugin/tenant/getallnetworks"
SUBNETS_URI = NETWORK_URI + "/lsubnet/"
SUBNET_URI = SUBNETS_URI + "%s"
GET_ALL_SUBNETS = "/pluginhandler/ocplugin/tenant/getallsubnets"
PORTS_URI = NETWORK_URI + "/lport/"
PORT_URI = PORTS_URI + "%s"
EXT_URI = "/pluginhandler/ocplugin/ext/tenant/%s"
FLOATING_IPS_URI = EXT_URI + "/floatingip/"
FLOATING_IP_URI = FLOATING_IPS_URI + "%s"
ROUTERS_URI = EXT_URI + "/lrouter/"
ROUTER_URI = ROUTERS_URI + "%s"
TEST_NET = 'test-network'
TEST_SUBNET = 'test-subnet'
TEST_PORT = 'test-port'
TEST_FIP = 'test-floatingip'
TEST_ROUTER = 'test-router'
TEST_TENANT = 'test-tenant'
class TestNVSDApi(base.BaseTestCase):
def setUp(self):
super(TestNVSDApi, self).setUp()
self.nvsdlib = nvsdlib.NVSDApi()
def test_create_network(self):
network_obj = {
"name": 'test-net',
"tenant_id": TEST_TENANT,
"shared": False,
"admin_state_up": True,
"router:external": False
}
resp = mock.Mock()
resp.json.return_value = {'id': 'uuid'}
with mock.patch.object(self.nvsdlib, 'send_request',
return_value=resp) as send_request:
uri = NETWORKS_URI % TEST_TENANT
net = self.nvsdlib.create_network(network_obj)
send_request.assert_called_once_with(
"POST", uri,
body=jsonutils.dumps(network_obj),
resource='network',
tenant_id=TEST_TENANT)
self.assertEqual(net, {'id': 'uuid'})
def test_update_network(self):
network = {'id': TEST_NET,
'tenant_id': TEST_TENANT}
update_network = {'name': 'new_name'}
uri = NETWORK_URI % (TEST_TENANT, TEST_NET)
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.update_network(network, update_network)
send_request.assert_called_once_with(
"PUT", uri, body=jsonutils.dumps(update_network),
resource='network', tenant_id=TEST_TENANT,
resource_id=TEST_NET)
def test_delete_network(self):
network = {'id': TEST_NET,
'tenant_id': TEST_TENANT}
uri = NETWORK_URI % (TEST_TENANT, TEST_NET)
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
with mock.patch.object(self.nvsdlib, '_get_ports'):
self.nvsdlib.delete_network(network)
send_request.assert_called_once_with(
"DELETE", uri, resource='network',
tenant_id=TEST_TENANT, resource_id=TEST_NET)
def test_create_port(self):
path = PORTS_URI % (TEST_TENANT, TEST_NET)
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
fixed_ips = [{'ip_address': '10.0.0.2',
'subnet_id': TEST_SUBNET}]
lport = {
"id": TEST_PORT,
"name": 'test',
"device_id": "device_id",
"device_owner": "device_owner",
"mac_address": "mac_address",
"fixed_ips": fixed_ips,
"admin_state_up": True,
"network_id": TEST_NET,
"status": 'ACTIVE'
}
self.nvsdlib.create_port(TEST_TENANT, lport)
expected = {"id": TEST_PORT, "name": 'test',
"device_id": "device_id",
"device_owner": "device_owner",
"mac_address": "mac_address",
"ip_address": '10.0.0.2',
"subnet_id": TEST_SUBNET,
"admin_state_up": True,
"network_id": TEST_NET,
"status": 'ACTIVE'}
send_request.assert_called_once_with(
"POST", path,
body=jsonutils.dumps(expected),
resource='port',
tenant_id=TEST_TENANT)
def test_update_port(self):
port = {'id': TEST_PORT,
'network_id': TEST_NET}
port_update = {'name': 'new-name'}
uri = PORT_URI % (TEST_TENANT, TEST_NET, TEST_PORT)
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.update_port(TEST_TENANT, port, port_update)
send_request.assert_called_once_with(
"PUT", uri,
body=jsonutils.dumps(port_update),
resource='port',
resource_id='test-port',
tenant_id=TEST_TENANT)
def test_delete_port(self):
port = {'network_id': TEST_NET,
'tenant_id': TEST_TENANT}
uri = PORT_URI % (TEST_TENANT, TEST_NET, TEST_PORT)
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.delete_port(TEST_PORT, port)
send_request.assert_called_once_with("DELETE", uri,
resource='port',
tenant_id=TEST_TENANT,
resource_id=TEST_PORT)
def test_create_subnet(self):
subnet = {'id': TEST_SUBNET,
'tenant_id': TEST_TENANT,
'network_id': TEST_NET}
uri = SUBNETS_URI % (TEST_TENANT, TEST_NET)
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.create_subnet(subnet)
send_request.assert_called_once_with("POST", uri,
body=jsonutils.dumps(subnet),
resource='subnet',
tenant_id=TEST_TENANT)
def test_update_subnet(self):
subnet = {'id': TEST_SUBNET,
'tenant_id': TEST_TENANT,
'network_id': TEST_NET}
subnet_update = {'name': 'new-name'}
uri = SUBNET_URI % (TEST_TENANT, TEST_NET, TEST_SUBNET)
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.update_subnet(subnet, subnet_update)
send_request.assert_called_once_with(
"PUT", uri,
body=jsonutils.dumps(subnet_update), resource='subnet',
tenant_id=TEST_TENANT, resource_id=TEST_SUBNET)
def test_delete_subnet(self):
subnet = {'id': TEST_SUBNET,
'tenant_id': TEST_TENANT,
'network_id': TEST_NET}
uri = SUBNET_URI % (TEST_TENANT, TEST_NET, TEST_SUBNET)
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.delete_subnet(subnet)
send_request.assert_called_once_with("DELETE", uri,
resource='subnet',
tenant_id=TEST_TENANT,
resource_id=TEST_SUBNET)
def test_create_floatingip(self):
floatingip = {'id': TEST_FIP,
'tenant_id': TEST_TENANT}
uri = FLOATING_IPS_URI % TEST_TENANT
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.create_floatingip(floatingip)
send_request.assert_called_once_with(
"POST", uri,
body=jsonutils.dumps(floatingip),
resource='floating_ip',
tenant_id=TEST_TENANT)
def test_update_floatingip(self):
floatingip = {'id': TEST_FIP,
'tenant_id': TEST_TENANT}
uri = FLOATING_IP_URI % (TEST_TENANT, TEST_FIP)
floatingip_update = {'floatingip': {'router_id': TEST_ROUTER}}
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.update_floatingip(floatingip, floatingip_update)
send_request.assert_called_once_with(
"PUT", uri,
body=jsonutils.dumps(floatingip_update['floatingip']),
resource='floating_ip', tenant_id=TEST_TENANT,
resource_id=TEST_FIP)
def test_delete_floatingip(self):
floatingip = {'id': TEST_FIP,
'tenant_id': TEST_TENANT}
uri = FLOATING_IP_URI % (TEST_TENANT, TEST_FIP)
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.delete_floatingip(floatingip)
send_request.assert_called_once_with(
"DELETE", uri, resource='floating_ip', tenant_id=TEST_TENANT,
resource_id=TEST_FIP)
def test_create_router(self):
router = {'id': TEST_ROUTER, 'tenant_id': TEST_TENANT}
uri = ROUTERS_URI % TEST_TENANT
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.create_router(router)
send_request.assert_called_once_with(
"POST", uri, body=jsonutils.dumps(router), resource='router',
tenant_id=TEST_TENANT)
def test_update_router(self):
router = {'id': TEST_ROUTER, 'tenant_id': TEST_TENANT}
uri = ROUTER_URI % (TEST_TENANT, TEST_ROUTER)
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.update_router(router)
send_request.assert_called_once_with(
"PUT", uri, body=jsonutils.dumps(router),
resource='router', tenant_id=TEST_TENANT,
resource_id=TEST_ROUTER)
def test_delete_router(self):
uri = ROUTER_URI % (TEST_TENANT, TEST_ROUTER)
with mock.patch.object(self.nvsdlib, 'send_request') as send_request:
self.nvsdlib.delete_router(TEST_TENANT, TEST_ROUTER)
send_request.assert_called_once_with(
"DELETE", uri, resource='router',
tenant_id=TEST_TENANT, resource_id=TEST_ROUTER)

View File

@ -1,59 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
import mock
from oslo_serialization import jsonutils
import requests
from neutron.plugins.oneconvergence.lib import config # noqa
from neutron.plugins.oneconvergence.lib import plugin_helper as client
from neutron.tests import base
class TestPluginHelper(base.BaseTestCase):
def setUp(self):
super(TestPluginHelper, self).setUp()
self.nvsdcontroller = client.NVSDController()
def get_response(self, *args, **kwargs):
response = mock.Mock()
response.status_code = requests.codes.ok
response.content = jsonutils.dumps({'session_uuid': 'new_auth_token'})
return response
def test_login(self):
login_url = ('http://127.0.0.1:8082/pluginhandler/ocplugin/'
'authmgmt/login')
headers = {'Content-Type': 'application/json'}
data = jsonutils.dumps({"user_name": "ocplugin", "passwd": "oc123"})
timeout = 30.0
with mock.patch.object(self.nvsdcontroller.pool, 'request',
side_effect=self.get_response) as request:
self.nvsdcontroller.login()
request.assert_called_once_with('POST', url=login_url,
headers=headers, data=data,
timeout=timeout)
def test_request(self):
with mock.patch.object(self.nvsdcontroller.pool, 'request',
side_effect=self.get_response) as request:
self.nvsdcontroller.login()
self.nvsdcontroller.request("POST", "/some_url")
self.assertEqual(request.call_count, 2)
request.assert_called_with(
'POST',
url='http://127.0.0.1:8082/some_url?authToken=new_auth_token',
headers={'Content-Type': 'application/json'}, data='',
timeout=30.0)

View File

@ -1,106 +0,0 @@
# Copyright 2014 OneConvergence, Inc. All Rights Reserved.
#
# 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.
import uuid
import mock
from neutron.extensions import securitygroup as ext_sg
from neutron import manager
from neutron.plugins.oneconvergence import plugin as nvsd_plugin
from neutron.tests import tools
from neutron.tests.unit.agent import test_securitygroups_rpc as test_sg_rpc
from neutron.tests.unit.extensions import test_securitygroup as test_sg
PLUGIN_NAME = ('neutron.plugins.oneconvergence.'
'plugin.OneConvergencePluginV2')
AGENTNOTIFIER = ('neutron.plugins.oneconvergence.'
'plugin.NVSDPluginV2AgentNotifierApi')
DUMMY_NVSD_LIB = ('neutron.tests.unit.plugins.oneconvergence.'
'dummynvsdlib.NVSDApi')
class OneConvergenceSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase):
_plugin_name = PLUGIN_NAME
def setUp(self):
if 'v6' in self._testMethodName:
self.skipTest("NVSD Plugin does not support IPV6.")
def mocked_oneconvergence_init(self):
def side_effect(*args, **kwargs):
return {'id': str(uuid.uuid4())}
self.nvsdlib = mock.Mock()
self.nvsdlib.create_network.side_effect = side_effect
test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_HYBRID_DRIVER)
notifier_cls = mock.patch(AGENTNOTIFIER).start()
self.notifier = mock.Mock()
notifier_cls.return_value = self.notifier
self.useFixture(tools.AttributeMapMemento())
with mock.patch.object(nvsd_plugin.OneConvergencePluginV2,
'oneconvergence_init',
new=mocked_oneconvergence_init):
super(OneConvergenceSecurityGroupsTestCase,
self).setUp(PLUGIN_NAME)
def tearDown(self):
super(OneConvergenceSecurityGroupsTestCase, self).tearDown()
class TestOneConvergenceSGServerRpcCallBack(
OneConvergenceSecurityGroupsTestCase,
test_sg_rpc.SGServerRpcCallBackTestCase):
pass
class TestOneConvergenceSecurityGroups(OneConvergenceSecurityGroupsTestCase,
test_sg.TestSecurityGroups,
test_sg_rpc.SGNotificationTestMixin):
def test_security_group_get_port_from_device(self):
with self.network() as n:
with self.subnet(n):
with self.security_group() as sg:
security_group_id = sg['security_group']['id']
res = self._create_port(self.fmt, n['network']['id'])
port = self.deserialize(self.fmt, res)
fixed_ips = port['port']['fixed_ips']
data = {'port': {'fixed_ips': fixed_ips,
'name': port['port']['name'],
ext_sg.SECURITYGROUPS:
[security_group_id]}}
req = self.new_update_request('ports', data,
port['port']['id'])
res = self.deserialize(self.fmt,
req.get_response(self.api))
port_id = res['port']['id']
plugin = manager.NeutronManager.get_plugin()
port_dict = plugin.get_port_from_device(mock.Mock(),
port_id)
self.assertEqual(port_id, port_dict['id'])
self.assertEqual([security_group_id],
port_dict[ext_sg.SECURITYGROUPS])
self.assertEqual([], port_dict['security_group_rules'])
self.assertEqual([fixed_ips[0]['ip_address']],
port_dict['fixed_ips'])
self._delete('ports', port_id)
def test_security_group_get_port_from_device_with_no_port(self):
plugin = manager.NeutronManager.get_plugin()
port_dict = plugin.get_port_from_device(mock.Mock(), 'bad_device_id')
self.assertIsNone(port_dict)

View File

@ -66,7 +66,6 @@ data_files =
etc/neutron/plugins/ml2/sriov_agent.ini
etc/neutron/plugins/mlnx = etc/neutron/plugins/mlnx/mlnx_conf.ini
etc/neutron/plugins/nuage = etc/neutron/plugins/nuage/nuage_plugin.ini
etc/neutron/plugins/oneconvergence = etc/neutron/plugins/oneconvergence/nvsdplugin.ini
etc/neutron/plugins/ovsvapp = etc/neutron/plugins/ovsvapp/ovsvapp_agent.ini
scripts =
bin/neutron-rootwrap-xen-dom0
@ -87,7 +86,6 @@ console_scripts =
neutron-netns-cleanup = neutron.cmd.netns_cleanup:main
neutron-ns-metadata-proxy = neutron.cmd.eventlet.agents.metadata_proxy:main
neutron-ovsvapp-agent = neutron.cmd.eventlet.plugins.ovsvapp_neutron_agent:main
neutron-nvsd-agent = neutron.plugins.oneconvergence.agent.nvsd_neutron_agent:main
neutron-openvswitch-agent = neutron.cmd.eventlet.plugins.ovs_neutron_agent:main
neutron-ovs-cleanup = neutron.cmd.ovs_cleanup:main
neutron-pd-notify = neutron.cmd.pd_notify:main
@ -107,7 +105,6 @@ neutron.core_plugins =
embrane = neutron.plugins.embrane.plugins.embrane_ml2_plugin:EmbraneMl2Plugin
ml2 = neutron.plugins.ml2.plugin:Ml2Plugin
nuage = neutron.plugins.nuage.plugin:NuagePlugin
oneconvergence = neutron.plugins.oneconvergence.plugin:OneConvergencePluginV2
neutron.service_plugins =
dummy = neutron.tests.unit.dummy_plugin:DummyServicePlugin
router = neutron.services.l3_router.l3_router_plugin:L3RouterPlugin

View File

@ -16,7 +16,6 @@ ignore_regexes=(
"^plugins/brocade.*$"
"^plugins/embrane.*$"
"^plugins/ibm.*$"
"^plugins/oneconvergence.*$"
# The following open source plugin tests are not actually unit
# tests and are ignored pending their relocation to the functional
# test tree.