chain agnostic node plumber
This plumber simply provides chain drivers with the Service Targets they requested for, without making any modification depending on the rest of the chain. Partially implements blueprint node-centric-chain-plugin Change-Id: I9030b4b43f87dc250e263eeaf58576f1b5bef40a
This commit is contained in:
@@ -21,7 +21,7 @@ service_chain_opts = [
|
||||
"gbpservice.neutron.servicechain.ncp_drivers "
|
||||
"namespace.")),
|
||||
cfg.StrOpt('node_plumber',
|
||||
default='dummy_plumber',
|
||||
default='agnostic_plumber',
|
||||
help=_("The plumber used by the Node Composition Plugin "
|
||||
"for service plumbing. Entrypoint loaded from the "
|
||||
"gbpservice.neutron.servicechain.ncp_plumbers "
|
||||
|
||||
@@ -25,6 +25,11 @@ class NodeCompositionPluginException(exceptions.NeutronException):
|
||||
pass
|
||||
|
||||
|
||||
class PlumbingException(exceptions.NeutronException):
|
||||
"""Base for node driver exceptions returned to user."""
|
||||
pass
|
||||
|
||||
|
||||
class NodeCompositionPluginBadRequest(exceptions.BadRequest,
|
||||
NodeCompositionPluginException):
|
||||
"""Base for node driver bad request exceptions returned to user."""
|
||||
@@ -45,4 +50,10 @@ class NoDriverAvailableForAction(NodeCompositionPluginBadRequest):
|
||||
|
||||
class ServiceProfileInUseByAnInstance(NodeCompositionPluginBadRequest):
|
||||
message = _("Cannot update Service Profile %(profile_id)s because it's "
|
||||
"used by servicechain instance %(instance_id)s.")
|
||||
"used by servicechain instance %(instance_id)s.")
|
||||
|
||||
|
||||
class NotAvailablePTGForTargetRequest(PlumbingException):
|
||||
message = _("PTG of type %(ptg_type)s doesn't exist for service chain "
|
||||
"instance %(instance)s. However, it is required by the "
|
||||
"scheduled Node Driver in order to deploy Node %(node)s")
|
||||
|
||||
@@ -105,17 +105,41 @@ def get_service_targets(session, policy_target_id=None, relationship=None,
|
||||
servicechain_instance_id=None, position=None,
|
||||
servicechain_node_id=None):
|
||||
with session.begin(subtransactions=True):
|
||||
query = session.query(ServiceTarget)
|
||||
if servicechain_instance_id:
|
||||
query = query.filter_by(
|
||||
servicechain_instance_id=servicechain_instance_id)
|
||||
if servicechain_node_id:
|
||||
query = query.filter_by(
|
||||
servicechain_node_id=servicechain_node_id)
|
||||
if policy_target_id:
|
||||
query = query.filter_by(policy_target_id=policy_target_id)
|
||||
if position:
|
||||
query = query.filter_by(position=position)
|
||||
if relationship:
|
||||
query = query.filter_by(relationship=relationship)
|
||||
query = _prepare_service_target_query(
|
||||
session, policy_target_id=policy_target_id,
|
||||
relationship=relationship,
|
||||
servicechain_instance_id=servicechain_instance_id,
|
||||
position=position, servicechain_node_id=servicechain_node_id)
|
||||
return query.all()
|
||||
|
||||
|
||||
def get_service_targets_count(session, policy_target_id=None,
|
||||
relationship=None, servicechain_instance_id=None,
|
||||
position=None, servicechain_node_id=None):
|
||||
with session.begin(subtransactions=True):
|
||||
query = _prepare_service_target_query(
|
||||
session, policy_target_id=policy_target_id,
|
||||
relationship=relationship,
|
||||
servicechain_instance_id=servicechain_instance_id,
|
||||
position=position, servicechain_node_id=servicechain_node_id)
|
||||
return query.count()
|
||||
|
||||
|
||||
def _prepare_service_target_query(session, policy_target_id=None,
|
||||
relationship=None,
|
||||
servicechain_instance_id=None, position=None,
|
||||
servicechain_node_id=None):
|
||||
query = session.query(ServiceTarget)
|
||||
if servicechain_instance_id:
|
||||
query = query.filter_by(
|
||||
servicechain_instance_id=servicechain_instance_id)
|
||||
if servicechain_node_id:
|
||||
query = query.filter_by(
|
||||
servicechain_node_id=servicechain_node_id)
|
||||
if policy_target_id:
|
||||
query = query.filter_by(policy_target_id=policy_target_id)
|
||||
if position:
|
||||
query = query.filter_by(position=position)
|
||||
if relationship:
|
||||
query = query.filter_by(relationship=relationship)
|
||||
return query
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# 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.common import log
|
||||
|
||||
from gbpservice.neutron.services.servicechain.plugins.ncp import plumber_base
|
||||
|
||||
|
||||
class ChainAgnosticPlumber(plumber_base.NodePlumberBase):
|
||||
""" Chain Agnostic Plumber.
|
||||
|
||||
This plumber simply provides node drivers with the Service Targets
|
||||
they requested for, without making any modification depending on the
|
||||
rest of the chain.
|
||||
"""
|
||||
|
||||
@log.log
|
||||
def initialize(self):
|
||||
pass
|
||||
|
||||
@log.log
|
||||
def plug_services(self, context, deployment):
|
||||
for part in deployment:
|
||||
self._create_service_targets(context, part)
|
||||
|
||||
@log.log
|
||||
def unplug_services(self, context, deployment):
|
||||
for part in deployment:
|
||||
self._delete_service_targets(context, part)
|
||||
@@ -13,6 +13,15 @@
|
||||
import abc
|
||||
import six
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from gbpservice.neutron.extensions import group_policy
|
||||
from gbpservice.neutron.services.servicechain.plugins.ncp import exceptions
|
||||
from gbpservice.neutron.services.servicechain.plugins.ncp import model
|
||||
|
||||
TARGET_DESCRIPTION = "%s facing Service Target for node %s in instance %s"
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class NodePlumberBase(object):
|
||||
@@ -74,5 +83,59 @@ class NodePlumberBase(object):
|
||||
node_context.current_position
|
||||
"""
|
||||
|
||||
def _create_service_targets(self, context, part):
|
||||
info = part['plumbing_info']
|
||||
if not info:
|
||||
return
|
||||
part_context = part['context']
|
||||
provider = part_context.provider
|
||||
consumer = part_context.consumer
|
||||
management = part_context.management
|
||||
|
||||
self._create_service_target(context, part_context,
|
||||
info.get('provider', []),
|
||||
provider, 'provider')
|
||||
self._create_service_target(context, part_context,
|
||||
info.get('consumer', []),
|
||||
consumer, 'consumer')
|
||||
self._create_service_target(context, part_context,
|
||||
info.get('management', []),
|
||||
management, 'management')
|
||||
|
||||
def _delete_service_targets(self, context, part):
|
||||
part_context = part['context']
|
||||
node = part_context.current_node
|
||||
instance = part_context.instance
|
||||
gbp_plugin = part_context.gbp_plugin
|
||||
pts = model.get_service_targets(
|
||||
context.session, servicechain_instance_id=instance['id'],
|
||||
servicechain_node_id=node['id'])
|
||||
|
||||
for pt in pts:
|
||||
try:
|
||||
gbp_plugin.delete_policy_target(context, pt.policy_target_id)
|
||||
except group_policy.PolicyTargetNotFound as ex:
|
||||
LOG.debug(ex.message)
|
||||
|
||||
def _create_service_target(self, context, part_context, targets, group,
|
||||
relationship):
|
||||
instance = part_context.instance
|
||||
node = part_context.current_node
|
||||
gbp_plugin = part_context.gbp_plugin
|
||||
for target in targets:
|
||||
if not group:
|
||||
exceptions.NotAvailablePTGForTargetRequest(
|
||||
ptg_type=relationship, instance=instance['id'],
|
||||
node=node['id'])
|
||||
data = {'policy_target_group_id': group['id'],
|
||||
'description': TARGET_DESCRIPTION % (relationship,
|
||||
node['id'],
|
||||
instance['id']),
|
||||
'name': '', 'port_id': None}
|
||||
data.update(target)
|
||||
pt = gbp_plugin.create_policy_target(context,
|
||||
{'policy_target': data})
|
||||
model.set_service_target(part_context, pt['id'], relationship)
|
||||
|
||||
def _sort_deployment(self, deployment):
|
||||
deployment.sort(key=lambda x: x['context'].current_position)
|
||||
Reference in New Issue
Block a user