Status attributes for GBP resources

Adds attributes to reflect the opertaional status of a resource.

Also updates Policy Driver interface and Policy Plugin implementation
to conditionally allow policy drivers to pull and update status
in response to a GET.

Change-Id: I4f123d8b84125427032ebb9d75aad40b33617271
Implements: blueprint resource-status
This commit is contained in:
Sumit Naiksatam 2016-03-07 11:24:32 -08:00
parent 9519193d9c
commit 05a7709fb2
16 changed files with 862 additions and 433 deletions

3
.gitignore vendored
View File

@ -54,3 +54,6 @@ ChangeLog
*~
.*.swp
.*sw?
# Pycharm
.idea

View File

@ -34,18 +34,18 @@ MAX_IPV6_SUBNET_PREFIX_LENGTH = 127
ADDRESS_NOT_SPECIFIED = ''
class HasNameDescription(object):
class BaseGbpResource(models_v2.HasId, models_v2.HasTenant):
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
status = sa.Column(sa.String(length=16), nullable=True)
status_details = sa.Column(sa.String(length=4096), nullable=True)
class BaseSharedGbpResource(models_v2.HasId, models_v2.HasTenant,
HasNameDescription):
class BaseSharedGbpResource(BaseGbpResource):
shared = sa.Column(sa.Boolean)
pass
class PolicyTarget(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
class PolicyTarget(model_base.BASEV2, BaseGbpResource):
"""Lowest unit of abstraction on which a policy is applied."""
__tablename__ = 'gp_policy_targets'
type = sa.Column(sa.String(15))
@ -53,8 +53,6 @@ class PolicyTarget(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
'polymorphic_on': type,
'polymorphic_identity': 'base'
}
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
policy_target_group_id = sa.Column(sa.String(36),
sa.ForeignKey(
'gp_policy_target_groups.id'),
@ -86,8 +84,7 @@ class PTGToPRSConsumingAssociation(model_base.BASEV2):
primary_key=True)
class PolicyTargetGroup(model_base.BASEV2,
models_v2.HasId, models_v2.HasTenant):
class PolicyTargetGroup(model_base.BASEV2, BaseSharedGbpResource):
"""It is a collection of policy_targets."""
__tablename__ = 'gp_policy_target_groups'
type = sa.Column(sa.String(15))
@ -95,8 +92,6 @@ class PolicyTargetGroup(model_base.BASEV2,
'polymorphic_on': type,
'polymorphic_identity': 'base'
}
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
policy_targets = orm.relationship(PolicyTarget,
backref='policy_target_group')
l2_policy_id = sa.Column(sa.String(36),
@ -111,11 +106,10 @@ class PolicyTargetGroup(model_base.BASEV2,
consumed_policy_rule_sets = orm.relationship(
PTGToPRSConsumingAssociation,
backref='consuming_policy_target_group', cascade='all, delete-orphan')
shared = sa.Column(sa.Boolean)
service_management = sa.Column(sa.Boolean)
class L2Policy(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
class L2Policy(model_base.BASEV2, BaseSharedGbpResource):
"""Represents a L2 Policy for a collection of policy_target_groups."""
__tablename__ = 'gp_l2_policies'
type = sa.Column(sa.String(15))
@ -123,8 +117,6 @@ class L2Policy(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
'polymorphic_on': type,
'polymorphic_identity': 'base'
}
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
policy_target_groups = orm.relationship(PolicyTargetGroup,
backref='l2_policy')
l3_policy_id = sa.Column(sa.String(36),
@ -132,7 +124,6 @@ class L2Policy(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
nullable=True)
inject_default_route = sa.Column(sa.Boolean, default=True,
server_default=sa.sql.true())
shared = sa.Column(sa.Boolean)
class ESToL3PAssociation(model_base.BASEV2):
@ -147,7 +138,7 @@ class ESToL3PAssociation(model_base.BASEV2):
primary_key=True)
class L3Policy(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
class L3Policy(model_base.BASEV2, BaseSharedGbpResource):
"""Represents a L3 Policy with a non-overlapping IP address space."""
__tablename__ = 'gp_l3_policies'
type = sa.Column(sa.String(15))
@ -155,13 +146,10 @@ class L3Policy(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
'polymorphic_on': type,
'polymorphic_identity': 'base'
}
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
ip_version = sa.Column(sa.Integer, nullable=False)
ip_pool = sa.Column(sa.String(64), nullable=False)
subnet_prefix_length = sa.Column(sa.Integer, nullable=False)
l2_policies = orm.relationship(L2Policy, backref='l3_policy')
shared = sa.Column(sa.Boolean)
external_segments = orm.relationship(
ESToL3PAssociation, backref='l3_policies',
cascade='all, delete-orphan')
@ -178,18 +166,14 @@ class NetworkServiceParam(model_base.BASEV2, models_v2.HasId):
nullable=False)
class NetworkServicePolicy(model_base.BASEV2, models_v2.HasId,
models_v2.HasTenant):
class NetworkServicePolicy(model_base.BASEV2, BaseSharedGbpResource):
"""Represents a Network Service Policy."""
__tablename__ = 'gp_network_service_policies'
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
policy_target_groups = orm.relationship(PolicyTargetGroup,
backref='network_service_policy')
network_service_params = orm.relationship(
NetworkServiceParam, backref='network_service_policy',
cascade='all, delete-orphan')
shared = sa.Column(sa.Boolean)
class PRSToPRAssociation(model_base.BASEV2):
@ -215,11 +199,9 @@ class PolicyRuleActionAssociation(model_base.BASEV2):
primary_key=True)
class PolicyRule(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
class PolicyRule(model_base.BASEV2, BaseSharedGbpResource):
"""Represents a Group Policy Rule."""
__tablename__ = 'gp_policy_rules'
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
enabled = sa.Column(sa.Boolean)
policy_classifier_id = sa.Column(sa.String(36),
sa.ForeignKey(
@ -231,15 +213,11 @@ class PolicyRule(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
policy_rule_sets = orm.relationship(PRSToPRAssociation,
backref='policy_rule', lazy="joined",
cascade='all, delete-orphan')
shared = sa.Column(sa.Boolean)
class PolicyClassifier(model_base.BASEV2, models_v2.HasId,
models_v2.HasTenant):
class PolicyClassifier(model_base.BASEV2, BaseSharedGbpResource):
"""Represents a Group Policy Classifier."""
__tablename__ = 'gp_policy_classifiers'
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
protocol = sa.Column(sa.String(50), nullable=True)
port_range_min = sa.Column(sa.Integer)
port_range_max = sa.Column(sa.Integer)
@ -249,14 +227,11 @@ class PolicyClassifier(model_base.BASEV2, models_v2.HasId,
name='direction'))
policy_rules = orm.relationship(PolicyRule,
backref='gp_policy_classifiers')
shared = sa.Column(sa.Boolean)
class PolicyAction(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
class PolicyAction(model_base.BASEV2, BaseSharedGbpResource):
"""Represents a Group Policy Action."""
__tablename__ = 'gp_policy_actions'
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
action_type = sa.Column(sa.Enum(gp_constants.GP_ACTION_ALLOW,
gp_constants.GP_ACTION_REDIRECT,
name='action_type'))
@ -266,7 +241,6 @@ class PolicyAction(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
action_value = sa.Column(sa.String(36), nullable=True)
policy_rules = orm.relationship(PolicyRuleActionAssociation,
cascade='all', backref='gp_policy_actions')
shared = sa.Column(sa.Boolean)
class EPToPRSProvidingAssociation(model_base.BASEV2):
@ -319,6 +293,8 @@ class PolicyRuleSet(model_base.BASEV2, models_v2.HasTenant):
EPToPRSConsumingAssociation,
backref='consumed_policy_rule_set', lazy="joined", cascade='all')
shared = sa.Column(sa.Boolean)
status = sa.Column(sa.String(length=16), nullable=True)
status_details = sa.Column(sa.String(length=4096), nullable=True)
class NATPool(model_base.BASEV2, BaseSharedGbpResource):
@ -794,24 +770,32 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
l3_policy_id=l3p_db['id'], allocated_address=ip)
l3p_db.external_segments.append(assoc)
def _populate_common_fields_in_dict(self, db_ref):
res = {'id': db_ref['id'],
'tenant_id': db_ref['tenant_id'],
'name': db_ref['name'],
'description': db_ref['description'],
'status': db_ref['status'],
'status_details': db_ref['status_details'],
'shared': db_ref.get('shared', False)}
return res
def _make_policy_target_dict(self, pt, fields=None):
res = {'id': pt['id'],
'tenant_id': pt['tenant_id'],
'name': pt['name'],
'description': pt['description'],
'status': pt['status'],
'status_details': pt['status_details'],
'policy_target_group_id': pt['policy_target_group_id'],
'cluster_id': pt['cluster_id']}
return self._fields(res, fields)
def _make_policy_target_group_dict(self, ptg, fields=None):
res = {'id': ptg['id'],
'tenant_id': ptg['tenant_id'],
'name': ptg['name'],
'description': ptg['description'],
'l2_policy_id': ptg['l2_policy_id'],
'network_service_policy_id': ptg['network_service_policy_id'],
'shared': ptg.get('shared', False),
'service_management': ptg.get('service_management', False)}
res = self._populate_common_fields_in_dict(ptg)
res['l2_policy_id'] = ptg['l2_policy_id']
res['network_service_policy_id'] = ptg['network_service_policy_id']
res['service_management'] = ptg.get('service_management', False)
res['policy_targets'] = [
pt['id'] for pt in ptg['policy_targets']]
res['provided_policy_rule_sets'] = (
@ -823,27 +807,18 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
return self._fields(res, fields)
def _make_l2_policy_dict(self, l2p, fields=None):
res = {'id': l2p['id'],
'tenant_id': l2p['tenant_id'],
'name': l2p['name'],
'description': l2p['description'],
'l3_policy_id': l2p['l3_policy_id'],
'inject_default_route': l2p.get('inject_default_route', True),
'shared': l2p.get('shared', False), }
res = self._populate_common_fields_in_dict(l2p)
res['l3_policy_id'] = l2p['l3_policy_id']
res['inject_default_route'] = l2p.get('inject_default_route', True)
res['policy_target_groups'] = [
ptg['id'] for ptg in l2p['policy_target_groups']]
return self._fields(res, fields)
def _make_l3_policy_dict(self, l3p, fields=None):
res = {'id': l3p['id'],
'tenant_id': l3p['tenant_id'],
'name': l3p['name'],
'description': l3p['description'],
'ip_version': l3p['ip_version'],
'ip_pool': l3p['ip_pool'],
'subnet_prefix_length':
l3p['subnet_prefix_length'],
'shared': l3p.get('shared', False), }
res = self._populate_common_fields_in_dict(l3p)
res['ip_version'] = l3p['ip_version']
res['ip_pool'] = l3p['ip_pool']
res['subnet_prefix_length'] = l3p['subnet_prefix_length']
res['l2_policies'] = [l2p['id']
for l2p in l3p['l2_policies']]
es_dict = {}
@ -856,11 +831,7 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
return self._fields(res, fields)
def _make_network_service_policy_dict(self, nsp, fields=None):
res = {'id': nsp['id'],
'tenant_id': nsp['tenant_id'],
'name': nsp['name'],
'description': nsp['description'],
'shared': nsp.get('shared', False), }
res = self._populate_common_fields_in_dict(nsp)
res['policy_target_groups'] = [
ptg['id'] for ptg in nsp['policy_target_groups']]
params = []
@ -873,41 +844,29 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
return self._fields(res, fields)
def _make_policy_classifier_dict(self, pc, fields=None):
res = self._populate_common_fields_in_dict(pc)
port_range = self._get_port_range_from_min_max_ports(
pc['port_range_min'],
pc['port_range_max'])
res = {'id': pc['id'],
'tenant_id': pc['tenant_id'],
'name': pc['name'],
'description': pc['description'],
'protocol': pc['protocol'],
'port_range': port_range,
'direction': pc['direction'],
'shared': pc.get('shared', False), }
res['protocol'] = pc['protocol']
res['port_range'] = port_range
res['direction'] = pc['direction']
res['policy_rules'] = [pr['id']
for pr in pc['policy_rules']]
return self._fields(res, fields)
def _make_policy_action_dict(self, pa, fields=None):
res = {'id': pa['id'],
'tenant_id': pa['tenant_id'],
'name': pa['name'],
'description': pa['description'],
'action_type': pa['action_type'],
'action_value': pa['action_value'],
'shared': pa.get('shared', False), }
res = self._populate_common_fields_in_dict(pa)
res['action_type'] = pa['action_type']
res['action_value'] = pa['action_value']
res['policy_rules'] = [pr['policy_rule_id'] for
pr in pa['policy_rules']]
return self._fields(res, fields)
def _make_policy_rule_dict(self, pr, fields=None):
res = {'id': pr['id'],
'tenant_id': pr['tenant_id'],
'name': pr['name'],
'description': pr['description'],
'enabled': pr['enabled'],
'policy_classifier_id': pr['policy_classifier_id'],
'shared': pr.get('shared', False), }
res = self._populate_common_fields_in_dict(pr)
res['enabled'] = pr['enabled']
res['policy_classifier_id'] = pr['policy_classifier_id']
res['policy_actions'] = [pa['policy_action_id']
for pa in pr['policy_actions']]
res['policy_rule_sets'] = [prs['policy_rule_set_id'] for prs in
@ -915,11 +874,7 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
return self._fields(res, fields)
def _make_policy_rule_set_dict(self, prs, fields=None):
res = {'id': prs['id'],
'tenant_id': prs['tenant_id'],
'name': prs['name'],
'description': prs['description'],
'shared': prs.get('shared', False), }
res = self._populate_common_fields_in_dict(prs)
if prs['parent']:
res['parent_id'] = prs['parent']['id']
else:
@ -958,14 +913,10 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
return self._fields(res, fields)
def _make_external_segment_dict(self, es, fields=None):
res = {'id': es['id'],
'tenant_id': es['tenant_id'],
'name': es['name'],
'description': es['description'],
'shared': es.get('shared', False),
'ip_version': es['ip_version'],
'cidr': es['cidr'],
'port_address_translation': es['port_address_translation']}
res = self._populate_common_fields_in_dict(es)
res['ip_version'] = es['ip_version']
res['cidr'] = es['cidr']
res['port_address_translation'] = es['port_address_translation']
res['external_routes'] = [{'destination': er['destination'],
'nexthop': er['nexthop']} for er in
es['external_routes']]
@ -979,11 +930,7 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
return self._fields(res, fields)
def _make_external_policy_dict(self, ep, fields=None):
res = {'id': ep['id'],
'tenant_id': ep['tenant_id'],
'name': ep['name'],
'description': ep['description'],
'shared': ep.get('shared', False), }
res = self._populate_common_fields_in_dict(ep)
res['external_segments'] = [
es['external_segment_id']
for es in ep['external_segments']]
@ -996,14 +943,10 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
return self._fields(res, fields)
def _make_nat_pool_dict(self, np, fields=None):
res = {'id': np['id'],
'tenant_id': np['tenant_id'],
'name': np['name'],
'description': np['description'],
'shared': np.get('shared', False),
'ip_version': np['ip_version'],
'ip_pool': np['ip_pool'],
'external_segment_id': np['external_segment_id']}
res = self._populate_common_fields_in_dict(np)
res['ip_version'] = np['ip_version']
res['ip_pool'] = np['ip_pool']
res['external_segment_id'] = np['external_segment_id']
return self._fields(res, fields)
def _get_ptgs_for_providing_policy_rule_set(self, context,
@ -1116,7 +1059,9 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
id=uuidutils.generate_uuid(), tenant_id=tenant_id,
name=pt['name'], description=pt['description'],
policy_target_group_id=pt['policy_target_group_id'],
cluster_id=pt['cluster_id'])
cluster_id=pt['cluster_id'],
status=pt.get('status'),
status_details=pt.get('status_details'))
context.session.add(pt_db)
return self._make_policy_target_dict(pt_db)
@ -1170,7 +1115,9 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
l2_policy_id=ptg['l2_policy_id'],
network_service_policy_id=ptg['network_service_policy_id'],
shared=ptg.get('shared', False),
service_management=ptg.get('service_management', False))
service_management=ptg.get('service_management', False),
status=ptg.get('status'),
status_details=ptg.get('status_details'))
context.session.add(ptg_db)
self._process_policy_rule_sets_for_ptg(context, ptg_db, ptg)
return self._make_policy_target_group_dict(ptg_db)
@ -1236,10 +1183,12 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
l2p_db = L2Policy(id=uuidutils.generate_uuid(),
tenant_id=tenant_id, name=l2p['name'],
description=l2p['description'],
l3_policy_id=l2p['l3_policy_id'],
l3_policy_id=l2p.get('l3_policy_id'),
inject_default_route=l2p.get(
'inject_default_route', True),
shared=l2p.get('shared', False))
shared=l2p.get('shared', False),
status=l2p.get('status'),
status_details=l2p.get('status_details'))
context.session.add(l2p_db)
return self._make_l2_policy_dict(l2p_db)
@ -1298,7 +1247,9 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
ip_version=l3p['ip_version'],
ip_pool=l3p['ip_pool'],
subnet_prefix_length=l3p['subnet_prefix_length'],
shared=l3p.get('shared', False))
shared=l3p.get('shared', False),
status=l3p.get('status'),
status_details=l3p.get('status_details'))
if 'external_segments' in l3p:
self._set_ess_for_l3p(context, l3p_db,
l3p['external_segments'])
@ -1361,7 +1312,10 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
tenant_id=tenant_id,
name=nsp['name'],
description=nsp['description'],
shared=nsp.get('shared', False))
shared=nsp.get('shared', False),
status=nsp.get('status'),
status_details=
nsp.get('status_details'))
context.session.add(nsp_db)
self._set_params_for_network_service_policy(
context, nsp_db, nsp)
@ -1431,7 +1385,10 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
port_range_min=port_min,
port_range_max=port_max,
direction=pc['direction'],
shared=pc.get('shared', False))
shared=pc.get('shared', False),
status=pc.get('status'),
status_details=
pc.get('status_details'))
context.session.add(pc_db)
return self._make_policy_classifier_dict(pc_db)
@ -1497,7 +1454,10 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
description=pa['description'],
action_type=pa['action_type'],
action_value=pa['action_value'],
shared=pa.get('shared', False))
shared=pa.get('shared', False),
status=pa.get('status'),
status_details=
pa.get('status_details'))
context.session.add(pa_db)
return self._make_policy_action_dict(pa_db)
@ -1552,7 +1512,9 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
description=pr['description'],
enabled=pr['enabled'],
policy_classifier_id=pr['policy_classifier_id'],
shared=pr.get('shared', False))
shared=pr.get('shared', False),
status=pr.get('status'),
status_details=pr.get('status_details'))
context.session.add(pr_db)
self._set_actions_for_rule(context, pr_db,
pr['policy_actions'])
@ -1612,7 +1574,9 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
tenant_id=tenant_id,
name=prs['name'],
description=prs['description'],
shared=prs.get('shared', False))
shared=prs.get('shared', False),
status=prs.get('status'),
status_details=prs.get('status_details'))
context.session.add(prs_db)
self._set_rules_for_policy_rule_set(context, prs_db,
prs['policy_rules'])
@ -1687,7 +1651,9 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
ep_db = ExternalPolicy(
id=uuidutils.generate_uuid(), tenant_id=tenant_id,
name=ep['name'], description=ep['description'],
shared=ep.get('shared', False))
shared=ep.get('shared', False),
status=ep.get('status'),
status_details=ep.get('status_details'))
context.session.add(ep_db)
if 'external_segments' in ep:
self._set_ess_for_ep(context, ep_db,
@ -1751,7 +1717,9 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
name=es['name'], description=es['description'],
shared=es.get('shared', False), ip_version=es['ip_version'],
cidr=es['cidr'],
port_address_translation=es['port_address_translation'])
port_address_translation=es['port_address_translation'],
status=es.get('status'),
status_details=es.get('status_details'))
context.session.add(es_db)
if 'external_routes' in es:
self._process_segment_ers(context, es_db, es)
@ -1811,7 +1779,9 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
name=np['name'], description=np['description'],
shared=np.get('shared', False), ip_version=np['ip_version'],
ip_pool=np['ip_pool'],
external_segment_id=np['external_segment_id'])
external_segment_id=np['external_segment_id'],
status=np.get('status'),
status_details=np.get('status_details'))
context.session.add(np_db)
return self._make_nat_pool_dict(np_db)

