Merge "PLUMgrid quantum plugin"
This commit is contained in:
commit
13f4ed7524
39
etc/quantum/plugins/plumgrid/plumgrid.ini
Normal file
39
etc/quantum/plugins/plumgrid/plumgrid.ini
Normal file
@ -0,0 +1,39 @@
|
||||
# Config file for Quantum PLUMgrid plugin
|
||||
|
||||
[DATABASE]
|
||||
# This line MUST be changed to actually run the plugin.
|
||||
# Example:
|
||||
# sql_connection = mysql://<user>:<pass>@<host>:3306/plumgrid_quantum
|
||||
# Replace <host> above with the IP address of the database used by the
|
||||
# main quantum server.
|
||||
# sql_connection = sqlite://
|
||||
# Database reconnection retry times - in event connectivity is lost
|
||||
# set to -1 implies an infinite retry count
|
||||
# sql_max_retries = 10
|
||||
# Database reconnection interval in seconds - if the initial connection to the
|
||||
# database fails
|
||||
# reconnect_interval = 2
|
||||
# Enable the use of eventlet's db_pool for MySQL. The flags sql_min_pool_size,
|
||||
# sql_max_pool_size and sql_idle_timeout are relevant only if this is enabled.
|
||||
# sql_dbpool_enable = False
|
||||
# Minimum number of SQL connections to keep open in a pool
|
||||
# sql_min_pool_size = 1
|
||||
# Maximum number of SQL connections to keep open in a pool
|
||||
# sql_max_pool_size = 5
|
||||
# Timeout in seconds before idle sql connections are reaped
|
||||
# sql_idle_timeout = 3600
|
||||
|
||||
[PLUMgridNOS]
|
||||
# This line should be pointing to the NOS server,
|
||||
# for the PLUMgrid platform. In other deployments,
|
||||
# this is known as controller
|
||||
# nos_server=<nos-ip-address>
|
||||
# nos_server_port=<nos-port>
|
||||
# Authentification parameters for the NOS server.
|
||||
# These are the admin credentials to manage and control
|
||||
# the NOS server.
|
||||
# username=<nos-admin-username>
|
||||
# password=<nos-admin-password>
|
||||
# servertimeout=5
|
||||
# Name of the network topology to be deployed by NOS
|
||||
# topologyname=<nos-topology-name>
|
7
quantum/plugins/plumgrid/README
Normal file
7
quantum/plugins/plumgrid/README
Normal file
@ -0,0 +1,7 @@
|
||||
PLUMgrid Quantum Virtual Network Plugin
|
||||
|
||||
This plugin implements Quantum v2 APIs and helps configure
|
||||
L2/L3 virtual networks consisting of PLUMgrid Platform.
|
||||
|
||||
For more details on use please refer to:
|
||||
http://wiki.openstack.org/plumgrid-quantum
|
17
quantum/plugins/plumgrid/__init__.py
Normal file
17
quantum/plugins/plumgrid/__init__.py
Normal file
@ -0,0 +1,17 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright 2013 PLUMgrid, 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.
|
||||
#
|
||||
# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc.
|
17
quantum/plugins/plumgrid/common/__init__.py
Normal file
17
quantum/plugins/plumgrid/common/__init__.py
Normal file
@ -0,0 +1,17 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright 2013 PLUMgrid, 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.
|
||||
#
|
||||
# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc.
|
31
quantum/plugins/plumgrid/common/exceptions.py
Normal file
31
quantum/plugins/plumgrid/common/exceptions.py
Normal file
@ -0,0 +1,31 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright 2013 PLUMgrid, 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.
|
||||
#
|
||||
# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc.
|
||||
|
||||
|
||||
""" Quantum PLUMgrid Plugin exceptions """
|
||||
|
||||
from quantum.common import exceptions as base_exec
|
||||
|
||||
|
||||
class PLUMgridException(base_exec.QuantumException):
|
||||
message = _("An unexpected error occurred in the PLUMgrid Plugin: "
|
||||
"%(err_msg)s")
|
||||
|
||||
|
||||
class PLUMgridConnectionFailed(PLUMgridException):
|
||||
message = _("Connection failed with PLUMgrid NOS: %(err_msg)s")
|
17
quantum/plugins/plumgrid/plumgrid_nos_plugin/__init__.py
Normal file
17
quantum/plugins/plumgrid/plumgrid_nos_plugin/__init__.py
Normal file
@ -0,0 +1,17 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright 2013 PLUMgrid, 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.
|
||||
#
|
||||
# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc.
|
19
quantum/plugins/plumgrid/plumgrid_nos_plugin/plugin_ver.py
Normal file
19
quantum/plugins/plumgrid/plumgrid_nos_plugin/plugin_ver.py
Normal file
@ -0,0 +1,19 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright 2013 PLUMgrid, 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.
|
||||
#
|
||||
# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc.
|
||||
|
||||
VERSION = "0.1"
|
@ -0,0 +1,44 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# Copyright 2013 PLUMgrid, 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.
|
||||
#
|
||||
# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc.
|
||||
# @author: Brenden Blanco, bblanco@plumgrid.com, PLUMgrid, Inc.
|
||||
|
||||
"""
|
||||
Snippets needed by the PLUMgrid Plugin
|
||||
"""
|
||||
|
||||
from quantum.openstack.common import log as logging
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DataNOSPLUMgrid():
|
||||
|
||||
BASE_NOS_URL = '/0/connectivity/domain/'
|
||||
|
||||
def __init__(self):
|
||||
LOG.info(_('QuantumPluginPLUMgrid Status: NOS Body Data Creation'))
|
||||
|
||||
def create_domain_body_data(self, tenant_id):
|
||||
body_data = {"container_group": tenant_id}
|
||||
return body_data
|
||||
|
||||
def create_network_body_data(self, tenant_id, topology_name):
|
||||
body_data = {"config_template": "single_bridge",
|
||||
"container_group": tenant_id,
|
||||
"topology_name": topology_name}
|
||||
return body_data
|
344
quantum/plugins/plumgrid/plumgrid_nos_plugin/plumgrid_plugin.py
Normal file
344
quantum/plugins/plumgrid/plumgrid_nos_plugin/plumgrid_plugin.py
Normal file
@ -0,0 +1,344 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# Copyright 2013 PLUMgrid, 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.
|
||||
#
|
||||
# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc.
|
||||
|
||||
"""
|
||||
Quantum PLUMgrid Plug-in for PLUMgrid Virtual Technology
|
||||
This plugin will forward authenticated REST API calls
|
||||
to the Network Operating System by PLUMgrid called NOS
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
from quantum.db import api as db
|
||||
from quantum.db import db_base_plugin_v2
|
||||
from quantum.openstack.common import cfg
|
||||
from quantum.openstack.common import log as logging
|
||||
from quantum.plugins.plumgrid.common import exceptions as plum_excep
|
||||
from quantum.plugins.plumgrid.plumgrid_nos_plugin import plumgrid_nos_snippets
|
||||
from quantum.plugins.plumgrid.plumgrid_nos_plugin import rest_connection
|
||||
from quantum.plugins.plumgrid.plumgrid_nos_plugin.plugin_ver import VERSION
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
nos_server_opts = [
|
||||
cfg.StrOpt('nos_server', default='localhost',
|
||||
help=_("PLUMgrid NOS server to connect to")),
|
||||
cfg.StrOpt('nos_server_port', default='8080',
|
||||
help=_("PLUMgrid NOS server port to connect to")),
|
||||
cfg.StrOpt('username', default='username',
|
||||
help=_("PLUMgrid NOS admin username")),
|
||||
cfg.StrOpt('password', default='password', secret=True,
|
||||
help=_("PLUMgrid NOS admin password")),
|
||||
cfg.IntOpt('servertimeout', default=5,
|
||||
help=_("PLUMgrid NOS server timeout")),
|
||||
cfg.IntOpt('topologyname', default='t1',
|
||||
help=_("PLUMgrid NOS topology name")), ]
|
||||
|
||||
|
||||
cfg.CONF.register_opts(nos_server_opts, "PLUMgridNOS")
|
||||
|
||||
|
||||
class QuantumPluginPLUMgridV2(db_base_plugin_v2.QuantumDbPluginV2):
|
||||
|
||||
def __init__(self):
|
||||
LOG.info(_('QuantumPluginPLUMgrid Status: Starting Plugin'))
|
||||
|
||||
# PLUMgrid NOS configuration
|
||||
nos_plumgrid = cfg.CONF.PLUMgridNOS.nos_server
|
||||
nos_port = cfg.CONF.PLUMgridNOS.nos_server_port
|
||||
timeout = cfg.CONF.PLUMgridNOS.servertimeout
|
||||
self.topology_name = cfg.CONF.PLUMgridNOS.topologyname
|
||||
self.snippets = plumgrid_nos_snippets.DataNOSPLUMgrid()
|
||||
|
||||
# TODO: (Edgar) These are placeholders for next PLUMgrid release
|
||||
nos_username = cfg.CONF.PLUMgridNOS.username
|
||||
nos_password = cfg.CONF.PLUMgridNOS.password
|
||||
self.rest_conn = rest_connection.RestConnection(nos_plumgrid,
|
||||
nos_port, timeout)
|
||||
if self.rest_conn is None:
|
||||
raise SystemExit(_('QuantumPluginPLUMgrid Status: '
|
||||
'Aborting Plugin'))
|
||||
|
||||
else:
|
||||
# Plugin DB initialization
|
||||
db.configure_db()
|
||||
|
||||
# PLUMgrid NOS info validation
|
||||
LOG.info(_('QuantumPluginPLUMgrid NOS: %s'), nos_plumgrid)
|
||||
if not nos_plumgrid:
|
||||
raise SystemExit(_('QuantumPluginPLUMgrid Status: '
|
||||
'NOS value is missing in config file'))
|
||||
|
||||
LOG.debug(_('QuantumPluginPLUMgrid Status: Quantum server with '
|
||||
'PLUMgrid Plugin has started'))
|
||||
|
||||
def create_network(self, context, network):
|
||||
"""
|
||||
Create network core Quantum API
|
||||
"""
|
||||
|
||||
LOG.debug(_('QuantumPluginPLUMgrid Status: create_network() called'))
|
||||
|
||||
# Plugin DB - Network Create and validation
|
||||
tenant_id = self._get_tenant_id_for_create(context,
|
||||
network["network"])
|
||||
self._network_admin_state(network)
|
||||
|
||||
with context.session.begin(subtransactions=True):
|
||||
net = super(QuantumPluginPLUMgridV2, self).create_network(context,
|
||||
network)
|
||||
|
||||
try:
|
||||
LOG.debug(_('QuantumPluginPLUMgrid Status: %s, %s, %s'),
|
||||
tenant_id, network["network"], net["id"])
|
||||
nos_url = self.snippets.BASE_NOS_URL + net["id"]
|
||||
headers = {}
|
||||
body_data = self.snippets.create_domain_body_data(tenant_id)
|
||||
self.rest_conn.nos_rest_conn(nos_url,
|
||||
'PUT', body_data, headers)
|
||||
|
||||
except:
|
||||
err_message = _("PLUMgrid NOS communication failed")
|
||||
LOG.Exception(err_message)
|
||||
raise plum_excep.PLUMgridException(err_message)
|
||||
|
||||
# return created network
|
||||
return net
|
||||
|
||||
def update_network(self, context, net_id, network):
|
||||
"""
|
||||
Update network core Quantum API
|
||||
"""
|
||||
|
||||
LOG.debug(_("QuantumPluginPLUMgridV2.update_network() called"))
|
||||
self._network_admin_state(network)
|
||||
tenant_id = self._get_tenant_id_for_create(context, network["network"])
|
||||
|
||||
# Get initial network details
|
||||
original_net = super(QuantumPluginPLUMgridV2, self).get_network(
|
||||
context, net_id)
|
||||
|
||||
with context.session.begin(subtransactions=True):
|
||||
# Plugin DB - Network Update
|
||||
new_network = super(
|
||||
QuantumPluginPLUMgridV2, self).update_network(context,
|
||||
net_id, network)
|
||||
|
||||
try:
|
||||
# PLUMgrid Server does not support updating resources yet
|
||||
nos_url = self.snippets.BASE_NOS_URL + net_id
|
||||
headers = {}
|
||||
body_data = {}
|
||||
self.rest_conn.nos_rest_conn(nos_url,
|
||||
'DELETE', body_data, headers)
|
||||
nos_url = self.snippets.BASE_NOS_URL + new_network["id"]
|
||||
body_data = self.snippets.create_domain_body_data(tenant_id)
|
||||
self.rest_conn.nos_rest_conn(nos_url,
|
||||
'PUT', body_data, headers)
|
||||
except:
|
||||
err_message = _("PLUMgrid NOS communication failed")
|
||||
LOG.Exception(err_message)
|
||||
raise plum_excep.PLUMgridException(err_message)
|
||||
|
||||
# return updated network
|
||||
return new_network
|
||||
|
||||
def delete_network(self, context, net_id):
|
||||
"""
|
||||
Delete network core Quantum API
|
||||
"""
|
||||
LOG.debug(_("QuantumPluginPLUMgrid Status: delete_network() called"))
|
||||
super(QuantumPluginPLUMgridV2, self).get_network(context, net_id)
|
||||
|
||||
with context.session.begin(subtransactions=True):
|
||||
# Plugin DB - Network Delete
|
||||
net_deleted = super(QuantumPluginPLUMgridV2,
|
||||
self).delete_network(context, net_id)
|
||||
|
||||
try:
|
||||
nos_url = self.snippets.BASE_NOS_URL + net_id
|
||||
headers = {}
|
||||
body_data = {}
|
||||
self.rest_conn.nos_rest_conn(nos_url,
|
||||
'DELETE', body_data, headers)
|
||||
except:
|
||||
err_message = _("PLUMgrid NOS communication failed")
|
||||
LOG.Exception(err_message)
|
||||
raise plum_excep.PLUMgridException(err_message)
|
||||
|
||||
def create_port(self, context, port):
|
||||
"""
|
||||
Create port core Quantum API
|
||||
"""
|
||||
LOG.debug(_("QuantumPluginPLUMgrid Status: create_port() called"))
|
||||
|
||||
# Port operations on PLUMgrid NOS is an automatic operation from the
|
||||
# VIF driver operations in Nova. It requires admin_state_up to be True
|
||||
port["port"]["admin_state_up"] = True
|
||||
|
||||
# Plugin DB - Port Create and Return port
|
||||
return super(QuantumPluginPLUMgridV2, self).create_port(context,
|
||||
port)
|
||||
|
||||
def update_port(self, context, port_id, port):
|
||||
"""
|
||||
Update port core Quantum API
|
||||
|
||||
"""
|
||||
LOG.debug(_("QuantumPluginPLUMgrid Status: update_port() called"))
|
||||
|
||||
# Port operations on PLUMgrid NOS is an automatic operation from the
|
||||
# VIF driver operations in Nova.
|
||||
|
||||
# Plugin DB - Port Update
|
||||
return super(QuantumPluginPLUMgridV2, self).update_port(
|
||||
context, port_id, port)
|
||||
|
||||
def delete_port(self, context, port_id):
|
||||
"""
|
||||
Delete port core Quantum API
|
||||
"""
|
||||
|
||||
LOG.debug(_("QuantumPluginPLUMgrid Status: delete_port() called"))
|
||||
|
||||
# Port operations on PLUMgrid NOS is an automatic operation from the
|
||||
# VIF driver operations in Nova.
|
||||
|
||||
# Plugin DB - Port Delete
|
||||
super(QuantumPluginPLUMgridV2, self).delete_port(context, port_id)
|
||||
|
||||
def create_subnet(self, context, subnet):
|
||||
"""
|
||||
Create subnet core Quantum API
|
||||
"""
|
||||
|
||||
LOG.debug(_("QuantumPluginPLUMgrid Status: create_subnet() called"))
|
||||
|
||||
with context.session.begin(subtransactions=True):
|
||||
# Plugin DB - Subnet Create
|
||||
subnet = super(QuantumPluginPLUMgridV2, self).create_subnet(
|
||||
context, subnet)
|
||||
subnet_details = self._get_subnet(context, subnet["id"])
|
||||
net_id = subnet_details["network_id"]
|
||||
tenant_id = subnet_details["tenant_id"]
|
||||
|
||||
try:
|
||||
nos_url = self.snippets.BASE_NOS_URL + net_id
|
||||
headers = {}
|
||||
body_data = self.snippets.create_network_body_data(
|
||||
tenant_id, self.topology_name)
|
||||
self.rest_conn.nos_rest_conn(nos_url,
|
||||
'PUT', body_data, headers)
|
||||
except:
|
||||
err_message = _("PLUMgrid NOS communication failed: ")
|
||||
LOG.Exception(err_message)
|
||||
raise plum_excep.PLUMgridException(err_message)
|
||||
|
||||
return subnet
|
||||
|
||||
def delete_subnet(self, context, subnet_id):
|
||||
"""
|
||||
Delete subnet core Quantum API
|
||||
"""
|
||||
|
||||
LOG.debug(_("QuantumPluginPLUMgrid Status: delete_subnet() called"))
|
||||
#Collecting subnet info
|
||||
subnet_details = self._get_subnet(context, subnet_id)
|
||||
|
||||
with context.session.begin(subtransactions=True):
|
||||
# Plugin DB - Subnet Delete
|
||||
del_subnet = super(QuantumPluginPLUMgridV2, self).delete_subnet(
|
||||
context, subnet_id)
|
||||
try:
|
||||
headers = {}
|
||||
body_data = {}
|
||||
net_id = subnet_details["network_id"]
|
||||
self._cleaning_nos_subnet_structure(body_data, headers, net_id)
|
||||
except:
|
||||
err_message = _("PLUMgrid NOS communication failed: ")
|
||||
LOG.Exception(err_message)
|
||||
raise plum_excep.PLUMgridException(err_message)
|
||||
|
||||
return del_subnet
|
||||
|
||||
def update_subnet(self, context, subnet_id, subnet):
|
||||
"""
|
||||
Update subnet core Quantum API
|
||||
"""
|
||||
|
||||
LOG.debug(_("update_subnet() called"))
|
||||
#Collecting subnet info
|
||||
initial_subnet = self._get_subnet(context, subnet_id)
|
||||
net_id = initial_subnet["network_id"]
|
||||
tenant_id = initial_subnet["tenant_id"]
|
||||
|
||||
with context.session.begin(subtransactions=True):
|
||||
# Plugin DB - Subnet Update
|
||||
new_subnet = super(QuantumPluginPLUMgridV2, self).update_subnet(
|
||||
context, subnet_id, subnet)
|
||||
|
||||
try:
|
||||
# PLUMgrid Server does not support updating resources yet
|
||||
headers = {}
|
||||
body_data = {}
|
||||
self._cleaning_nos_subnet_structure(body_data, headers, net_id)
|
||||
nos_url = self.snippets.BASE_NOS_URL + net_id
|
||||
body_data = self.snippets.create_network_body_data(
|
||||
tenant_id, self.topology_name)
|
||||
self.rest_conn.nos_rest_conn(nos_url,
|
||||
'PUT', body_data, headers)
|
||||
|
||||
except:
|
||||
err_message = _("PLUMgrid NOS communication failed: ")
|
||||
LOG.Exception(err_message)
|
||||
raise plum_excep.PLUMgridException(err_message)
|
||||
|
||||
return new_subnet
|
||||
|
||||
"""
|
||||
Extension API implementation
|
||||
"""
|
||||
# TODO: (Edgar) Complete extensions for PLUMgrid
|
||||
|
||||
"""
|
||||
Internal PLUMgrid fuctions
|
||||
"""
|
||||
|
||||
def _get_plugin_version(self):
|
||||
return VERSION
|
||||
|
||||
def _cleaning_nos_subnet_structure(self, body_data, headers, net_id):
|
||||
domain_structure = ['/properties', '/link', '/ne']
|
||||
for structure in domain_structure:
|
||||
nos_url = self.snippets.BASE_NOS_URL + net_id + structure
|
||||
self.rest_conn.nos_rest_conn(nos_url, 'DELETE', body_data, headers)
|
||||
|
||||
def _network_admin_state(self, network):
|
||||
try:
|
||||
if network["network"].get("admin_state_up"):
|
||||
network_name = network["network"]["name"]
|
||||
if network["network"]["admin_state_up"] is False:
|
||||
LOG.warning(_("Network with admin_state_up=False are not "
|
||||
"supported yet by this plugin. Ignoring "
|
||||
"setting for network %s"), network_name)
|
||||
except:
|
||||
err_message = _("Network Admin State Validation Falied: ")
|
||||
LOG.Exception(err_message)
|
||||
raise plum_excep.PLUMgridException(err_message)
|
||||
return network
|
@ -0,0 +1,92 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# Copyright 2013 PLUMgrid, 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.
|
||||
#
|
||||
# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc.
|
||||
# @author: Brenden Blanco, bblanco@plumgrid.com, PLUMgrid, Inc.
|
||||
|
||||
"""
|
||||
Quantum PLUMgrid Plug-in for PLUMgrid Virtual Technology
|
||||
This plugin will forward authenticated REST API calls
|
||||
to the Network Operating System by PLUMgrid called NOS
|
||||
"""
|
||||
|
||||
import httplib
|
||||
import urllib2
|
||||
|
||||
from quantum.openstack.common import jsonutils as json
|
||||
from quantum.openstack.common import log as logging
|
||||
from quantum.plugins.plumgrid.common import exceptions as plum_excep
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RestConnection(object):
|
||||
"""REST Connection to PLUMgrid NOS Server."""
|
||||
|
||||
def __init__(self, server, port, timeout):
|
||||
LOG.debug(_('QuantumPluginPLUMgrid Status: REST Connection Started'))
|
||||
self.server = server
|
||||
self.port = port
|
||||
self.timeout = timeout
|
||||
|
||||
def nos_rest_conn(self, nos_url, action, data, headers):
|
||||
self.nos_url = nos_url
|
||||
body_data = json.dumps(data)
|
||||
if not headers:
|
||||
headers = {}
|
||||
headers['Content-type'] = 'application/json'
|
||||
headers['Accept'] = 'application/json'
|
||||
|
||||
LOG.debug(_("PLUMgrid_NOS_Server: %s %s %s"), self.server, self.port,
|
||||
action)
|
||||
|
||||
conn = httplib.HTTPConnection(self.server, self.port,
|
||||
timeout=self.timeout)
|
||||
if conn is None:
|
||||
LOG.error(_('PLUMgrid_NOS_Server: Could not establish HTTP '
|
||||
'connection'))
|
||||
return
|
||||
|
||||
try:
|
||||
LOG.debug(_("PLUMgrid_NOS_Server Sending Data: %s %s %s"),
|
||||
nos_url, body_data, headers)
|
||||
conn.request(action, nos_url, body_data, headers)
|
||||
resp = conn.getresponse()
|
||||
resp_str = resp.read()
|
||||
|
||||
LOG.debug(_("PLUMgrid_NOS_Server Connection Data: %s, %s"),
|
||||
resp, resp_str)
|
||||
|
||||
if resp.status is httplib.OK:
|
||||
try:
|
||||
respdata = json.loads(resp_str)
|
||||
LOG.debug(_("PLUMgrid_NOS_Server Connection RESP: %s"),
|
||||
respdata)
|
||||
pass
|
||||
except ValueError:
|
||||
err_message = _("PLUMgrid HTTP Connection Failed: ")
|
||||
LOG.Exception(err_message)
|
||||
raise plum_excep.PLUMgridException(err_message)
|
||||
|
||||
ret = (resp.status, resp.reason, resp_str)
|
||||
except urllib2.HTTPError, e:
|
||||
LOG.error(_('PLUMgrid_NOS_Server: %(action)s failure, %(e)r'))
|
||||
ret = 0, None, None, None
|
||||
conn.close()
|
||||
LOG.debug(_("PLUMgrid_NOS_Server: status=%(status)d, "
|
||||
"reason=%(reason)r, ret=%(ret)s"),
|
||||
{'status': ret[0], 'reason': ret[1], 'ret': ret[2]})
|
||||
return ret
|
17
quantum/tests/unit/plumgrid/__init__.py
Normal file
17
quantum/tests/unit/plumgrid/__init__.py
Normal file
@ -0,0 +1,17 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright 2013 PLUMgrid, 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.
|
||||
#
|
||||
# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc.
|
77
quantum/tests/unit/plumgrid/test_plumgrid_plugin.py
Normal file
77
quantum/tests/unit/plumgrid/test_plumgrid_plugin.py
Normal file
@ -0,0 +1,77 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# Copyright 2013 PLUMgrid, 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.
|
||||
#
|
||||
# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc.
|
||||
|
||||
"""
|
||||
Test cases for Quantum PLUMgrid Plug-in
|
||||
"""
|
||||
|
||||
from mock import patch
|
||||
|
||||
from quantum.manager import QuantumManager
|
||||
from quantum.tests.unit import test_db_plugin as test_plugin
|
||||
|
||||
|
||||
class PLUMgridPluginV2TestCase(test_plugin.QuantumDbPluginV2TestCase):
|
||||
|
||||
_plugin_name = ('quantum.plugins.plumgrid.plumgrid_nos_plugin.'
|
||||
'plumgrid_plugin.QuantumPluginPLUMgridV2')
|
||||
|
||||
def setUp(self):
|
||||
self.restHTTPConnection = patch('httplib.HTTPConnection')
|
||||
self.restHTTPConnection.start()
|
||||
super(PLUMgridPluginV2TestCase, self).setUp(self._plugin_name)
|
||||
|
||||
def tearDown(self):
|
||||
super(PLUMgridPluginV2TestCase, self).tearDown()
|
||||
self.restHTTPConnection.stop()
|
||||
|
||||
|
||||
class TestPlumgridPluginV2HTTPResponse(test_plugin.TestV2HTTPResponse,
|
||||
PLUMgridPluginV2TestCase):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class TestPlumgridPluginPortsV2(test_plugin.TestPortsV2,
|
||||
PLUMgridPluginV2TestCase):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class TestPlumgridPluginNetworksV2(test_plugin.TestNetworksV2,
|
||||
PLUMgridPluginV2TestCase):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class TestPlumgridPluginSubnetsV2(test_plugin.TestSubnetsV2,
|
||||
PLUMgridPluginV2TestCase):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class TestPlumgridNetworkAdminState(PLUMgridPluginV2TestCase):
|
||||
|
||||
def test_network_admin_state(self):
|
||||
name = 'network_test'
|
||||
admin_status_up = False
|
||||
tenant_id = 'tenant_test'
|
||||
network = {'network': {'name': name,
|
||||
'admin_state_up': admin_status_up,
|
||||
'tenant_id': tenant_id}}
|
||||
plugin = QuantumManager.get_plugin()
|
||||
self.assertEqual(plugin._network_admin_state(network), network)
|
3
setup.py
3
setup.py
@ -53,6 +53,7 @@ ryu_plugin_config_path = 'etc/quantum/plugins/ryu'
|
||||
meta_plugin_config_path = 'etc/quantum/plugins/metaplugin'
|
||||
nec_plugin_config_path = 'etc/quantum/plugins/nec'
|
||||
hyperv_plugin_config_path = 'etc/quantum/plugins/hyperv'
|
||||
plumgrid_plugin_config_path = 'etc/quantum/plugins/plumgrid'
|
||||
|
||||
if sys.platform == 'win32':
|
||||
# Windows doesn't have an "/etc" directory equivalent
|
||||
@ -107,6 +108,8 @@ else:
|
||||
(nec_plugin_config_path, ['etc/quantum/plugins/nec/nec.ini']),
|
||||
(hyperv_plugin_config_path,
|
||||
['etc/quantum/plugins/hyperv/hyperv_quantum_plugin.ini']),
|
||||
(plumgrid_plugin_config_path,
|
||||
['etc/quantum/plugins/plumgrid/plumgrid.ini']),
|
||||
]
|
||||
|
||||
ConsoleScripts = [
|
||||
|
Loading…
Reference in New Issue
Block a user