Support Hierarchial Policy Rule Set for Redirects
Change-Id: I5dc4a73c9af82689e4f16a1d07f75b205a354b83 Closes-bug: 1387006
This commit is contained in:
		@@ -0,0 +1,46 @@
 | 
			
		||||
# Copyright 2014 OpenStack Foundation
 | 
			
		||||
#
 | 
			
		||||
#    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.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
"""sc_instance_spec_mapping
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
# revision identifiers, used by Alembic.
 | 
			
		||||
revision = '8e14fcb1587e'
 | 
			
		||||
down_revision = '64fa77aca090'
 | 
			
		||||
 | 
			
		||||
from alembic import op
 | 
			
		||||
import sqlalchemy as sa
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def upgrade(active_plugins=None, options=None):
 | 
			
		||||
    op.create_table(
 | 
			
		||||
        'sc_instance_spec_mappings',
 | 
			
		||||
        sa.Column('servicechain_spec_id',
 | 
			
		||||
                  sa.String(length=36),
 | 
			
		||||
                  nullable=False),
 | 
			
		||||
        sa.Column('servicechain_instance_id',
 | 
			
		||||
                  sa.String(length=36),
 | 
			
		||||
                  nullable=False),
 | 
			
		||||
        sa.ForeignKeyConstraint(['servicechain_spec_id'], ['sc_specs.id']),
 | 
			
		||||
        sa.ForeignKeyConstraint(['servicechain_instance_id'],
 | 
			
		||||
                                ['sc_instances.id'],
 | 
			
		||||
                                ondelete='CASCADE'),
 | 
			
		||||
        sa.PrimaryKeyConstraint('servicechain_instance_id',
 | 
			
		||||
                                'servicechain_spec_id')
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def downgrade(active_plugins=None, options=None):
 | 
			
		||||
    op.drop_table('sc_instance_spec_mappings')
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
64fa77aca090
 | 
			
		||||
8e14fcb1587e
 | 
			
		||||
 
 | 
			
		||||
@@ -37,8 +37,7 @@ def upgrade(active_plugins=None, options=None):
 | 
			
		||||
                    sa.Column('policy_id',
 | 
			
		||||
                              sa.String(length=36),
 | 
			
		||||
                              nullable=True),
 | 
			
		||||
                    sa.PrimaryKeyConstraint('instance_id'),
 | 
			
		||||
                    sa.PrimaryKeyConstraint('policy_id'))
 | 
			
		||||
                    sa.PrimaryKeyConstraint('instance_id', 'policy_id'))
 | 
			
		||||
 | 
			
		||||
    op.create_table('nvsd_sc_instance_vip_eps',
 | 
			
		||||
                    sa.Column('instance_id',
 | 
			
		||||
@@ -50,7 +49,8 @@ def upgrade(active_plugins=None, options=None):
 | 
			
		||||
                    sa.Column('nvsd_ep_id',
 | 
			
		||||
                              sa.String(length=36),
 | 
			
		||||
                              nullable=True),
 | 
			
		||||
                    sa.PrimaryKeyConstraint('instance_id'))
 | 
			
		||||
                    sa.PrimaryKeyConstraint('instance_id', 'vip_port',
 | 
			
		||||
                                            'nvsd_ep_id'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def downgrade(active_plugins=None, options=None):
 | 
			
		||||
 
 | 
			
		||||
@@ -63,27 +63,25 @@ def upgrade(active_plugins=None, options=None):
 | 
			
		||||
        sa.Column('provider_ptg_id', sa.String(length=36), nullable=True),
 | 
			
		||||
        sa.Column('consumer_ptg_id', sa.String(length=36), nullable=True),
 | 
			
		||||
        sa.Column('classifier_id', sa.String(length=36), nullable=True),
 | 
			
		||||
        sa.Column('servicechain_spec', sa.String(length=36), nullable=True),
 | 
			
		||||
        # FixMe(Magesh) Deletes the instances table itself !!!
 | 
			
		||||
        # sa.ForeignKeyConstraint(['provider_ptg'],
 | 
			
		||||
        # FixMe(Magesh) If cascade on delete is used, we lose this info !!!
 | 
			
		||||
        # sa.ForeignKeyConstraint(['provider_ptg_id'],
 | 
			
		||||
        #                         ['gp_policy_target_groups.id'],
 | 
			
		||||
        #                         ondelete='CASCADE'),
 | 
			
		||||
        # sa.ForeignKeyConstraint(['consumer_ptg'],
 | 
			
		||||
        # sa.ForeignKeyConstraint(['consumer_ptg_id'],
 | 
			
		||||
        #                         ['gp_policy_target_groups.id'],
 | 
			
		||||
        #                         ondelete='CASCADE'),
 | 
			
		||||
        # sa.ForeignKeyConstraint(['classifier'], ['gp_policy_classifiers.id'],
 | 
			
		||||
        #                        ondelete='CASCADE'),
 | 
			
		||||
        sa.ForeignKeyConstraint(['servicechain_spec'], ['sc_specs.id']),
 | 
			
		||||
        sa.PrimaryKeyConstraint('id')
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    op.create_table(
 | 
			
		||||
        'sc_spec_node_associations',
 | 
			
		||||
        sa.Column('servicechain_spec', sa.String(length=36), nullable=False),
 | 
			
		||||
        sa.Column('servicechain_spec_id',
 | 
			
		||||
                  sa.String(length=36),
 | 
			
		||||
                  nullable=False),
 | 
			
		||||
        sa.Column('node_id', sa.String(length=36), nullable=False),
 | 
			
		||||
        sa.ForeignKeyConstraint(['servicechain_spec'], ['sc_specs.id']),
 | 
			
		||||
        sa.ForeignKeyConstraint(['servicechain_spec_id'], ['sc_specs.id']),
 | 
			
		||||
        sa.ForeignKeyConstraint(['node_id'], ['sc_nodes.id']),
 | 
			
		||||
        sa.PrimaryKeyConstraint('servicechain_spec', 'node_id')
 | 
			
		||||
        sa.PrimaryKeyConstraint('servicechain_spec_id', 'node_id')
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,13 +33,23 @@ MAX_IPV6_SUBNET_PREFIX_LENGTH = 127
 | 
			
		||||
class SpecNodeAssociation(model_base.BASEV2):
 | 
			
		||||
    """Models one to many providing relation between Specs and Nodes."""
 | 
			
		||||
    __tablename__ = 'sc_spec_node_associations'
 | 
			
		||||
    servicechain_spec = sa.Column(
 | 
			
		||||
    servicechain_spec_id = sa.Column(
 | 
			
		||||
        sa.String(36), sa.ForeignKey('sc_specs.id'), primary_key=True)
 | 
			
		||||
    node_id = sa.Column(sa.String(36),
 | 
			
		||||
                        sa.ForeignKey('sc_nodes.id'),
 | 
			
		||||
                        primary_key=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class InstanceSpecAssociation(model_base.BASEV2):
 | 
			
		||||
    """Models  one to many providing relation between Instance and Specs."""
 | 
			
		||||
    __tablename__ = 'sc_instance_spec_mappings'
 | 
			
		||||
    servicechain_instance_id = sa.Column(
 | 
			
		||||
        sa.String(36), sa.ForeignKey('sc_instances.id'), primary_key=True)
 | 
			
		||||
    servicechain_spec_id = sa.Column(sa.String(36),
 | 
			
		||||
                                     sa.ForeignKey('sc_specs.id'),
 | 
			
		||||
                                     primary_key=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ServiceChainNode(model_base.BASEV2, models_v2.HasId,
 | 
			
		||||
                       models_v2.HasTenant):
 | 
			
		||||
    """ServiceChain Node"""
 | 
			
		||||
@@ -60,10 +70,11 @@ class ServiceChainInstance(model_base.BASEV2, models_v2.HasId,
 | 
			
		||||
    name = sa.Column(sa.String(50))
 | 
			
		||||
    description = sa.Column(sa.String(255))
 | 
			
		||||
    config_param_values = sa.Column(sa.String(4096))
 | 
			
		||||
    servicechain_spec = sa.Column(
 | 
			
		||||
        sa.String(36), sa.ForeignKey('sc_specs.id'), nullable=True)
 | 
			
		||||
    specs = orm.relationship(InstanceSpecAssociation,
 | 
			
		||||
                             backref='instances',
 | 
			
		||||
                             cascade='all,delete, delete-orphan')
 | 
			
		||||
    provider_ptg_id = sa.Column(sa.String(36),
 | 
			
		||||
                             # FixMe(Magesh) Deletes the instances table itself
 | 
			
		||||
                             # FixMe(Magesh) Issue with cascade on Delete
 | 
			
		||||
                             # sa.ForeignKey('gp_policy_target_groups.id'),
 | 
			
		||||
                             nullable=True)
 | 
			
		||||
    consumer_ptg_id = sa.Column(sa.String(36),
 | 
			
		||||
@@ -85,8 +96,9 @@ class ServiceChainSpec(model_base.BASEV2, models_v2.HasId,
 | 
			
		||||
        SpecNodeAssociation,
 | 
			
		||||
        backref='specs', cascade='all, delete, delete-orphan')
 | 
			
		||||
    config_param_names = sa.Column(sa.String(4096))
 | 
			
		||||
    instances = orm.relationship(ServiceChainInstance,
 | 
			
		||||
                                 backref="specs")
 | 
			
		||||
    instances = orm.relationship(InstanceSpecAssociation,
 | 
			
		||||
                                 backref="specs",
 | 
			
		||||
                                 cascade='all, delete, delete-orphan')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
 | 
			
		||||
@@ -144,10 +156,11 @@ class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
 | 
			
		||||
               'name': instance['name'],
 | 
			
		||||
               'description': instance['description'],
 | 
			
		||||
               'config_param_values': instance['config_param_values'],
 | 
			
		||||
               'servicechain_spec': instance['servicechain_spec'],
 | 
			
		||||
               'provider_ptg_id': instance['provider_ptg_id'],
 | 
			
		||||
               'consumer_ptg_id': instance['consumer_ptg_id'],
 | 
			
		||||
               'classifier_id': instance['classifier_id']}
 | 
			
		||||
        res['servicechain_specs'] = [sc_spec['servicechain_spec_id']
 | 
			
		||||
                                    for sc_spec in instance['specs']]
 | 
			
		||||
        return self._fields(res, fields)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
@@ -251,10 +264,39 @@ class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
 | 
			
		||||
                        config_param_names.extend(config_params.keys())
 | 
			
		||||
                        spec_db.config_param_names = str(config_param_names)
 | 
			
		||||
 | 
			
		||||
                assoc = SpecNodeAssociation(servicechain_spec=spec_db.id,
 | 
			
		||||
                assoc = SpecNodeAssociation(servicechain_spec_id=spec_db.id,
 | 
			
		||||
                                            node_id=node_id)
 | 
			
		||||
                spec_db.nodes.append(assoc)
 | 
			
		||||
 | 
			
		||||
    def _process_specs_for_instance(self, context, instance_db, instance):
 | 
			
		||||
        if 'servicechain_specs' in instance:
 | 
			
		||||
            self._set_specs_for_instance(context, instance_db,
 | 
			
		||||
                                         instance['servicechain_specs'])
 | 
			
		||||
            del instance['servicechain_specs']
 | 
			
		||||
        return instance
 | 
			
		||||
 | 
			
		||||
    def _set_specs_for_instance(self, context, instance_db, spec_id_list):
 | 
			
		||||
        if not spec_id_list:
 | 
			
		||||
            instance_db.spec_ids = []
 | 
			
		||||
            return
 | 
			
		||||
        with context.session.begin(subtransactions=True):
 | 
			
		||||
            filters = {'id': spec_id_list}
 | 
			
		||||
            specs_in_db = self._get_collection_query(context, ServiceChainSpec,
 | 
			
		||||
                                                     filters=filters)
 | 
			
		||||
            specs_list = set(spec_db['id'] for spec_db in specs_in_db)
 | 
			
		||||
            for spec_id in spec_id_list:
 | 
			
		||||
                if spec_id not in specs_list:
 | 
			
		||||
                    # Do not update if spec ID is invalid
 | 
			
		||||
                    raise schain.ServiceChainSpecNotFound(sc_spec_id=spec_id)
 | 
			
		||||
            # Reset the existing list and then add each spec in order. The list
 | 
			
		||||
            # could be empty in which case we clear the existing specs.
 | 
			
		||||
            instance_db.specs = []
 | 
			
		||||
            for spec_id in spec_id_list:
 | 
			
		||||
                assoc = InstanceSpecAssociation(
 | 
			
		||||
                                    servicechain_instance_id=instance_db.id,
 | 
			
		||||
                                    servicechain_spec_id=spec_id)
 | 
			
		||||
                instance_db.specs.append(assoc)
 | 
			
		||||
 | 
			
		||||
    @log.log
 | 
			
		||||
    def create_servicechain_spec(self, context, servicechain_spec):
 | 
			
		||||
        spec = servicechain_spec['servicechain_spec']
 | 
			
		||||
@@ -320,10 +362,10 @@ class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
 | 
			
		||||
                tenant_id=tenant_id, name=instance['name'],
 | 
			
		||||
                description=instance['description'],
 | 
			
		||||
                config_param_values=instance['config_param_values'],
 | 
			
		||||
                servicechain_spec=instance['servicechain_spec'],
 | 
			
		||||
                provider_ptg_id=instance['provider_ptg_id'],
 | 
			
		||||
                consumer_ptg_id=instance['consumer_ptg_id'],
 | 
			
		||||
                classifier_id=instance['classifier_id'])
 | 
			
		||||
            self._process_specs_for_instance(context, instance_db, instance)
 | 
			
		||||
            context.session.add(instance_db)
 | 
			
		||||
        return self._make_sc_instance_dict(instance_db)
 | 
			
		||||
 | 
			
		||||
@@ -334,6 +376,8 @@ class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
 | 
			
		||||
        with context.session.begin(subtransactions=True):
 | 
			
		||||
            instance_db = self._get_servicechain_instance(
 | 
			
		||||
                context, servicechain_instance_id)
 | 
			
		||||
            instance = self._process_specs_for_instance(context, instance_db,
 | 
			
		||||
                                                        instance)
 | 
			
		||||
            instance_db.update(instance)
 | 
			
		||||
        return self._make_sc_instance_dict(instance_db)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -141,8 +141,9 @@ RESOURCE_ATTRIBUTE_MAP = {
 | 
			
		||||
        'tenant_id': {'allow_post': True, 'allow_put': False,
 | 
			
		||||
                      'validate': {'type:string': None},
 | 
			
		||||
                      'required_by_policy': True, 'is_visible': True},
 | 
			
		||||
        'servicechain_spec': {'allow_post': True, 'allow_put': True,
 | 
			
		||||
                              'validate': {'type:uuid_or_none': None},
 | 
			
		||||
        'servicechain_specs': {'allow_post': True, 'allow_put': True,
 | 
			
		||||
                              'validate': {'type:uuid_list': None},
 | 
			
		||||
                              'convert_to': attr.convert_none_to_empty_list,
 | 
			
		||||
                              'default': None, 'is_visible': True,
 | 
			
		||||
                              'required': True},
 | 
			
		||||
        'provider_ptg_id': {'allow_post': True, 'allow_put': False,
 | 
			
		||||
 
 | 
			
		||||
@@ -1121,15 +1121,15 @@ class ResourceMappingDriver(api.PolicyDriver):
 | 
			
		||||
            return
 | 
			
		||||
        spec = self._servicechain_plugin._get_servicechain_spec(
 | 
			
		||||
                    context._plugin_context, context.original['action_value'])
 | 
			
		||||
        servicechain_instances = spec.instances
 | 
			
		||||
        for servicechain_instance in servicechain_instances:
 | 
			
		||||
            sc_instance_update = {
 | 
			
		||||
                        'servicechain_spec': context.current['action_value']}
 | 
			
		||||
            self._update_resource(self._servicechain_plugin,
 | 
			
		||||
        for servicechain_instance in spec.instances:
 | 
			
		||||
            sc_instance_update_req = {
 | 
			
		||||
                    'servicechain_specs': [context.current['action_value']]}
 | 
			
		||||
            self._update_resource(
 | 
			
		||||
                        self._servicechain_plugin,
 | 
			
		||||
                        context._plugin_context,
 | 
			
		||||
                        'servicechain_instance',
 | 
			
		||||
                                  servicechain_instance['id'],
 | 
			
		||||
                                  sc_instance_update)
 | 
			
		||||
                        servicechain_instance.servicechain_instance_id,
 | 
			
		||||
                        sc_instance_update_req)
 | 
			
		||||
 | 
			
		||||
    def _get_rule_ids_for_actions(self, context, action_id):
 | 
			
		||||
        policy_rule_qry = context.session.query(
 | 
			
		||||
@@ -1137,10 +1137,11 @@ class ResourceMappingDriver(api.PolicyDriver):
 | 
			
		||||
        policy_rule_qry.filter_by(policy_action_id=action_id)
 | 
			
		||||
        return policy_rule_qry.all()
 | 
			
		||||
 | 
			
		||||
    def _handle_redirect_action(self, context, policy_rule_sets):
 | 
			
		||||
        for policy_rule_set_id in policy_rule_sets:
 | 
			
		||||
            policy_rule_set = context._plugin.get_policy_rule_set(
 | 
			
		||||
                                context._plugin_context, policy_rule_set_id)
 | 
			
		||||
    def _handle_redirect_action(self, context, policy_rule_set_ids):
 | 
			
		||||
        policy_rule_sets = context._plugin.get_policy_rule_sets(
 | 
			
		||||
                                    context._plugin_context,
 | 
			
		||||
                                    filters={'id': policy_rule_set_ids})
 | 
			
		||||
        for policy_rule_set in policy_rule_sets:
 | 
			
		||||
            ptgs_consuming_prs = policy_rule_set[
 | 
			
		||||
                                            'consuming_policy_target_groups']
 | 
			
		||||
            ptgs_providing_prs = policy_rule_set[
 | 
			
		||||
@@ -1148,18 +1149,41 @@ class ResourceMappingDriver(api.PolicyDriver):
 | 
			
		||||
 | 
			
		||||
            # Create the ServiceChain Instance when we have both Provider and
 | 
			
		||||
            # consumer PTGs. If Labels are available, they have to be applied
 | 
			
		||||
            # here. For now we support a single provider
 | 
			
		||||
            if not ptgs_consuming_prs or not ptgs_providing_prs:
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            for rule_id in policy_rule_set.get('policy_rules'):
 | 
			
		||||
                policy_rule = context._plugin.get_policy_rule(
 | 
			
		||||
                    context._plugin_context, rule_id)
 | 
			
		||||
            parent_classifier_id = None
 | 
			
		||||
            parent_spec_id = None
 | 
			
		||||
            if policy_rule_set['parent_id']:
 | 
			
		||||
                parent = context._plugin.get_policy_rule_set(
 | 
			
		||||
                    context._plugin_context, policy_rule_set['parent_id'])
 | 
			
		||||
                policy_rules = context._plugin.get_policy_rules(
 | 
			
		||||
                                    context._plugin_context,
 | 
			
		||||
                                    filters={'id': parent['policy_rules']})
 | 
			
		||||
                for policy_rule in policy_rules:
 | 
			
		||||
                    policy_actions = context._plugin.get_policy_actions(
 | 
			
		||||
                        context._plugin_context,
 | 
			
		||||
                        filters={'id': policy_rule["policy_actions"],
 | 
			
		||||
                                 'action_type': [gconst.GP_ACTION_REDIRECT]})
 | 
			
		||||
                    for policy_action in policy_actions:
 | 
			
		||||
                        parent_classifier_id = policy_rule.get(
 | 
			
		||||
                                                    "policy_classifier_id")
 | 
			
		||||
                        parent_spec_id = policy_action.get("action_value")
 | 
			
		||||
                        break  # One Redirect action per Policy rule set
 | 
			
		||||
 | 
			
		||||
            policy_rules = context._plugin.get_policy_rules(
 | 
			
		||||
                    context._plugin_context,
 | 
			
		||||
                    filters={'id': policy_rule_set['policy_rules']})
 | 
			
		||||
            for policy_rule in policy_rules:
 | 
			
		||||
                classifier_id = policy_rule.get("policy_classifier_id")
 | 
			
		||||
                for action_id in policy_rule.get("policy_actions"):
 | 
			
		||||
                    policy_action = context._plugin.get_policy_action(
 | 
			
		||||
                        context._plugin_context, action_id)
 | 
			
		||||
                    if policy_action['action_type'].upper() == "REDIRECT":
 | 
			
		||||
                if parent_classifier_id and not set(
 | 
			
		||||
                                [parent_classifier_id]) & set([classifier_id]):
 | 
			
		||||
                    continue
 | 
			
		||||
                policy_actions = context._plugin.get_policy_actions(
 | 
			
		||||
                        context._plugin_context,
 | 
			
		||||
                        filters={'id': policy_rule.get("policy_actions"),
 | 
			
		||||
                                 'action_type': [gconst.GP_ACTION_REDIRECT]})
 | 
			
		||||
                for policy_action in policy_actions:
 | 
			
		||||
                    for ptg_consuming_prs in ptgs_consuming_prs:
 | 
			
		||||
                        for ptg_providing_prs in ptgs_providing_prs:
 | 
			
		||||
                            ptg_chain_map = (
 | 
			
		||||
@@ -1171,19 +1195,14 @@ class ResourceMappingDriver(api.PolicyDriver):
 | 
			
		||||
                            # issues here.
 | 
			
		||||
                            if ptg_chain_map:
 | 
			
		||||
                                continue  # one chain between pair of PTGs
 | 
			
		||||
                                sc_instance = (
 | 
			
		||||
                                    self._create_servicechain_instance(
 | 
			
		||||
                                        context,
 | 
			
		||||
                                        policy_action.get("action_value"),
 | 
			
		||||
                                        ptg_providing_prs,
 | 
			
		||||
                                        ptg_consuming_prs,
 | 
			
		||||
                                        classifier_id))
 | 
			
		||||
                                chain_instance_id = sc_instance['id']
 | 
			
		||||
                            sc_instance = self._create_servicechain_instance(
 | 
			
		||||
                                context, policy_action.get("action_value"),
 | 
			
		||||
                                parent_spec_id, ptg_providing_prs,
 | 
			
		||||
                                ptg_consuming_prs, classifier_id)
 | 
			
		||||
                            self._set_ptg_servicechain_instance_mapping(
 | 
			
		||||
                                context._plugin_context.session,
 | 
			
		||||
                                    ptg_providing_prs,
 | 
			
		||||
                                    ptg_consuming_prs,
 | 
			
		||||
                                    chain_instance_id)
 | 
			
		||||
                                ptg_providing_prs, ptg_consuming_prs,
 | 
			
		||||
                                sc_instance['id'])
 | 
			
		||||
 | 
			
		||||
    def _cleanup_redirect_action(self, context):
 | 
			
		||||
        for ptg_chain in context.ptg_chain_map:
 | 
			
		||||
@@ -1339,10 +1358,14 @@ class ResourceMappingDriver(api.PolicyDriver):
 | 
			
		||||
            return ip_address
 | 
			
		||||
 | 
			
		||||
    def _create_servicechain_instance(self, context, servicechain_spec,
 | 
			
		||||
                                      parent_servicechain_spec,
 | 
			
		||||
                                      provider_ptg_id, consumer_ptg_id,
 | 
			
		||||
                                      classifier_id, config_params=None):
 | 
			
		||||
                                      classifier_id,
 | 
			
		||||
                                      config_params=None):
 | 
			
		||||
        sc_spec = [servicechain_spec]
 | 
			
		||||
        if parent_servicechain_spec:
 | 
			
		||||
            sc_spec.insert(0, parent_servicechain_spec)
 | 
			
		||||
        config_param_values = {}
 | 
			
		||||
 | 
			
		||||
        ptg = context._plugin.get_policy_target_group(
 | 
			
		||||
            context._plugin_context, provider_ptg_id)
 | 
			
		||||
        network_service_policy_id = ptg.get("network_service_policy_id")
 | 
			
		||||
@@ -1362,7 +1385,7 @@ class ResourceMappingDriver(api.PolicyDriver):
 | 
			
		||||
        attrs = {'tenant_id': context.current['tenant_id'],
 | 
			
		||||
                 'name': 'gbp_' + context.current['name'],
 | 
			
		||||
                 'description': "",
 | 
			
		||||
                 'servicechain_spec': servicechain_spec,
 | 
			
		||||
                 'servicechain_specs': sc_spec,
 | 
			
		||||
                 'provider_ptg_id': provider_ptg_id,
 | 
			
		||||
                 'consumer_ptg_id': consumer_ptg_id,
 | 
			
		||||
                 'classifier_id': classifier_id,
 | 
			
		||||
@@ -1784,18 +1807,27 @@ class ResourceMappingDriver(api.PolicyDriver):
 | 
			
		||||
        for child in children:
 | 
			
		||||
            child = context._plugin.get_policy_rule_set(
 | 
			
		||||
                context._plugin_context, child)
 | 
			
		||||
            child_rules = set(child['policy_rules'])
 | 
			
		||||
            child_rule_ids = set(child['policy_rules'])
 | 
			
		||||
            if child['parent_id']:
 | 
			
		||||
                parent = context._plugin.get_policy_rule_set(
 | 
			
		||||
                    context._plugin_context, child['parent_id'])
 | 
			
		||||
                parent_rules = set(parent['policy_rules'])
 | 
			
		||||
                delta_rules = context._plugin.get_policy_rules(
 | 
			
		||||
                parent_policy_rules = context._plugin.get_policy_rules(
 | 
			
		||||
                                        context._plugin_context,
 | 
			
		||||
                    filters={'id': child_rules - parent_rules})
 | 
			
		||||
                                        filters={'id': parent['policy_rules']})
 | 
			
		||||
                child_rules = context._plugin.get_policy_rules(
 | 
			
		||||
                                        context._plugin_context,
 | 
			
		||||
                                        filters={'id': child['policy_rules']})
 | 
			
		||||
                parent_classifier_ids = [x['policy_classifier_id']
 | 
			
		||||
                                     for x in parent_policy_rules]
 | 
			
		||||
                delta_rules = [x['id'] for x in child_rules
 | 
			
		||||
                               if x['policy_classifier_id']
 | 
			
		||||
                               not in set(parent_classifier_ids)]
 | 
			
		||||
                delta_rules = context._plugin.get_policy_rules(
 | 
			
		||||
                                context._plugin_context, {'id': delta_rules})
 | 
			
		||||
                self._remove_policy_rule_set_rules(context, child, delta_rules)
 | 
			
		||||
            # Old parent may have filtered some rules, need to add them again
 | 
			
		||||
            child_rules = context._plugin.get_policy_rules(
 | 
			
		||||
                context._plugin_context, filters={'id': child_rules})
 | 
			
		||||
                context._plugin_context, filters={'id': child_rule_ids})
 | 
			
		||||
            self._apply_policy_rule_set_rules(context, child, child_rules)
 | 
			
		||||
 | 
			
		||||
    def _get_default_security_group(self, plugin_context, ptg_id,
 | 
			
		||||
@@ -2020,9 +2052,20 @@ class ResourceMappingDriver(api.PolicyDriver):
 | 
			
		||||
        if prs['parent_id']:
 | 
			
		||||
            parent = context._plugin.get_policy_rule_set(
 | 
			
		||||
                context._plugin_context, prs['parent_id'])
 | 
			
		||||
            parent_policy_rules = context._plugin.get_policy_rules(
 | 
			
		||||
                                        context._plugin_context,
 | 
			
		||||
                                        filters={'id': parent['policy_rules']})
 | 
			
		||||
            subset_rules = context._plugin.get_policy_rules(
 | 
			
		||||
                                        context._plugin_context,
 | 
			
		||||
                                        filters={'id': subset})
 | 
			
		||||
            parent_classifier_ids = [x['policy_classifier_id']
 | 
			
		||||
                                     for x in parent_policy_rules]
 | 
			
		||||
            policy_rules = [x['id'] for x in subset_rules
 | 
			
		||||
                            if x['policy_classifier_id']
 | 
			
		||||
                            in set(parent_classifier_ids)]
 | 
			
		||||
            return context._plugin.get_policy_rules(
 | 
			
		||||
                context._plugin_context,
 | 
			
		||||
                {'id': set(subset) & set(parent['policy_rules'])})
 | 
			
		||||
                {'id': policy_rules})
 | 
			
		||||
        else:
 | 
			
		||||
            return context._plugin.get_policy_rules(
 | 
			
		||||
                context._plugin_context, {'id': set(subset)})
 | 
			
		||||
 
 | 
			
		||||
@@ -109,13 +109,14 @@ class OneconvergenceServiceChainDriver(simplechain_driver.SimpleChainDriver):
 | 
			
		||||
 | 
			
		||||
    @log.log
 | 
			
		||||
    def update_servicechain_instance_postcommit(self, context):
 | 
			
		||||
        original_spec_id = context._original_sc_instance.get(
 | 
			
		||||
                                                    'servicechain_spec')
 | 
			
		||||
        new_spec_id = context._sc_instance.get('servicechain_spec')
 | 
			
		||||
        if original_spec_id != new_spec_id:
 | 
			
		||||
        original_spec_ids = context._original_sc_instance.get(
 | 
			
		||||
                                                    'servicechain_specs')
 | 
			
		||||
        new_spec_ids = context._sc_instance.get('servicechain_specs')
 | 
			
		||||
        if set(original_spec_ids) != set(new_spec_ids):
 | 
			
		||||
            for new_spec_id in new_spec_ids:
 | 
			
		||||
                newspec = context._plugin.get_servicechain_spec(
 | 
			
		||||
                    context._plugin_context, new_spec_id)
 | 
			
		||||
            self._update_servicechain_instance(context, context._sc_instance,
 | 
			
		||||
                self._update_servicechain_instance(context, context.current,
 | 
			
		||||
                                                   newspec)
 | 
			
		||||
 | 
			
		||||
    @log.log
 | 
			
		||||
@@ -208,7 +209,8 @@ class OneconvergenceServiceChainDriver(simplechain_driver.SimpleChainDriver):
 | 
			
		||||
 | 
			
		||||
    def _create_servicechain_instance_postcommit(self, context):
 | 
			
		||||
        sc_instance = context.current
 | 
			
		||||
        sc_spec_id = sc_instance.get('servicechain_spec')
 | 
			
		||||
        sc_spec_ids = sc_instance.get('servicechain_specs')
 | 
			
		||||
        for sc_spec_id in sc_spec_ids:
 | 
			
		||||
            sc_spec = context._plugin.get_servicechain_spec(
 | 
			
		||||
                context._plugin_context, sc_spec_id)
 | 
			
		||||
            sc_node_ids = sc_spec.get('nodes')
 | 
			
		||||
@@ -418,8 +420,7 @@ class OneconvergenceServiceChainDriver(simplechain_driver.SimpleChainDriver):
 | 
			
		||||
        return service_ids
 | 
			
		||||
 | 
			
		||||
    def create_nvsd_action(self, context, action_body):
 | 
			
		||||
        return self.nvsd_api.create_policy_action(context,
 | 
			
		||||
                                             action_body)
 | 
			
		||||
        return self.nvsd_api.create_policy_action(context, action_body)
 | 
			
		||||
 | 
			
		||||
    def _create_nvsd_services_action(self, context, service_ids):
 | 
			
		||||
        nvsd_action_list = []
 | 
			
		||||
@@ -447,7 +448,7 @@ class OneconvergenceServiceChainDriver(simplechain_driver.SimpleChainDriver):
 | 
			
		||||
                               'tenant_id': context.tenant,
 | 
			
		||||
                               'user_id': context.user,
 | 
			
		||||
                               "action_value": service_id}
 | 
			
		||||
        #Supporting only one TAP in a chain
 | 
			
		||||
        # Supporting only one TAP in a chain
 | 
			
		||||
        if copy_action:
 | 
			
		||||
            action = self.create_nvsd_action(context, copy_action)
 | 
			
		||||
            nvsd_action_list.append(action['id'])
 | 
			
		||||
@@ -465,12 +466,12 @@ class OneconvergenceServiceChainDriver(simplechain_driver.SimpleChainDriver):
 | 
			
		||||
        if status == self.CREATE_IN_PROGRESS:
 | 
			
		||||
            return False
 | 
			
		||||
        elif status == self.CREATE_FAILED:
 | 
			
		||||
            #TODO(Magesh): Status has to be added to ServiceChainInstance
 | 
			
		||||
            #Update the Status to ERROR  at this point
 | 
			
		||||
            # TODO(Magesh): Status has to be added to ServiceChainInstance
 | 
			
		||||
            # Update the Status to ERROR  at this point
 | 
			
		||||
            return True
 | 
			
		||||
 | 
			
		||||
        #Services are created by now. Determine Service IDs an setup
 | 
			
		||||
        #Traffic Steering.
 | 
			
		||||
        # Services are created by now. Determine Service IDs an setup
 | 
			
		||||
        # Traffic Steering.
 | 
			
		||||
        service_ids = self._fetch_serviceids_from_stack(context, node_stacks,
 | 
			
		||||
                                                        chain_instance_id)
 | 
			
		||||
        nvsd_action_list = self._create_nvsd_services_action(context,
 | 
			
		||||
@@ -483,11 +484,10 @@ class OneconvergenceServiceChainDriver(simplechain_driver.SimpleChainDriver):
 | 
			
		||||
            policy_id = self.create_nvsd_policy(context, left_group,
 | 
			
		||||
                                                right_group, classifier_id,
 | 
			
		||||
                                                nvsd_action_list)
 | 
			
		||||
            #TODO(Magesh): Need to store actions and rules also, because
 | 
			
		||||
            #cleanup will be missed if policy create failed
 | 
			
		||||
            self._add_chain_policy_map(context.session,
 | 
			
		||||
                                       chain_instance_id,
 | 
			
		||||
                                       policy_id)
 | 
			
		||||
            # TODO(Magesh): Need to store actions and rules also, because
 | 
			
		||||
            # cleanup will be missed if policy create failed
 | 
			
		||||
            self._add_chain_policy_map(context.session, chain_instance_id,
 | 
			
		||||
                                       policy_id, classifier_id)
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -110,7 +110,8 @@ class SimpleChainDriver(object):
 | 
			
		||||
    @log.log
 | 
			
		||||
    def create_servicechain_instance_postcommit(self, context):
 | 
			
		||||
        sc_instance = context.current
 | 
			
		||||
        sc_spec_id = sc_instance.get('servicechain_spec')
 | 
			
		||||
        sc_spec_ids = sc_instance.get('servicechain_specs')
 | 
			
		||||
        for sc_spec_id in sc_spec_ids:
 | 
			
		||||
            sc_spec = context._plugin.get_servicechain_spec(
 | 
			
		||||
                context._plugin_context, sc_spec_id)
 | 
			
		||||
            sc_node_ids = sc_spec.get('nodes')
 | 
			
		||||
@@ -123,9 +124,10 @@ class SimpleChainDriver(object):
 | 
			
		||||
 | 
			
		||||
    @log.log
 | 
			
		||||
    def update_servicechain_instance_postcommit(self, context):
 | 
			
		||||
        original_spec_id = context.original.get('servicechain_spec')
 | 
			
		||||
        new_spec_id = context.current.get('servicechain_spec')
 | 
			
		||||
        if original_spec_id != new_spec_id:
 | 
			
		||||
        original_spec_ids = context.original.get('servicechain_specs')
 | 
			
		||||
        new_spec_ids = context.current.get('servicechain_specs')
 | 
			
		||||
        if set(original_spec_ids) != set(new_spec_ids):
 | 
			
		||||
            for new_spec_id in new_spec_ids:
 | 
			
		||||
                newspec = context._plugin.get_servicechain_spec(
 | 
			
		||||
                    context._plugin_context, new_spec_id)
 | 
			
		||||
                self._update_servicechain_instance(context, context.current,
 | 
			
		||||
 
 | 
			
		||||
@@ -82,14 +82,14 @@ class ServiceChainDBTestBase(object):
 | 
			
		||||
    def _get_test_servicechain_instance_attrs(self, name='sci1',
 | 
			
		||||
                                              description='test sci',
 | 
			
		||||
                                              config_param_values="{}",
 | 
			
		||||
                                              servicechain_spec=None,
 | 
			
		||||
                                              servicechain_specs=[],
 | 
			
		||||
                                              provider_ptg_id=None,
 | 
			
		||||
                                              consumer_ptg_id=None,
 | 
			
		||||
                                              classifier_id=None):
 | 
			
		||||
        attrs = {'name': name, 'description': description,
 | 
			
		||||
                 'tenant_id': self._tenant_id,
 | 
			
		||||
                 'config_param_values': config_param_values,
 | 
			
		||||
                 'servicechain_spec': servicechain_spec,
 | 
			
		||||
                 'servicechain_specs': servicechain_specs,
 | 
			
		||||
                 'provider_ptg_id': provider_ptg_id,
 | 
			
		||||
                 'consumer_ptg_id': consumer_ptg_id,
 | 
			
		||||
                 'classifier_id': classifier_id}
 | 
			
		||||
@@ -167,7 +167,7 @@ class ServiceChainDBTestBase(object):
 | 
			
		||||
        self.assertIn('servicechain_spec', res)
 | 
			
		||||
        self.assertEqual([scn_id], res['servicechain_spec']['nodes'])
 | 
			
		||||
 | 
			
		||||
    def create_servicechain_instance(self, servicechain_spec=None,
 | 
			
		||||
    def create_servicechain_instance(self, servicechain_specs=[],
 | 
			
		||||
                                     config_param_values="{}",
 | 
			
		||||
                                     provider_ptg_id=None,
 | 
			
		||||
                                     consumer_ptg_id=None,
 | 
			
		||||
@@ -177,7 +177,7 @@ class ServiceChainDBTestBase(object):
 | 
			
		||||
        defaults.update(kwargs)
 | 
			
		||||
        data = {'servicechain_instance':
 | 
			
		||||
                {'config_param_values': config_param_values,
 | 
			
		||||
                 'servicechain_spec': servicechain_spec,
 | 
			
		||||
                 'servicechain_specs': servicechain_specs,
 | 
			
		||||
                 'tenant_id': self._tenant_id,
 | 
			
		||||
                 'provider_ptg_id': provider_ptg_id,
 | 
			
		||||
                 'consumer_ptg_id': consumer_ptg_id,
 | 
			
		||||
@@ -371,14 +371,14 @@ class TestServiceChainResources(ServiceChainDbTestCase):
 | 
			
		||||
        classifier_id = uuidutils.generate_uuid()
 | 
			
		||||
        config_param_values = "{}"
 | 
			
		||||
        attrs = self._get_test_servicechain_instance_attrs(
 | 
			
		||||
            servicechain_spec=scs_id,
 | 
			
		||||
            servicechain_specs=[scs_id],
 | 
			
		||||
            provider_ptg_id=policy_target_group_id,
 | 
			
		||||
            consumer_ptg_id=policy_target_group_id,
 | 
			
		||||
            classifier_id=classifier_id,
 | 
			
		||||
            config_param_values=config_param_values)
 | 
			
		||||
 | 
			
		||||
        sci = self.create_servicechain_instance(
 | 
			
		||||
            servicechain_spec=scs_id,
 | 
			
		||||
            servicechain_specs=[scs_id],
 | 
			
		||||
            provider_ptg_id=policy_target_group_id,
 | 
			
		||||
            consumer_ptg_id=policy_target_group_id,
 | 
			
		||||
            classifier_id=classifier_id,
 | 
			
		||||
@@ -411,18 +411,18 @@ class TestServiceChainResources(ServiceChainDbTestCase):
 | 
			
		||||
        consumer_ptg_id = uuidutils.generate_uuid()
 | 
			
		||||
        classifier_id = uuidutils.generate_uuid()
 | 
			
		||||
        attrs = self._get_test_servicechain_instance_attrs(
 | 
			
		||||
            name=name, description=description, servicechain_spec=scs_id,
 | 
			
		||||
            name=name, description=description, servicechain_specs=[scs_id],
 | 
			
		||||
            provider_ptg_id=provider_ptg_id, consumer_ptg_id=consumer_ptg_id,
 | 
			
		||||
            classifier_id=classifier_id,
 | 
			
		||||
            config_param_values=config_param_values)
 | 
			
		||||
 | 
			
		||||
        sci = self.create_servicechain_instance(
 | 
			
		||||
            servicechain_spec=scs_id, provider_ptg_id=provider_ptg_id,
 | 
			
		||||
            servicechain_specs=[scs_id], provider_ptg_id=provider_ptg_id,
 | 
			
		||||
            consumer_ptg_id=consumer_ptg_id, classifier_id=classifier_id,
 | 
			
		||||
            config_param_values=config_param_values)
 | 
			
		||||
        data = {'servicechain_instance': {'name': name,
 | 
			
		||||
                                          'description': description,
 | 
			
		||||
                                          'servicechain_spec': scs_id}}
 | 
			
		||||
                                          'servicechain_specs': [scs_id]}}
 | 
			
		||||
        req = self.new_update_request('servicechain_instances', data,
 | 
			
		||||
                                      sci['servicechain_instance']['id'])
 | 
			
		||||
        res = self.deserialize(self.fmt, req.get_response(self.ext_api))
 | 
			
		||||
 
 | 
			
		||||
@@ -158,9 +158,21 @@ class ResourceMappingTestCase(
 | 
			
		||||
        if prs['parent_id']:
 | 
			
		||||
            parent = self.show_policy_rule_set(
 | 
			
		||||
                prs['parent_id'])['policy_rule_set']
 | 
			
		||||
            return [self.show_policy_rule(x)['policy_rule']
 | 
			
		||||
                    for x in prs['policy_rules']
 | 
			
		||||
                    if x in parent['policy_rules']]
 | 
			
		||||
            parent_policy_rules = [self.show_policy_rule(
 | 
			
		||||
                                    policy_rule_id)['policy_rule'] for
 | 
			
		||||
                                   policy_rule_id in parent["policy_rules"]]
 | 
			
		||||
            subset_rules = [self.show_policy_rule(
 | 
			
		||||
                            policy_rule_id)['policy_rule'] for
 | 
			
		||||
                            policy_rule_id in prs['policy_rules']]
 | 
			
		||||
 | 
			
		||||
            parent_classifier_ids = [x['policy_classifier_id']
 | 
			
		||||
                                     for x in parent_policy_rules]
 | 
			
		||||
            policy_rules = [x['id'] for x in subset_rules
 | 
			
		||||
                            if x['policy_classifier_id']
 | 
			
		||||
                            in set(parent_classifier_ids)]
 | 
			
		||||
            return [self.show_policy_rule(
 | 
			
		||||
                    policy_rule_id)['policy_rule'] for
 | 
			
		||||
                    policy_rule_id in policy_rules]
 | 
			
		||||
        else:
 | 
			
		||||
            return [self.show_policy_rule(x)['policy_rule']
 | 
			
		||||
                    for x in prs['policy_rules']]
 | 
			
		||||
@@ -1432,7 +1444,7 @@ class TestPolicyRuleSet(ResourceMappingTestCase):
 | 
			
		||||
        sc_instance = sc_instances['servicechain_instances'][0]
 | 
			
		||||
        self.assertEqual(sc_instance['provider_ptg_id'], provider_ptg_id)
 | 
			
		||||
        self.assertEqual(sc_instance['consumer_ptg_id'], consumer_ptg_id)
 | 
			
		||||
        self.assertEqual(scs_id, sc_instance['servicechain_spec'])
 | 
			
		||||
        self.assertEqual([scs_id], sc_instance['servicechain_specs'])
 | 
			
		||||
 | 
			
		||||
        data = {'servicechain_node': {'service_type': "FIREWALL",
 | 
			
		||||
                                      'tenant_id': self._tenant_id,
 | 
			
		||||
@@ -1459,7 +1471,8 @@ class TestPolicyRuleSet(ResourceMappingTestCase):
 | 
			
		||||
        self.assertEqual(len(new_sc_instances['servicechain_instances']), 1)
 | 
			
		||||
        new_sc_instance = new_sc_instances['servicechain_instances'][0]
 | 
			
		||||
        self.assertEqual(sc_instance['id'], new_sc_instance['id'])
 | 
			
		||||
        self.assertEqual(new_scs_id, new_sc_instance['servicechain_spec'])
 | 
			
		||||
        self.assertEqual([new_scs_id], new_sc_instance['servicechain_specs'])
 | 
			
		||||
 | 
			
		||||
        req = self.new_delete_request(
 | 
			
		||||
                'policy_target_groups', consumer_ptg_id)
 | 
			
		||||
        res = req.get_response(self.ext_api)
 | 
			
		||||
@@ -1482,6 +1495,7 @@ class TestPolicyRuleSet(ResourceMappingTestCase):
 | 
			
		||||
        scs_req = self.new_create_request(SERVICECHAIN_SPECS, data, self.fmt)
 | 
			
		||||
        spec = self.deserialize(self.fmt, scs_req.get_response(self.ext_api))
 | 
			
		||||
        scs_id = spec['servicechain_spec']['id']
 | 
			
		||||
 | 
			
		||||
        classifier = self.create_policy_classifier(
 | 
			
		||||
            name="class1", protocol="tcp", direction="in", port_range="20:90")
 | 
			
		||||
        classifier_id = classifier['policy_classifier']['id']
 | 
			
		||||
@@ -1572,6 +1586,99 @@ class TestPolicyRuleSet(ResourceMappingTestCase):
 | 
			
		||||
        # No more service chain instances when all the providers are deleted
 | 
			
		||||
        self.assertEqual(len(sc_instances['servicechain_instances']), 0)
 | 
			
		||||
 | 
			
		||||
    def test_hierarchial_redirect(self):
 | 
			
		||||
        data = {'servicechain_node': {'service_type': "LOADBALANCER",
 | 
			
		||||
                                      'tenant_id': self._tenant_id,
 | 
			
		||||
                                      'config': "{}"}}
 | 
			
		||||
        scn_req = self.new_create_request(SERVICECHAIN_NODES, data, self.fmt)
 | 
			
		||||
        node = self.deserialize(self.fmt, scn_req.get_response(self.ext_api))
 | 
			
		||||
        scn_id = node['servicechain_node']['id']
 | 
			
		||||
        data = {'servicechain_spec': {'tenant_id': self._tenant_id,
 | 
			
		||||
                                      'nodes': [scn_id]}}
 | 
			
		||||
        scs_req = self.new_create_request(SERVICECHAIN_SPECS, data, self.fmt)
 | 
			
		||||
        spec = self.deserialize(self.fmt, scs_req.get_response(self.ext_api))
 | 
			
		||||
        scs_id = spec['servicechain_spec']['id']
 | 
			
		||||
        classifier1 = self.create_policy_classifier(
 | 
			
		||||
            name="class1", protocol="tcp", direction="in", port_range="20:90")
 | 
			
		||||
        classifier1_id = classifier1['policy_classifier']['id']
 | 
			
		||||
        classifier2 = self.create_policy_classifier(
 | 
			
		||||
                name="class1", protocol="tcp", direction="in", port_range="80")
 | 
			
		||||
        classifier2_id = classifier2['policy_classifier']['id']
 | 
			
		||||
        action = self.create_policy_action(
 | 
			
		||||
            name="action1", action_type=gconst.GP_ACTION_REDIRECT,
 | 
			
		||||
            action_value=scs_id)
 | 
			
		||||
        action_id = action['policy_action']['id']
 | 
			
		||||
        policy_rule1 = self.create_policy_rule(
 | 
			
		||||
            name='pr1', policy_classifier_id=classifier1_id,
 | 
			
		||||
            policy_actions=[action_id])
 | 
			
		||||
        policy_rule1_id = policy_rule1['policy_rule']['id']
 | 
			
		||||
        policy_rule2 = self.create_policy_rule(
 | 
			
		||||
            name='pr2', policy_classifier_id=classifier2_id,
 | 
			
		||||
            policy_actions=[action_id])
 | 
			
		||||
        policy_rule2_id = policy_rule2['policy_rule']['id']
 | 
			
		||||
        policy_rule_set = self.create_policy_rule_set(
 | 
			
		||||
            name="prs", policy_rules=[policy_rule1_id, policy_rule2_id])
 | 
			
		||||
        policy_rule_set_id = policy_rule_set['policy_rule_set']['id']
 | 
			
		||||
 | 
			
		||||
        data = {'servicechain_node': {'service_type': "FIREWALL",
 | 
			
		||||
                                      'tenant_id': self._tenant_id,
 | 
			
		||||
                                      'config': "{}"}}
 | 
			
		||||
        parent_scn_req = self.new_create_request(SERVICECHAIN_NODES,
 | 
			
		||||
                                                 data, self.fmt)
 | 
			
		||||
        parent_sc_node = self.deserialize(
 | 
			
		||||
                self.fmt, parent_scn_req.get_response(self.ext_api))
 | 
			
		||||
        parent_scn_id = parent_sc_node['servicechain_node']['id']
 | 
			
		||||
        data = {'servicechain_spec': {'tenant_id': self._tenant_id,
 | 
			
		||||
                                      'nodes': [parent_scn_id]}}
 | 
			
		||||
        parent_scs_req = self.new_create_request(
 | 
			
		||||
                        SERVICECHAIN_SPECS, data, self.fmt)
 | 
			
		||||
        parent_spec = self.deserialize(
 | 
			
		||||
                        self.fmt, parent_scs_req.get_response(self.ext_api))
 | 
			
		||||
        parent_scs_id = parent_spec['servicechain_spec']['id']
 | 
			
		||||
 | 
			
		||||
        parent_action = self.create_policy_action(
 | 
			
		||||
            name="action2", action_type=gconst.GP_ACTION_REDIRECT,
 | 
			
		||||
            action_value=parent_scs_id)
 | 
			
		||||
        parent_action_id = parent_action['policy_action']['id']
 | 
			
		||||
        parent_policy_rule = self.create_policy_rule(
 | 
			
		||||
            name='pr1', policy_classifier_id=classifier2_id,
 | 
			
		||||
            policy_actions=[parent_action_id])
 | 
			
		||||
        parent_policy_rule_id = parent_policy_rule['policy_rule']['id']
 | 
			
		||||
 | 
			
		||||
        self.create_policy_rule_set(
 | 
			
		||||
            name="c1", policy_rules=[parent_policy_rule_id],
 | 
			
		||||
            child_policy_rule_sets=[policy_rule_set_id])
 | 
			
		||||
 | 
			
		||||
        provider_ptg = self.create_policy_target_group(
 | 
			
		||||
            name="ptg1", provided_policy_rule_sets={policy_rule_set_id: None})
 | 
			
		||||
        provider_ptg_id = provider_ptg['policy_target_group']['id']
 | 
			
		||||
        consumer_ptg = self.create_policy_target_group(
 | 
			
		||||
            name="ptg2",
 | 
			
		||||
            consumed_policy_rule_sets={policy_rule_set_id: None})
 | 
			
		||||
        consumer_ptg_id = consumer_ptg['policy_target_group']['id']
 | 
			
		||||
        sc_node_list_req = self.new_list_request(SERVICECHAIN_INSTANCES)
 | 
			
		||||
        res = sc_node_list_req.get_response(self.ext_api)
 | 
			
		||||
        sc_instances = self.deserialize(self.fmt, res)
 | 
			
		||||
        # We should have one service chain instance created now
 | 
			
		||||
        self.assertEqual(len(sc_instances['servicechain_instances']), 1)
 | 
			
		||||
        sc_instance = sc_instances['servicechain_instances'][0]
 | 
			
		||||
        self.assertEqual(sc_instance['provider_ptg_id'], provider_ptg_id)
 | 
			
		||||
        self.assertEqual(sc_instance['consumer_ptg_id'], consumer_ptg_id)
 | 
			
		||||
        self.assertEqual(sc_instance['classifier_id'], classifier2_id)
 | 
			
		||||
        #REVISIT(Magesh): List api retrieves in different order
 | 
			
		||||
        #Functionally create/update is working fine
 | 
			
		||||
        #self.assertEqual(sc_instance['servicechain_spec'],
 | 
			
		||||
        #                 [parent_scs_id, scs_id])
 | 
			
		||||
 | 
			
		||||
        req = self.new_delete_request(
 | 
			
		||||
            'policy_target_groups', consumer_ptg_id)
 | 
			
		||||
        res = req.get_response(self.ext_api)
 | 
			
		||||
        self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code)
 | 
			
		||||
        sc_node_list_req = self.new_list_request(SERVICECHAIN_INSTANCES)
 | 
			
		||||
        res = sc_node_list_req.get_response(self.ext_api)
 | 
			
		||||
        sc_instances = self.deserialize(self.fmt, res)
 | 
			
		||||
        self.assertEqual(len(sc_instances['servicechain_instances']), 0)
 | 
			
		||||
 | 
			
		||||
    def test_shared_policy_rule_set_create_negative(self):
 | 
			
		||||
        self.create_policy_rule_set(shared=True,
 | 
			
		||||
                                    expected_res_status=400)
 | 
			
		||||
@@ -1711,6 +1818,41 @@ class TestPolicyRuleSet(ResourceMappingTestCase):
 | 
			
		||||
            port_range=8080)
 | 
			
		||||
        self._verify_prs_rules(prs['id'])
 | 
			
		||||
 | 
			
		||||
    def _update_same_classifier_multiple_rules(self):
 | 
			
		||||
        action = self.create_policy_action(
 | 
			
		||||
            action_type='allow')['policy_action']
 | 
			
		||||
        classifier = self.create_policy_classifier(
 | 
			
		||||
            protocol='TCP', port_range="22",
 | 
			
		||||
            direction='bi')['policy_classifier']
 | 
			
		||||
 | 
			
		||||
        pr1 = self.create_policy_rule(
 | 
			
		||||
            policy_classifier_id=classifier['id'],
 | 
			
		||||
            policy_actions=[action['id']])['policy_rule']
 | 
			
		||||
        pr2 = self.create_policy_rule(
 | 
			
		||||
            policy_classifier_id=classifier['id'],
 | 
			
		||||
            policy_actions=[action['id']])['policy_rule']
 | 
			
		||||
 | 
			
		||||
        prs = self.create_policy_rule_set(
 | 
			
		||||
            policy_rules=[pr1['id']],
 | 
			
		||||
            expected_res_status=201)['policy_rule_set']
 | 
			
		||||
        self.create_policy_rule_set(
 | 
			
		||||
            policy_rules=[pr2['id']], child_policy_rule_sets=[prs['id']],
 | 
			
		||||
            expected_res_status=201)
 | 
			
		||||
        self._verify_prs_rules(prs['id'])
 | 
			
		||||
 | 
			
		||||
        self.create_policy_target_group(
 | 
			
		||||
            provided_policy_rule_sets={prs['id']: None},
 | 
			
		||||
            expected_res_status=201)
 | 
			
		||||
        self.create_policy_target_group(
 | 
			
		||||
            consumed_policy_rule_sets={prs['id']: None},
 | 
			
		||||
            expected_res_status=201)
 | 
			
		||||
        self._verify_prs_rules(prs['id'])
 | 
			
		||||
 | 
			
		||||
        self.update_policy_classifier(
 | 
			
		||||
            pr1['policy_classifier_id'], expected_res_status=200,
 | 
			
		||||
            port_range=8080)
 | 
			
		||||
        self._verify_prs_rules(prs['id'])
 | 
			
		||||
 | 
			
		||||
    def test_delete_policy_rule(self):
 | 
			
		||||
        pr = self._create_http_allow_rule()
 | 
			
		||||
        pr2 = self._create_ssh_allow_rule()
 | 
			
		||||
 
 | 
			
		||||
@@ -79,10 +79,10 @@ class TestServiceChainInstance(SimpleChainDriverTestCase):
 | 
			
		||||
            instance1_name = "sc_instance_1"
 | 
			
		||||
            sc_instance1 = self.create_servicechain_instance(
 | 
			
		||||
                                        name=instance1_name,
 | 
			
		||||
                                        servicechain_spec=sc_spec_id)
 | 
			
		||||
                                        servicechain_specs=[sc_spec_id])
 | 
			
		||||
            self.assertEqual(
 | 
			
		||||
                sc_instance1['servicechain_instance']['servicechain_spec'],
 | 
			
		||||
                sc_spec_id)
 | 
			
		||||
                sc_instance1['servicechain_instance']['servicechain_specs'],
 | 
			
		||||
                [sc_spec_id])
 | 
			
		||||
            stack_name = "stack_" + instance1_name + scn1_name + scn_id[:5]
 | 
			
		||||
            expected_create_calls.append(
 | 
			
		||||
                        mock.call(stack_name, jsonutils.loads(template1), {}))
 | 
			
		||||
@@ -90,10 +90,10 @@ class TestServiceChainInstance(SimpleChainDriverTestCase):
 | 
			
		||||
            instance2_name = "sc_instance_2"
 | 
			
		||||
            sc_instance2 = self.create_servicechain_instance(
 | 
			
		||||
                                        name=instance2_name,
 | 
			
		||||
                                        servicechain_spec=sc_spec_id)
 | 
			
		||||
                                        servicechain_specs=[sc_spec_id])
 | 
			
		||||
            self.assertEqual(
 | 
			
		||||
                sc_instance2['servicechain_instance']['servicechain_spec'],
 | 
			
		||||
                sc_spec_id)
 | 
			
		||||
                sc_instance2['servicechain_instance']['servicechain_specs'],
 | 
			
		||||
                [sc_spec_id])
 | 
			
		||||
            stack_name = "stack_" + instance2_name + scn1_name + scn_id[:5]
 | 
			
		||||
            expected_create_calls.append(
 | 
			
		||||
                        mock.call(stack_name, jsonutils.loads(template1), {}))
 | 
			
		||||
@@ -133,10 +133,10 @@ class TestServiceChainInstance(SimpleChainDriverTestCase):
 | 
			
		||||
                                        'id': uuidutils.generate_uuid()}}
 | 
			
		||||
            sc_instance = self.create_servicechain_instance(
 | 
			
		||||
                                        name="sc_instance_1",
 | 
			
		||||
                                        servicechain_spec=sc_spec_id)
 | 
			
		||||
                                        servicechain_specs=[sc_spec_id])
 | 
			
		||||
            self.assertEqual(
 | 
			
		||||
                sc_instance['servicechain_instance']['servicechain_spec'],
 | 
			
		||||
                sc_spec_id)
 | 
			
		||||
                sc_instance['servicechain_instance']['servicechain_specs'],
 | 
			
		||||
                [sc_spec_id])
 | 
			
		||||
            stack_create.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY)
 | 
			
		||||
 | 
			
		||||
    def test_chain_instance_delete(self):
 | 
			
		||||
@@ -152,10 +152,10 @@ class TestServiceChainInstance(SimpleChainDriverTestCase):
 | 
			
		||||
                                        'id': uuidutils.generate_uuid()}}
 | 
			
		||||
            sc_instance = self.create_servicechain_instance(
 | 
			
		||||
                                        name="sc_instance_1",
 | 
			
		||||
                                        servicechain_spec=sc_spec_id)
 | 
			
		||||
                                        servicechain_specs=[sc_spec_id])
 | 
			
		||||
            self.assertEqual(
 | 
			
		||||
                sc_instance['servicechain_instance']['servicechain_spec'],
 | 
			
		||||
                sc_spec_id)
 | 
			
		||||
                sc_instance['servicechain_instance']['servicechain_specs'],
 | 
			
		||||
                [sc_spec_id])
 | 
			
		||||
            with mock.patch.object(simplechain_driver.HeatClient,
 | 
			
		||||
                                   'delete'):
 | 
			
		||||
                req = self.new_delete_request(
 | 
			
		||||
 
 | 
			
		||||
@@ -304,7 +304,7 @@ class ServiceChainExtensionTestCase(test_api_v2_extension.ExtensionTestCase):
 | 
			
		||||
    def _get_create_servicechain_instance_attrs(self):
 | 
			
		||||
        return {
 | 
			
		||||
            'name': 'servicechaininstance1',
 | 
			
		||||
            'servicechain_spec': _uuid(),
 | 
			
		||||
            'servicechain_specs': [_uuid()],
 | 
			
		||||
            'tenant_id': _uuid(),
 | 
			
		||||
            'provider_ptg_id': _uuid(),
 | 
			
		||||
            'consumer_ptg_id': _uuid(),
 | 
			
		||||
@@ -316,18 +316,18 @@ class ServiceChainExtensionTestCase(test_api_v2_extension.ExtensionTestCase):
 | 
			
		||||
    def _get_update_servicechain_instance_attrs(self):
 | 
			
		||||
        return {
 | 
			
		||||
            'name': 'new_name',
 | 
			
		||||
            'servicechain_spec': _uuid()
 | 
			
		||||
            'servicechain_specs': [_uuid()]
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def test_create_servicechain_instance_with_defaults(self):
 | 
			
		||||
        servicechain_instance_id = _uuid()
 | 
			
		||||
        data = {
 | 
			
		||||
            'servicechain_instance': {
 | 
			
		||||
                'servicechain_spec': _uuid(),
 | 
			
		||||
                'servicechain_specs': [_uuid()],
 | 
			
		||||
                'tenant_id': _uuid(),
 | 
			
		||||
                'provider_ptg_id': _uuid(),
 | 
			
		||||
                'consumer_ptg_id': _uuid(),
 | 
			
		||||
                'classifier_id': _uuid()
 | 
			
		||||
                'classifier_id': _uuid(),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        default_attrs = self._get_create_servicechain_instance_default_attrs()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user