View File

@ -331,6 +331,24 @@ class GroupPolicyMappingDbPlugin(gpdb.GroupPolicyDbPlugin):
ptg_db.update(ptg)
return self._make_policy_target_group_dict(ptg_db)
@log.log_method_call
def get_policy_target_groups_count(self, context, filters=None):
return self._get_collection_count(context, PolicyTargetGroupMapping,
filters=filters)
@log.log_method_call
def get_policy_target_groups(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
marker_obj = self._get_marker_obj(context, 'policy_target_group',
limit, marker)
return self._get_collection(context, PolicyTargetGroupMapping,
self._make_policy_target_group_dict,
filters=filters, fields=fields,
sorts=sorts, limit=limit,
marker_obj=marker_obj,
page_reverse=page_reverse)
@log.log_method_call
def create_l2_policy(self, context, l2_policy):
l2p = l2_policy['l2_policy']

View File

@ -0,0 +1,46 @@
# 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.
"""add status attributes
Revision ID: 12c1bc8d7026
Revises: 31b399f08b1c
Create Date: 2016-03-08 15:28:57.170563
"""
# revision identifiers, used by Alembic.
revision = '12c1bc8d7026'
down_revision = '31b399f08b1c'
from alembic import op
import sqlalchemy as sa
def upgrade():
table_names = ['gp_policy_targets', 'gp_policy_target_groups',
'gp_l2_policies', 'gp_l3_policies', 'gp_policy_rules',
'gp_policy_classifiers', 'gp_policy_actions',
'gp_policy_rule_sets', 'gp_nat_pools',
'gp_network_service_policies',
'gp_external_segments', 'gp_external_policies', 'sc_nodes',
'sc_instances', 'sc_specs', 'service_profiles']
for tname in table_names:
op.add_column(tname, sa.Column('status', sa.String(length=16),
nullable=True))
op.add_column(tname, sa.Column('status_details',
sa.String(length=4096), nullable=True))
def downgrade():
pass

View File

@ -1 +1 @@
31b399f08b1c
12c1bc8d7026

View File

@ -36,6 +36,17 @@ MAX_IPV4_SUBNET_PREFIX_LENGTH = 31
MAX_IPV6_SUBNET_PREFIX_LENGTH = 127
class BaseSCResource(models_v2.HasId, models_v2.HasTenant):
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
status = sa.Column(sa.String(length=16), nullable=True)
status_details = sa.Column(sa.String(length=4096), nullable=True)
class BaseSharedSCResource(BaseSCResource):
shared = sa.Column(sa.Boolean)
class SpecNodeAssociation(model_base.BASEV2):
"""Models one to many providing relation between Specs and Nodes."""
__tablename__ = 'sc_spec_node_associations'
@ -58,29 +69,22 @@ class InstanceSpecAssociation(model_base.BASEV2):
position = sa.Column(sa.Integer)
class ServiceChainNode(model_base.BASEV2, models_v2.HasId,
models_v2.HasTenant):
class ServiceChainNode(model_base.BASEV2, BaseSharedSCResource):
"""ServiceChain Node"""
__tablename__ = 'sc_nodes'
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
config = sa.Column(sa.TEXT)
specs = orm.relationship(SpecNodeAssociation,
backref="nodes",
cascade='all, delete, delete-orphan')
shared = sa.Column(sa.Boolean)
service_type = sa.Column(sa.String(50), nullable=True)
service_profile_id = sa.Column(
sa.String(36), sa.ForeignKey('service_profiles.id'),
nullable=True)
class ServiceChainInstance(model_base.BASEV2,
models_v2.HasId, models_v2.HasTenant):
class ServiceChainInstance(model_base.BASEV2, BaseSCResource):
"""Service chain instances"""
__tablename__ = 'sc_instances'
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
config_param_values = sa.Column(sa.String(4096))
specs = orm.relationship(
InstanceSpecAssociation,
@ -103,13 +107,10 @@ class ServiceChainInstance(model_base.BASEV2,
nullable=True)
class ServiceChainSpec(model_base.BASEV2, models_v2.HasId,
models_v2.HasTenant):
class ServiceChainSpec(model_base.BASEV2, BaseSharedSCResource):
""" ServiceChain Spec
"""
__tablename__ = 'sc_specs'
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
nodes = orm.relationship(
SpecNodeAssociation,
backref='specs', cascade='all, delete, delete-orphan',
@ -119,18 +120,13 @@ class ServiceChainSpec(model_base.BASEV2, models_v2.HasId,
instances = orm.relationship(InstanceSpecAssociation,
backref="specs",
cascade='all, delete, delete-orphan')
shared = sa.Column(sa.Boolean)
class ServiceProfile(model_base.BASEV2, models_v2.HasId,
models_v2.HasTenant):
class ServiceProfile(model_base.BASEV2, BaseSharedSCResource):
""" Service Profile
"""
__tablename__ = 'service_profiles'
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
vendor = sa.Column(sa.String(50))
shared = sa.Column(sa.Boolean)
# Not using ENUM for less painful upgrades. Validation will happen at the
# API level
insertion_mode = sa.Column(sa.String(50))
@ -188,26 +184,28 @@ class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
raise schain.ServiceProfileNotFound(
profile_id=profile_id)
def _populate_common_fields_in_dict(self, db_ref):
res = {'id': db_ref['id'],
'tenant_id': db_ref['tenant_id'],
'name': db_ref['name'],
'description': db_ref['description'],
'status': db_ref['status'],
'status_details': db_ref['status_details'],
'shared': db_ref.get('shared', False)}
return res
def _make_sc_node_dict(self, sc_node, fields=None):
res = {'id': sc_node['id'],
'tenant_id': sc_node['tenant_id'],
'name': sc_node['name'],
'description': sc_node['description'],
'service_profile_id': sc_node['service_profile_id'],
'service_type': sc_node['service_type'],
'config': sc_node['config'],
'shared': sc_node['shared']}
res = self._populate_common_fields_in_dict(sc_node)
res['service_profile_id'] = sc_node['service_profile_id']
res['service_type'] = sc_node['service_type']
res['config'] = sc_node['config']
res['servicechain_specs'] = [sc_spec['servicechain_spec_id']
for sc_spec in sc_node['specs']]
return self._fields(res, fields)
def _make_sc_spec_dict(self, spec, fields=None):
res = {'id': spec['id'],
'tenant_id': spec['tenant_id'],
'name': spec['name'],
'description': spec['description'],
'config_param_names': spec.get('config_param_names'),
'shared': spec['shared']}
res = self._populate_common_fields_in_dict(spec)
res['config_param_names'] = spec.get('config_param_names')
res['nodes'] = [sc_node['node_id'] for sc_node in spec['nodes']]
res['instances'] = [x['servicechain_instance_id'] for x in
spec['instances']]
@ -222,21 +220,19 @@ class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
'provider_ptg_id': instance['provider_ptg_id'],
'consumer_ptg_id': instance['consumer_ptg_id'],
'management_ptg_id': instance['management_ptg_id'],
'classifier_id': instance['classifier_id']}
'classifier_id': instance['classifier_id'],
'status': instance['status'],
'status_details': instance['status_details']}
res['servicechain_specs'] = [sc_spec['servicechain_spec_id']
for sc_spec in instance['specs']]
return self._fields(res, fields)
def _make_service_profile_dict(self, profile, fields=None):
res = {'id': profile['id'],
'tenant_id': profile['tenant_id'],
'name': profile['name'],
'description': profile['description'],
'shared': profile['shared'],
'service_type': profile['service_type'],
'service_flavor': profile['service_flavor'],
'vendor': profile['vendor'],
'insertion_mode': profile['insertion_mode']}
res = self._populate_common_fields_in_dict(profile)
res['service_type'] = profile['service_type']
res['service_flavor'] = profile['service_flavor']
res['vendor'] = profile['vendor']
res['insertion_mode'] = profile['insertion_mode']
res['nodes'] = [node['id'] for node in profile['nodes']]
return self._fields(res, fields)
@ -253,9 +249,11 @@ class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
node_db = ServiceChainNode(
id=uuidutils.generate_uuid(), tenant_id=tenant_id,
name=node['name'], description=node['description'],
service_profile_id=node['service_profile_id'],
service_type=node['service_type'],
config=node['config'], shared=node['shared'])
service_profile_id=node.get('service_profile_id'),
service_type=node.get('service_type'),
config=node['config'], shared=node['shared'],
status=node.get('status'),
status_details=node.get('status_details'))
context.session.add(node_db)
return self._make_sc_node_dict(node_db)
@ -419,7 +417,10 @@ class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
tenant_id=tenant_id,
name=spec['name'],
description=spec['description'],
shared=spec['shared'])
shared=spec['shared'],
status=spec.get('status'),
status_details=
spec.get('status_details'))
self._process_nodes_for_spec(context, spec_db, spec,
set_params=set_params)
context.session.add(spec_db)
@ -479,11 +480,11 @@ class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
instance = servicechain_instance['servicechain_instance']
tenant_id = self._get_tenant_id_for_create(context, instance)
with context.session.begin(subtransactions=True):
if not instance['management_ptg_id']:
if not instance.get('management_ptg_id'):
management_groups = (
self._grouppolicy_plugin.get_policy_target_groups(
context, {'service_management': [True],
'tenant_id': [instance['tenant_id']]}))
'tenant_id': [instance.get('tenant_id')]}))
if not management_groups:
# Fall back on shared service management
management_groups = (
@ -496,10 +497,12 @@ class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
tenant_id=tenant_id, name=instance['name'],
description=instance['description'],
config_param_values=instance['config_param_values'],
provider_ptg_id=instance['provider_ptg_id'],
consumer_ptg_id=instance['consumer_ptg_id'],
management_ptg_id=instance['management_ptg_id'],
classifier_id=instance['classifier_id'])
provider_ptg_id=instance.get('provider_ptg_id'),
consumer_ptg_id=instance.get('consumer_ptg_id'),
management_ptg_id=instance.get('management_ptg_id'),
classifier_id=instance.get('classifier_id'),
status=instance.get('status'),
status_details=instance.get('status_details'))
self._process_specs_for_instance(context, instance_db, instance)
context.session.add(instance_db)
return self._make_sc_instance_dict(instance_db)
@ -559,11 +562,13 @@ class ServiceChainDbPlugin(schain.ServiceChainPluginBase,
profile_db = ServiceProfile(
id=uuidutils.generate_uuid(), tenant_id=tenant_id,
name=profile['name'], description=profile['description'],
service_type=profile['service_type'],
insertion_mode=profile['insertion_mode'],
vendor=profile['vendor'],
service_flavor=profile['service_flavor'],
shared=profile['shared'])
service_type=profile.get('service_type'),
insertion_mode=profile.get('insertion_mode'),
vendor=profile.get('vendor'),
service_flavor=profile.get('service_flavor'),
shared=profile.get('shared'),
status=profile.get('status'),
status_details=profile.get('status_details'))
context.session.add(profile_db)
return self._make_service_profile_dict(profile_db)

