Share service chain constructs

Adding 'shared' attribute to the following service chain objects:

- Service Chain Node;
- Service Chain Spec.

As a side effect, REDIRECT rules can now be shared with a
shared SCS value.

implements blueprint share-servicechain-objects

Change-Id: If6cd4072271fdbe9f213aa2922cb918547340cd3
This commit is contained in:
Ivar Lazzaro
2015-03-16 17:24:49 -07:00
parent c66404c4b6
commit c9bfb7b116
14 changed files with 445 additions and 134 deletions

View File

@@ -19,12 +19,14 @@ from gbpservice.neutron.services.servicechain.plugins.msc import (
context as servicechain_context)
from gbpservice.neutron.services.servicechain.plugins.msc import (
driver_manager as manager)
from gbpservice.neutron.services.servicechain.plugins import sharing
LOG = logging.getLogger(__name__)
class ServiceChainPlugin(servicechain_db.ServiceChainDbPlugin):
class ServiceChainPlugin(servicechain_db.ServiceChainDbPlugin,
sharing.SharingMixin):
"""Implementation of the Service Chain Plugin.
@@ -42,6 +44,7 @@ class ServiceChainPlugin(servicechain_db.ServiceChainDbPlugin):
with session.begin(subtransactions=True):
result = super(ServiceChainPlugin, self).create_servicechain_node(
context, servicechain_node)
self._validate_shared_create(context, result, 'servicechain_node')
sc_context = servicechain_context.ServiceChainNodeContext(
self, context, result)
self.driver_manager.create_servicechain_node_precommit(
@@ -70,6 +73,8 @@ class ServiceChainPlugin(servicechain_db.ServiceChainDbPlugin):
self).update_servicechain_node(
context, servicechain_node_id,
servicechain_node)
self._validate_shared_update(context, original_sc_node,
updated_sc_node, 'servicechain_node')
sc_context = servicechain_context.ServiceChainNodeContext(
self, context, updated_sc_node,
original_sc_node=original_sc_node)
@@ -107,6 +112,7 @@ class ServiceChainPlugin(servicechain_db.ServiceChainDbPlugin):
with session.begin(subtransactions=True):
result = super(ServiceChainPlugin, self).create_servicechain_spec(
context, servicechain_spec)
self._validate_shared_create(context, result, 'servicechain_spec')
sc_context = servicechain_context.ServiceChainSpecContext(
self, context, result)
self.driver_manager.create_servicechain_spec_precommit(
@@ -134,6 +140,8 @@ class ServiceChainPlugin(servicechain_db.ServiceChainDbPlugin):
self).update_servicechain_spec(
context, servicechain_spec_id,
servicechain_spec)
self._validate_shared_update(context, original_sc_spec,
updated_sc_spec, 'servicechain_spec')
sc_context = servicechain_context.ServiceChainSpecContext(
self, context, updated_sc_spec,
original_sc_spec=original_sc_spec)

View File

@@ -0,0 +1,74 @@
# 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.api.v2 import attributes as nattr
from neutron import manager as n_manager
from neutron.plugins.common import constants as pconst
from oslo_log import log as logging
from gbpservice.neutron.services.grouppolicy.common import exceptions as gp_exc
from gbpservice.neutron.services.grouppolicy import plugin as gbp_plugin
LOG = logging.getLogger(__name__)
class SharingMixin(object):
"""Implementation of the Service Chain Plugin sharing rules.
"""
usage_graph = {'servicechain_spec': {'nodes':
'servicechain_node'},
'servicechain_node': {},
'servicechain_instance': {}}
_plurals = None
@property
def plurals(self):
if not self._plurals:
self._plurals = dict((nattr.PLURALS[k], k) for k in nattr.PLURALS)
return self._plurals
@property
def gbp_plugin(self):
# REVISIT(rkukura): Need initialization method after all
# plugins are loaded to grab and store plugin.
plugins = n_manager.NeutronManager.get_service_plugins()
gbp_plugin = plugins.get(pconst.GROUP_POLICY)
if not gbp_plugin:
LOG.error(_("No group policy service plugin found."))
raise gp_exc.GroupPolicyDeploymentError()
return gbp_plugin
def _validate_shared_create(self, context, obj, identity):
return gbp_plugin.GroupPolicyPlugin._validate_shared_create(
self, context, obj, identity)
def _validate_shared_update(self, context, original, updated, identity):
self._validate_shared_create(context, updated, identity)
if updated.get('shared') != original.get('shared'):
context = context.elevated()
getattr(self, '_validate_%s_unshare' % identity)(context, updated)
def _validate_servicechain_node_unshare(self, context, obj):
# Verify not pointed by shared SCS
gbp_plugin.GroupPolicyPlugin._check_shared_or_different_tenant(
context, obj, self.get_servicechain_specs, 'id',
obj['servicechain_specs'])
def _validate_servicechain_spec_unshare(self, context, obj):
# Verify not pointed by shared policy actions
gbp_plugin.GroupPolicyPlugin._check_shared_or_different_tenant(
context, obj, self.gbp_plugin.get_policy_actions, 'action_value',
[obj['id']])