View File

@ -407,6 +407,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'policy_target_group_id': {'allow_post': True, 'allow_put': True,
'validate': {'type:uuid_or_none': None},
'required': True, 'is_visible': True},
@ -427,6 +431,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'policy_targets': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid_list': None},
'convert_to': attr.convert_none_to_empty_list,
@ -470,6 +478,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'policy_target_groups': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid_list': None},
'convert_to': attr.convert_none_to_empty_list,
@ -505,6 +517,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'ip_version': {'allow_post': True, 'allow_put': False,
'convert_to': attr.convert_to_int,
'validate': {'type:values': [4, 6]},
@ -544,6 +560,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'validate': {'type:string': None},
'required_by_policy': True,
'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'protocol': {'allow_post': True, 'allow_put': True,
'is_visible': True, 'default': None,
'convert_to': convert_protocol},
@ -575,6 +595,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'validate': {'type:string': None},
'required_by_policy': True,
'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'action_type': {'allow_post': True, 'allow_put': False,
'convert_to': convert_action_to_case_insensitive,
'validate': {'type:values': gp_supported_actions},
@ -600,6 +624,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'enabled': {'allow_post': True, 'allow_put': True,
'default': True, 'convert_to': attr.convert_to_boolean,
'is_visible': True},
@ -631,6 +659,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'validate': {'type:string': None},
'required_by_policy': True,
'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'parent_id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True},
@ -661,6 +693,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'policy_target_groups': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid_list': None},
'convert_to': attr.convert_none_to_empty_list,
@ -687,6 +723,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'external_segments': {
'allow_post': True, 'allow_put': True, 'default': None,
'validate': {'type:uuid_list': None},
@ -719,6 +759,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'ip_version': {'allow_post': True, 'allow_put': False,
'convert_to': attr.convert_to_int,
'validate': {'type:values': [4, 6]},
@ -767,6 +811,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'ip_version': {'allow_post': True, 'allow_put': False,
'convert_to': attr.convert_to_int,
'validate': {'type:values': [4, 6]},

View File

@ -117,6 +117,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'service_type': {'allow_post': True, 'allow_put': False,
'validate': {'type:string_or_none': None},
'is_visible': True, 'default': None},
@ -144,6 +148,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'nodes': {'allow_post': True, 'allow_put': True,
'validate': {'type:uuid_list': None},
'convert_to': attr.convert_none_to_empty_list,
@ -170,6 +178,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'servicechain_specs': {'allow_post': True, 'allow_put': True,
'validate': {'type:uuid_list': None},
'convert_to': attr.convert_none_to_empty_list,
@ -208,6 +220,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'status_details': {'allow_post': False, 'allow_put': False,
'is_visible': True},
attr.SHARED: {'allow_post': True, 'allow_put': True,
'default': False, 'convert_to': attr.convert_to_boolean,
'is_visible': True, 'required_by_policy': True,

View File

@ -38,3 +38,9 @@ GP_NETWORK_SVC_PARAM_TYPE_STRING = 'string'
GP_NETWORK_SVC_PARAM_VALUE_SELF_SUBNET = 'self_subnet'
GP_NETWORK_SVC_PARAM_VALUE_NAT_POOL = 'nat_pool'
STATUS_ACTIVE = 'ACTIVE'
STATUS_BUILD = 'BUILD'
STATUS_ERROR = 'ERROR'
STATUS_STATES = [STATUS_ACTIVE, STATUS_BUILD, STATUS_ERROR]

View File

@ -21,21 +21,6 @@ class GroupPolicyContext(object):
self._plugin_context = plugin_context
class BaseResouceContext(GroupPolicyContext):
def __init__(self, plugin, plugin_context, resource, original=None):
super(BaseResouceContext, self).__init__(plugin, plugin_context)
self._resource = resource
self._original = original
@property
def current(self):
return self._resource
@property
def original(self):
return self._original
class PolicyTargetContext(GroupPolicyContext, api.PolicyTargetContext):
def __init__(self, plugin, plugin_context, policy_target,
@ -259,7 +244,21 @@ class PolicyRuleSetContext(GroupPolicyContext, api.PolicyRuleSetContext):
return self._original_policy_rule_set
class ExternalSegmentContext(BaseResouceContext, api.ExternalSegmentContext):
class ExternalSegmentContext(GroupPolicyContext, api.ExternalSegmentContext):
def __init__(self, plugin, plugin_context, external_segment,
original_external_segment=None):
super(ExternalSegmentContext, self).__init__(plugin, plugin_context)
self._external_segment = external_segment
self._original_external_segment = original_external_segment
@property
def current(self):
return self._external_segment
@property
def original(self):
return self._original_external_segment
def add_subnet(self, subnet_id):
self._plugin._set_subnet_to_es(self._plugin_context,
@ -267,7 +266,21 @@ class ExternalSegmentContext(BaseResouceContext, api.ExternalSegmentContext):
self.current['subnet_id'] = subnet_id
class ExternalPolicyContext(BaseResouceContext, api.ExternalPolicyContext):
class ExternalPolicyContext(GroupPolicyContext, api.ExternalPolicyContext):
def __init__(self, plugin, plugin_context, external_policy,
original_external_policy=None):
super(ExternalPolicyContext, self).__init__(plugin, plugin_context)
self._external_policy = external_policy
self._original_external_policy = original_external_policy
@property
def current(self):
return self._external_policy
@property
def original(self):
return self._original_external_policy
def set_external_segment(self, external_segment_id):
external_segmets = [external_segment_id]
@ -277,5 +290,18 @@ class ExternalPolicyContext(BaseResouceContext, api.ExternalPolicyContext):
{'external_policy': {'external_segments': external_segmets}})
class NatPoolContext(BaseResouceContext, api.NatPoolContext):
pass
class NatPoolContext(GroupPolicyContext, api.NatPoolContext):
def __init__(self, plugin, plugin_context, nat_pool,
original_nat_pool=None):
super(NatPoolContext, self).__init__(plugin, plugin_context)
self._nat_pool = nat_pool
self._original_nat_pool = original_nat_pool
@property
def current(self):
return self._nat_pool
@property
def original(self):
return self._original_nat_pool

View File

@ -578,6 +578,16 @@ class PolicyDriver(object):
"""
pass
def get_policy_target_status(self, context):
"""Get most recent status of a policy_target.
:param context: PolicyTargetContext instance describing the current
state of the policy_target, prior to the call to this get. Driver
can update the status and status_details. This status change will be
reflected as the new status and status_details of the resource.
"""
pass
def create_policy_target_group_precommit(self, context):
"""Allocate resources for a new policy_target_group.
@ -630,6 +640,17 @@ class PolicyDriver(object):
"""
pass
def get_policy_target_group_status(self, context):
"""Get most recent status of a policy_target_group.
:param context: PolicyTargetGroupContext instance describing the
current state of the policy_target_group, prior to the call to this
get.
Driver can update the status and status_details. This status change
will be reflected as the new status and status_details of the resource.
"""
pass
def create_l2_policy_precommit(self, context):
"""Allocate resources for a new l2_policy.
@ -680,6 +701,16 @@ class PolicyDriver(object):
"""
pass
def get_l2_policy_status(self, context):
"""Get most recent status of a l2_policy.
:param context: L2PolicyContext instance describing the current
state of the l2_policy, prior to the call to this get.
Driver can update the status and status_details. This status change
will be reflected as the new status and status_details of the resource.
"""
pass
def create_l3_policy_precommit(self, context):
"""Allocate resources for a new l3_policy.
@ -730,6 +761,16 @@ class PolicyDriver(object):
"""
pass
def get_l3_policy_status(self, context):
"""Get most recent status of a l3_policy.
:param context: L3PolicyContext instance describing the current
state of the l3_policy, prior to the call to this get.
Driver can update the status and status_details. This status change
will be reflected as the new status and status_details of the resource.
"""
pass
def create_policy_classifier_precommit(self, context):
"""Allocate resources for a new policy_classifier.
@ -780,6 +821,16 @@ class PolicyDriver(object):
"""
pass
def get_policy_classifier_status(self, context):
"""Get most recent status of a policy_classifier.
:param context: PolicyClassifierContext instance describing the current
state of the policy_classifier, prior to the call to this get.
Driver can update the status and status_details. This status change
will be reflected as the new status and status_details of the resource.
"""
pass
def create_policy_action_precommit(self, context):
"""Allocate resources for a new policy_action.
@ -830,6 +881,16 @@ class PolicyDriver(object):
"""
pass
def get_policy_action_status(self, context):
"""Get most recent status of a policy_action.
:param context: PolicyActionContext instance describing the current
state of the policy_action, prior to the call to this get.
Driver can update the status and status_details. This status change
will be reflected as the new status and status_details of the resource.
"""
pass
def create_policy_rule_precommit(self, context):
"""Allocate resources for a new policy_rule.
@ -880,6 +941,16 @@ class PolicyDriver(object):
"""
pass
def get_policy_rule_status(self, context):
"""Get most recent status of a policy_rule.
:param context: PolicyRuleContext instance describing the current
state of the policy_rule, prior to the call to this get.
Driver can update the status and status_details. This status change
will be reflected as the new status and status_details of the resource.
"""
pass
def create_policy_rule_set_precommit(self, context):
"""Allocate resources for a new policy_rule_set.
@ -930,6 +1001,16 @@ class PolicyDriver(object):
"""
pass
def get_policy_rule_set_status(self, context):
"""Get most recent status of a policy_rule_set.
:param context: PolicyRuleSetContext instance describing the current
state of the policy_rule_set, prior to the call to this get.
Driver can update the status and status_details. This status change
will be reflected as the new status and status_details of the resource.
"""
pass
def create_network_service_policy_precommit(self, context):
"""Allocate resources for a new network service policy.
@ -982,6 +1063,17 @@ class PolicyDriver(object):
"""
pass
def get_network_service_policy_status(self, context):
"""Get most recent status of a network_service_policy.
:param context: NetworkServicePolicyContext instance describing the
current state of the network_service_policy, prior to the call to this
get.
Driver can update the status and status_details. This status change
will be reflected as the new status and status_details of the resource.
"""
pass
def create_external_segment_precommit(self, context):
"""Allocate resources for a new network service policy.
@ -1034,6 +1126,16 @@ class PolicyDriver(object):
"""
pass
def get_external_segment_status(self, context):
"""Get most recent status of a external_segment.
:param context: ExternalSegmentContext instance describing the
current state of the external_segment, prior to the call to this get.
Driver can update the status and status_details. This status change
will be reflected as the new status and status_details of the resource.
"""
pass
def create_external_policy_precommit(self, context):
"""Allocate resources for a new network service policy.
@ -1086,6 +1188,16 @@ class PolicyDriver(object):
"""
pass
def get_external_policy_status(self, context):
"""Get most recent status of a external_policy.
:param context: ExternalPolicyContext instance describing the
current state of the external_policy, prior to the call to this get.
Driver can update the status and status_details. This status change
will be reflected as the new status and status_details of the resource.
"""
pass
def create_nat_pool_precommit(self, context):
"""Allocate resources for a new network service policy.
@ -1138,6 +1250,16 @@ class PolicyDriver(object):
"""
pass
def get_nat_pool_status(self, context):
"""Get most recent status of a nat_pool.
:param context: NatPoolContext instance describing the
current state of the nat_pool, prior to the call to this get.
Driver can update the status and status_details. This status change
will be reflected as the new status and status_details of the resource.
"""
pass
@six.add_metaclass(abc.ABCMeta)
class ExtensionDriver(object):

View File

@ -24,6 +24,7 @@ from oslo_log import helpers as log
from oslo_log import log as logging
from oslo_utils import excutils
from gbpservice.common import utils as gbp_utils
from gbpservice.neutron.db.grouppolicy import group_policy_db as gpdb
from gbpservice.neutron.db.grouppolicy import group_policy_mapping_db
from gbpservice.neutron.extensions import group_policy as gpex
@ -40,6 +41,9 @@ from gbpservice.neutron.services.servicechain.plugins.ncp import (
LOG = logging.getLogger(__name__)
STATUS = 'status'
STATUS_DETAILS = 'status_details'
STATUS_SET = set([STATUS, STATUS_DETAILS])
class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
@ -337,6 +341,80 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
res_type=primary_type, res_id=primary['id'],
ref_type=reference_type, ref_id=reference['id'])
def _get_status_from_drivers(self, context, context_name, resource_name,
resource_id, resource):
result = resource
status = resource['status']
status_details = resource['status_details']
policy_context = getattr(p_context, context_name)(
self, context, resource, resource)
getattr(self.policy_driver_manager,
"get_" + resource_name + "_status")(policy_context)
_resource = getattr(policy_context, "_" + resource_name)
updated_status = _resource['status']
updated_status_details = _resource['status_details']
if status != updated_status or (
status_details != updated_status_details):
new_status = {resource_name: {'status': updated_status,
'status_details':
updated_status_details}}
session = context.session
with session.begin(subtransactions=True):
result = getattr(super(GroupPolicyPlugin, self),
"update_" + resource_name)(
context, _resource['id'], new_status)
return result
def _get_resource(self, context, resource_name, resource_id,
gbp_context_name, fields=None):
session = context.session
with session.begin(subtransactions=True):
get_method = "".join(['get_', resource_name])
result = getattr(super(GroupPolicyPlugin, self), get_method)(
context, resource_id, None)
extend_resources_method = "".join(['extend_', resource_name,
'_dict'])
getattr(self.extension_manager, extend_resources_method)(
session, result)
# Invoke drivers only if status attributes are requested
if not fields or STATUS_SET.intersection(set(fields)):
result = self._get_status_from_drivers(
context, gbp_context_name, resource_name, resource_id, result)
return self._fields(result, fields)
def _get_resources(self, context, resource_name, gbp_context_name,
filters=None, fields=None, sorts=None, limit=None,
marker=None, page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
resource_plural = gbp_utils.get_resource_plural(resource_name)
get_resources_method = "".join(['get_', resource_plural])
results = getattr(super(GroupPolicyPlugin, self),
get_resources_method)(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
extend_resources_method = "".join(['extend_', resource_name,
'_dict'])
getattr(self.extension_manager, extend_resources_method)(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
new_filtered_results = []
# Invoke drivers only if status attributes are requested
if not fields or STATUS_SET.intersection(set(fields)):
for result in filtered_results:
result = self._get_status_from_drivers(
context, gbp_context_name, resource_name, result['id'],
result)
new_filtered_results.append(result)
new_filtered_results = new_filtered_results or filtered_results
return [self._fields(result, fields) for result in
new_filtered_results]
@resource_registry.tracked_resources(
l3_policy=group_policy_mapping_db.L3PolicyMapping,
l2_policy=group_policy_mapping_db.L2PolicyMapping,
@ -451,29 +529,19 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
"for policy_target %s"),
policy_target_id)
@log.log_method_call
def get_policy_target(self, context, policy_target_id, fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_policy_target(
context, policy_target_id, None)
self.extension_manager.extend_policy_target_dict(session, result)
return self._fields(result, fields)
return self._get_resource(context, 'policy_target', policy_target_id,
'PolicyTargetContext', fields=fields)
@log.log_method_call
def get_policy_targets(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin, self).get_policy_targets(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_policy_target_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in filtered_results]
return self._get_resources(
context, 'policy_target', 'PolicyTargetContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_policy_target_group(self, context, policy_target_group):
@ -597,31 +665,21 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
"for policy_target_group %s"),
policy_target_group_id)
@log.log_method_call
def get_policy_target_group(self, context, policy_target_group_id,
fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_policy_target_group(
context, policy_target_group_id, None)
self.extension_manager.extend_policy_target_group_dict(session,
result)
return self._fields(result, fields)
return self._get_resource(context, 'policy_target_group',
policy_target_group_id,
'PolicyTargetGroupContext', fields=fields)
@log.log_method_call
def get_policy_target_groups(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin, self).get_policy_target_groups(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_policy_target_group_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in results]
return self._get_resources(
context, 'policy_target_group', 'PolicyTargetGroupContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_l2_policy(self, context, l2_policy):
@ -689,29 +747,20 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
LOG.exception(_LE("delete_l2_policy_postcommit failed "
"for l2_policy %s"), l2_policy_id)
@log.log_method_call
def get_l2_policy(self, context, l2_policy_id, fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_l2_policy(
context, l2_policy_id, None)
self.extension_manager.extend_l2_policy_dict(session, result)
return self._fields(result, fields)
return self._get_resource(context, 'l2_policy',
l2_policy_id,
'L2PolicyContext', fields=fields)
@log.log_method_call
def get_l2_policies(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin, self).get_l2_policies(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_l2_policy_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in results]
return self._get_resources(
context, 'l2_policy', 'L2PolicyContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_network_service_policy(self, context, network_service_policy):
@ -793,32 +842,21 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
"delete_network_service_policy_postcommit failed "
"for network_service_policy %s"), network_service_policy_id)
@log.log_method_call
def get_network_service_policy(self, context, network_service_policy_id,
fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_network_service_policy(
context, network_service_policy_id, None)
self.extension_manager.extend_network_service_policy_dict(session,
result)
return self._fields(result, fields)
return self._get_resource(context, 'network_service_policy',
network_service_policy_id,
'NetworkServicePolicyContext', fields=fields)
@log.log_method_call
def get_network_service_policies(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin,
self).get_network_service_policies(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_network_service_policy_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in results]
return self._get_resources(
context, 'network_service_policy', 'NetworkServicePolicyContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_l3_policy(self, context, l3_policy):
@ -895,29 +933,20 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
"for l3_policy %s"), l3_policy_id)
return True
@log.log_method_call
def get_l3_policy(self, context, l3_policy_id, fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_l3_policy(
context, l3_policy_id, None)
self.extension_manager.extend_l3_policy_dict(session, result)
return self._fields(result, fields)
return self._get_resource(context, 'l3_policy',
l3_policy_id,
'L3PolicyContext', fields=fields)
@log.log_method_call
def get_l3_policies(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin, self).get_l3_policies(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_l3_policy_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in results]
return self._get_resources(
context, 'l3_policy', 'L3PolicyContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_policy_classifier(self, context, policy_classifier):
@ -990,31 +1019,21 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
LOG.exception(_LE("delete_policy_classifier_postcommit failed "
"for policy_classifier %s"), id)
@log.log_method_call
def get_policy_classifier(self, context, policy_classifier_id,
fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_policy_classifier(
context, policy_classifier_id, None)
self.extension_manager.extend_policy_classifier_dict(session,
result)
return self._fields(result, fields)
return self._get_resource(context, 'policy_classifier',
policy_classifier_id,
'PolicyClassifierContext', fields=fields)
@log.log_method_call
def get_policy_classifiers(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin, self).get_policy_classifiers(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_policy_classifier_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in results]
return self._get_resources(
context, 'policy_classifier', 'PolicyClassifierContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_policy_action(self, context, policy_action):
@ -1087,29 +1106,20 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
LOG.exception(_LE("delete_policy_action_postcommit failed "
"for policy_action %s"), id)
@log.log_method_call
def get_policy_action(self, context, policy_action_id, fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_policy_action(
context, policy_action_id, None)
self.extension_manager.extend_policy_action_dict(session, result)
return self._fields(result, fields)
return self._get_resource(context, 'policy_action',
policy_action_id,
'PolicyActionContext', fields=fields)
@log.log_method_call
def get_policy_actions(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin, self).get_policy_actions(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_policy_action_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in results]
return self._get_resources(
context, 'policy_action', 'PolicyActionContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_policy_rule(self, context, policy_rule):
@ -1180,29 +1190,20 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
LOG.exception(_LE("delete_policy_rule_postcommit failed "
"for policy_rule %s"), id)
@log.log_method_call
def get_policy_rule(self, context, policy_rule_id, fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_policy_rule(
context, policy_rule_id, None)
self.extension_manager.extend_policy_rule_dict(session, result)
return self._fields(result, fields)
return self._get_resource(context, 'policy_rule',
policy_rule_id,
'PolicyRuleContext', fields=fields)
@log.log_method_call
def get_policy_rules(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin, self).get_policy_rules(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_policy_rule_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in results]
return self._get_resources(
context, 'policy_rule', 'PolicyRuleContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_policy_rule_set(self, context, policy_rule_set):
@ -1274,29 +1275,20 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
LOG.exception(_LE("delete_policy_rule_set_postcommit failed "
"for policy_rule_set %s"), id)
@log.log_method_call
def get_policy_rule_set(self, context, policy_rule_set_id, fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_policy_rule_set(
context, policy_rule_set_id, None)
self.extension_manager.extend_policy_rule_set_dict(session, result)
return self._fields(result, fields)
return self._get_resource(context, 'policy_rule_set',
policy_rule_set_id,
'PolicyRuleSetContext', fields=fields)
@log.log_method_call
def get_policy_rule_sets(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin, self).get_policy_rule_sets(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_policy_rule_set_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in results]
return self._get_resources(
context, 'policy_rule_set', 'PolicyRuleSetContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_external_segment(self, context, external_segment):
@ -1382,30 +1374,20 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
external_segment_id)
return True
@log.log_method_call
def get_external_segment(self, context, external_segment_id, fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_external_segment(
context, external_segment_id, None)
self.extension_manager.extend_external_segment_dict(session,
result)
return self._fields(result, fields)
return self._get_resource(context, 'external_segment',
external_segment_id,
'ExternalSegmentContext', fields=fields)
@log.log_method_call
def get_external_segments(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin, self).get_external_segments(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_external_segment_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in results]
return self._get_resources(
context, 'external_segment', 'ExternalSegmentContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_external_policy(self, context, external_policy):
@ -1482,30 +1464,20 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
LOG.exception(_LE("delete_external_policy_postcommit failed "
"for external_policy %s"), external_policy_id)
@log.log_method_call
def get_external_policy(self, context, external_policy_id, fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_external_policy(
context, external_policy_id, None)
self.extension_manager.extend_external_policy_dict(session,
result)
return self._fields(result, fields)
return self._get_resource(context, 'external_policy',
external_policy_id,
'ExternalPolicyContext', fields=fields)
@log.log_method_call
def get_external_policies(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin, self).get_external_policies(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_external_policy_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in results]
return self._get_resources(
context, 'external_policy', 'ExternalPolicyContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_nat_pool(self, context, nat_pool):
@ -1572,29 +1544,20 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
"for nat_pool %s"),
nat_pool_id)
@log.log_method_call
def get_nat_pool(self, context, nat_pool_id, fields=None):
session = context.session
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin, self).get_nat_pool(
context, nat_pool_id, None)
self.extension_manager.extend_nat_pool_dict(session, result)
return self._fields(result, fields)
return self._get_resource(context, 'nat_pool',
nat_pool_id,
'NatPoolContext', fields=fields)
@log.log_method_call
def get_nat_pools(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
session = context.session
with session.begin(subtransactions=True):
results = super(GroupPolicyPlugin, self).get_nat_pools(
context, filters, None, sorts, limit, marker, page_reverse)
filtered_results = []
for result in results:
self.extension_manager.extend_nat_pool_dict(
session, result)
filtered = self._filter_extended_result(result, filters)
if filtered:
filtered_results.append(filtered)
return [self._fields(result, fields) for result in results]
return self._get_resources(
context, 'nat_pool', 'NatPoolContext',
filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse)
def _is_port_bound(self, port_id):
# REVISIT(ivar): This operation shouldn't be done within a DB lock

View File

@ -154,6 +154,9 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
self._call_on_drivers("delete_policy_target_postcommit", context,
continue_on_failure=True)
def get_policy_target_status(self, context):
self._call_on_drivers("get_policy_target_status", context)
def create_policy_target_group_precommit(self, context):
self._call_on_drivers("create_policy_target_group_precommit", context)
@ -173,6 +176,9 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
self._call_on_drivers("delete_policy_target_group_postcommit", context,
continue_on_failure=True)
def get_policy_target_group_status(self, context):
self._call_on_drivers("get_policy_target_group_status", context)
def create_l2_policy_precommit(self, context):
self._call_on_drivers("create_l2_policy_precommit", context)
@ -192,6 +198,9 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
self._call_on_drivers("delete_l2_policy_postcommit", context,
continue_on_failure=True)
def get_l2_policy_status(self, context):
self._call_on_drivers("get_l2_policy_status", context)
def create_l3_policy_precommit(self, context):
self._call_on_drivers("create_l3_policy_precommit", context)
@ -211,6 +220,9 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
self._call_on_drivers("delete_l3_policy_postcommit", context,
continue_on_failure=True)
def get_l3_policy_status(self, context):
self._call_on_drivers("get_l3_policy_status", context)
def create_network_service_policy_precommit(self, context):
self._call_on_drivers(
"create_network_service_policy_precommit", context)
@ -236,6 +248,9 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
"delete_network_service_policy_postcommit", context,
continue_on_failure=True)
def get_network_service_policy_status(self, context):
self._call_on_drivers("get_network_service_policy_status", context)
def create_policy_classifier_precommit(self, context):
self._call_on_drivers("create_policy_classifier_precommit", context)
@ -255,6 +270,9 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
self._call_on_drivers("delete_policy_classifier_postcommit", context,
continue_on_failure=True)
def get_policy_classifier_status(self, context):
self._call_on_drivers("get_policy_classifier_status", context)
def create_policy_action_precommit(self, context):
self._call_on_drivers("create_policy_action_precommit", context)
@ -274,6 +292,9 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
self._call_on_drivers("delete_policy_action_postcommit", context,
continue_on_failure=True)
def get_policy_action_status(self, context):
self._call_on_drivers("get_policy_action_status", context)
def create_policy_rule_precommit(self, context):
self._call_on_drivers("create_policy_rule_precommit", context)
@ -293,6 +314,9 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
self._call_on_drivers("delete_policy_rule_postcommit", context,
continue_on_failure=True)
def get_policy_rule_status(self, context):
self._call_on_drivers("get_policy_rule_status", context)
def create_policy_rule_set_precommit(self, context):
self._call_on_drivers("create_policy_rule_set_precommit", context)
@ -312,6 +336,9 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
self._call_on_drivers("delete_policy_rule_set_postcommit", context,
continue_on_failure=True)
def get_policy_rule_set_status(self, context):
self._call_on_drivers("get_policy_rule_set_status", context)
def create_external_segment_precommit(self, context):
self._call_on_drivers("create_external_segment_precommit",
context)
@ -336,6 +363,9 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
self._call_on_drivers("delete_external_segment_postcommit",
context, continue_on_failure=True)
def get_external_segment_status(self, context):
self._call_on_drivers("get_external_segment_status", context)
def create_external_policy_precommit(self, context):
self._call_on_drivers("create_external_policy_precommit",
context)
@ -360,6 +390,9 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
self._call_on_drivers("delete_external_policy_postcommit",
context, continue_on_failure=True)
def get_external_policy_status(self, context):
self._call_on_drivers("get_external_policy_status", context)
def create_nat_pool_precommit(self, context):
self._call_on_drivers("create_nat_pool_precommit", context)
@ -378,3 +411,6 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
def delete_nat_pool_postcommit(self, context):
self._call_on_drivers("delete_nat_pool_postcommit", context,
continue_on_failure=True)
def get_nat_pool_status(self, context):
self._call_on_drivers("get_nat_pool_status", context)

View File

@ -93,7 +93,7 @@ class ApiManagerMixin(object):
res = req.get_response(self.ext_api)
if expected_res_status:
self.assertEqual(res.status_int, expected_res_status)
self.assertEqual(expected_res_status, res.status_int)
elif res.status_int >= webob.exc.HTTPClientError.code:
raise webob.exc.HTTPClientError(code=res.status_int)
@ -113,7 +113,7 @@ class ApiManagerMixin(object):
res = req.get_response(api or self.ext_api)
if expected_res_status:
self.assertEqual(res.status_int, expected_res_status)
self.assertEqual(expected_res_status, res.status_int)
elif res.status_int >= webob.exc.HTTPClientError.code:
raise webob.exc.HTTPClientError(code=res.status_int)
return self.deserialize(self.fmt, res)
@ -126,7 +126,7 @@ class ApiManagerMixin(object):
res = req.get_response(self.ext_api)
if expected_res_status:
self.assertEqual(res.status_int, expected_res_status)
self.assertEqual(expected_res_status, res.status_int)
elif res.status_int >= webob.exc.HTTPClientError.code:
raise webob.exc.HTTPClientError(code=res.status_int)
return self.deserialize(self.fmt, res)
@ -138,7 +138,7 @@ class ApiManagerMixin(object):
'', tenant_id or self._tenant_id, is_admin_context)
res = req.get_response(self.ext_api)
if expected_res_status:
self.assertEqual(res.status_int, expected_res_status)
self.assertEqual(expected_res_status, res.status_int)
elif res.status_int >= webob.exc.HTTPClientError.code:
raise webob.exc.HTTPClientError(code=res.status_int)
if res.status_int != 204:
@ -149,7 +149,7 @@ class ApiManagerMixin(object):
res = req.get_response(api)
if expected_res_status:
self.assertEqual(res.status_int, expected_res_status)
self.assertEqual(expected_res_status, res.status_int)
elif res.status_int >= webob.exc.HTTPClientError.code:
raise webob.exc.HTTPClientError(code=res.status_int)
return self.deserialize(self.fmt, res)
@ -256,6 +256,12 @@ class GroupPolicyDBTestBase(ApiManagerMixin):
return resource_plural
def _get_resource_singular(self, resource_plural):
if resource_plural.endswith('ies'):
return resource_plural.replace('ies', 'y')
else:
return resource_plural[:-1]
def _test_list_resources(self, resource, items,
neutron_context=None,
query_params=None):
@ -339,6 +345,7 @@ class GroupPolicyDbTestCase(GroupPolicyDBTestBase,
plugins = manager.NeutronManager.get_service_plugins()
self._gbp_plugin = plugins.get(constants.GROUP_POLICY)
self._sc_plugin = plugins.get(constants.SERVICECHAIN)
class TestGroupResources(GroupPolicyDbTestCase):
@ -1538,3 +1545,52 @@ class TestGroupResources(GroupPolicyDbTestCase):
expected_res_status=400)
self.assertEqual('IpAddressOverlappingInExternalSegment',
res['NeutronError']['type'])
class TestStatusAttributesForResources(GroupPolicyDbTestCase):
def _test_set_status_attrs(self, resource_name, plugin_ref):
all_statuses = []
status_details = 'something'
none_status_dict = {resource_name: {'status': None,
'status_details': None}}
for status in gp_constants.STATUS_STATES:
status_dict = {'status': status,
'status_details': status_details}
all_statuses.append(status_dict)
operation_name = ''.join(['get_create_', resource_name,
'_default_attrs'])
attrs = {resource_name: cm.__getattribute__(operation_name)()}
if resource_name == 'policy_rule':
pc_id = self.create_policy_classifier()['policy_classifier']['id']
attrs[resource_name]['policy_classifier_id'] = pc_id
for status in all_statuses:
attrs[resource_name]['status'] = status['status']
attrs[resource_name]['status_details'] = (
status['status_details'])
update_dict = {resource_name: status}
neutron_context = context.Context('', self._tenant_id)
operation_name = ''.join(['create_', resource_name])
res = plugin_ref.__getattribute__(operation_name)(
neutron_context, attrs)
self.assertEqual(status['status'], res['status'])
self.assertEqual(status_details, res['status_details'])
operation_name = ''.join(['update_', resource_name])
res = plugin_ref.__getattribute__(operation_name)(
neutron_context, res['id'], none_status_dict)
self.assertIsNone(res['status'])
self.assertIsNone(res['status_details'])
operation_name = ''.join(['update_', resource_name])
res = plugin_ref.__getattribute__(operation_name)(
neutron_context, res['id'], update_dict)
self.assertEqual(status['status'], res['status'])
self.assertEqual(status_details, res['status_details'])
def test_set_status_attrs(self):
for resource_name in gpolicy.RESOURCE_ATTRIBUTE_MAP:
self._test_set_status_attrs(self._get_resource_singular(
resource_name), self._gbp_plugin)

View File

@ -542,6 +542,15 @@ class TestServiceChainResources(ServiceChainDbTestCase):
ctx, sp_id)
class TestServiceChainStatusAttributesForResources(
test_group_policy_db.TestStatusAttributesForResources):
def test_set_status_attrs(self):
for resource_name in service_chain.RESOURCE_ATTRIBUTE_MAP:
self._test_set_status_attrs(self._get_resource_singular(
resource_name), self._sc_plugin)
class TestQuotasForServiceChain(ServiceChainDbTestCase):
def setUp(self, core_plugin=None, sc_plugin=None,

View File

@ -17,7 +17,10 @@ from neutron.tests.unit.plugins.ml2 import test_plugin
from oslo_config import cfg
import webob.exc
from gbpservice.neutron.db.grouppolicy import group_policy_mapping_db as gpmdb
from gbpservice.neutron.extensions import group_policy as gpolicy
from gbpservice.neutron.services.grouppolicy.drivers import dummy_driver
from gbpservice.neutron.services.grouppolicy import plugin as gplugin
from gbpservice.neutron.tests.unit.db.grouppolicy import (
test_group_policy_db as tgpdb)
from gbpservice.neutron.tests.unit.db.grouppolicy import (
@ -43,6 +46,17 @@ class FakeDriver(object):
return self._fill_order
NEW_STATUS = 'new_status'
NEW_STATUS_DETAILS = 'new_status_details'
def get_status_for_test(self, context):
resource_name = [item for item in context.__dict__.keys()
if item.startswith('_original')][0][len('_original'):]
getattr(context, resource_name)['status'] = NEW_STATUS
getattr(context, resource_name)['status_details'] = NEW_STATUS_DETAILS
class GroupPolicyPluginTestCase(tgpmdb.GroupPolicyMappingDbTestCase):
def setUp(self, core_plugin=None, gp_plugin=None, ml2_options=None,
@ -915,6 +929,97 @@ class TestPolicyTarget(GroupPolicyPluginTestCase):
self._test_cross_tenant(True)
class TestResourceStatusChange(GroupPolicyPluginTestCase):
def setUp(self, core_plugin=None, gp_plugin=None, ml2_options=None,
sc_plugin=None):
for resource_name in gpolicy.RESOURCE_ATTRIBUTE_MAP:
method_name = "get_" + self._get_resource_singular(
resource_name) + "_status"
setattr(dummy_driver.NoopDriver, method_name, get_status_for_test)
super(TestResourceStatusChange, self).setUp(
core_plugin=core_plugin, gp_plugin=gp_plugin, sc_plugin=sc_plugin)
def _test_status_change_on_get(self, resource_name, fields=None):
resource_singular = self._get_resource_singular(resource_name)
if resource_name == 'policy_rules':
pc_id = self.create_policy_classifier()['policy_classifier']['id']
resource = self.create_policy_rule(policy_classifier_id=pc_id)
else:
resource = getattr(self, "create_" + resource_singular)()
self.assertIsNone(resource[resource_singular]['status'])
self.assertIsNone(resource[resource_singular]['status_details'])
req = self.new_show_request(
resource_name, resource[resource_singular]['id'], fmt=self.fmt,
fields=fields)
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
if not fields:
self.assertEqual(NEW_STATUS, res[resource_singular]['status'])
self.assertEqual(NEW_STATUS_DETAILS,
res[resource_singular]['status_details'])
elif not gplugin.STATUS_SET.intersection(set(fields)):
neutron_context = context.Context('', self._tenant_id)
db_obj = getattr(
gpmdb.GroupPolicyMappingDbPlugin, "get_" + resource_singular)(
self._gbp_plugin, neutron_context,
resource[resource_singular]['id'])
self.assertIsNone(db_obj['status'])
self.assertIsNone(db_obj['status_details'])
def test_status_change_on_get(self):
for resource_name in gpolicy.RESOURCE_ATTRIBUTE_MAP:
self._test_status_change_on_get(resource_name)
def test_no_status_change_on_get(self):
# We explicitly populate the fields list with no status attributes
for resource_name in gpolicy.RESOURCE_ATTRIBUTE_MAP:
self._test_status_change_on_get(resource_name,
fields=['name'])
def _test_status_change_on_list(self, resource_name, fields=None):
resource_singular = self._get_resource_singular(resource_name)
if resource_name == 'policy_rules':
pc_id = self.create_policy_classifier()['policy_classifier']['id']
objs = [self.create_policy_rule(policy_classifier_id=pc_id),
self.create_policy_rule(policy_classifier_id=pc_id),
self.create_policy_rule(policy_classifier_id=pc_id)]
else:
create_method = "create_" + resource_singular
objs = [getattr(self, create_method)(),
getattr(self, create_method)(),
getattr(self, create_method)()]
for obj in objs:
req = self.new_show_request(
resource_name, obj[resource_singular]['id'], fmt=self.fmt,
fields=fields)
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
if not fields:
self.assertEqual(NEW_STATUS, res[resource_singular]['status'])
self.assertEqual(NEW_STATUS_DETAILS,
res[resource_singular]['status_details'])
elif not gplugin.STATUS_SET.intersection(set(fields)):
neutron_context = context.Context('', self._tenant_id)
db_obj = getattr(
gpmdb.GroupPolicyMappingDbPlugin,
"get_" + resource_singular)(
self._gbp_plugin, neutron_context,
obj[resource_singular]['id'])
self.assertIsNone(db_obj['status'])
self.assertIsNone(db_obj['status_details'])
def test_status_change_on_list(self):
for resource_name in gpolicy.RESOURCE_ATTRIBUTE_MAP:
self._test_status_change_on_list(resource_name)
def test_no_status_change_on_list(self):
for resource_name in gpolicy.RESOURCE_ATTRIBUTE_MAP:
self._test_status_change_on_list(resource_name, fields=['name'])
class TestPolicyAction(GroupPolicyPluginTestCase):
def test_redirect_value(self):