diff --git a/.gitignore b/.gitignore index 81fa95e01..876f30d81 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,6 @@ ChangeLog *~ .*.swp .*sw? + +# Pycharm +.idea diff --git a/gbpservice/neutron/db/grouppolicy/group_policy_db.py b/gbpservice/neutron/db/grouppolicy/group_policy_db.py index afb5eab02..9051cbc0e 100644 --- a/gbpservice/neutron/db/grouppolicy/group_policy_db.py +++ b/gbpservice/neutron/db/grouppolicy/group_policy_db.py @@ -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) diff --git a/gbpservice/neutron/db/grouppolicy/group_policy_mapping_db.py b/gbpservice/neutron/db/grouppolicy/group_policy_mapping_db.py index 41def1861..6bc73d016 100644 --- a/gbpservice/neutron/db/grouppolicy/group_policy_mapping_db.py +++ b/gbpservice/neutron/db/grouppolicy/group_policy_mapping_db.py @@ -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'] diff --git a/gbpservice/neutron/db/migration/alembic_migrations/versions/12c1bc8d7026_add_status_attributes.py b/gbpservice/neutron/db/migration/alembic_migrations/versions/12c1bc8d7026_add_status_attributes.py new file mode 100644 index 000000000..f58fab6a3 --- /dev/null +++ b/gbpservice/neutron/db/migration/alembic_migrations/versions/12c1bc8d7026_add_status_attributes.py @@ -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 diff --git a/gbpservice/neutron/db/migration/alembic_migrations/versions/HEAD b/gbpservice/neutron/db/migration/alembic_migrations/versions/HEAD index ece86f603..aaa0e4d3c 100644 --- a/gbpservice/neutron/db/migration/alembic_migrations/versions/HEAD +++ b/gbpservice/neutron/db/migration/alembic_migrations/versions/HEAD @@ -1 +1 @@ -31b399f08b1c +12c1bc8d7026 diff --git a/gbpservice/neutron/db/servicechain_db.py b/gbpservice/neutron/db/servicechain_db.py index 7c0199eec..11140408e 100644 --- a/gbpservice/neutron/db/servicechain_db.py +++ b/gbpservice/neutron/db/servicechain_db.py @@ -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) diff --git a/gbpservice/neutron/extensions/group_policy.py b/gbpservice/neutron/extensions/group_policy.py index 5fb0cf434..143a660d9 100644 --- a/gbpservice/neutron/extensions/group_policy.py +++ b/gbpservice/neutron/extensions/group_policy.py @@ -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]}, diff --git a/gbpservice/neutron/extensions/servicechain.py b/gbpservice/neutron/extensions/servicechain.py index 90ac6b12c..8b37a9068 100644 --- a/gbpservice/neutron/extensions/servicechain.py +++ b/gbpservice/neutron/extensions/servicechain.py @@ -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, diff --git a/gbpservice/neutron/services/grouppolicy/common/constants.py b/gbpservice/neutron/services/grouppolicy/common/constants.py index 29b11f3d7..b7c4fa595 100644 --- a/gbpservice/neutron/services/grouppolicy/common/constants.py +++ b/gbpservice/neutron/services/grouppolicy/common/constants.py @@ -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] diff --git a/gbpservice/neutron/services/grouppolicy/group_policy_context.py b/gbpservice/neutron/services/grouppolicy/group_policy_context.py index 5d334d220..b4983419f 100644 --- a/gbpservice/neutron/services/grouppolicy/group_policy_context.py +++ b/gbpservice/neutron/services/grouppolicy/group_policy_context.py @@ -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 diff --git a/gbpservice/neutron/services/grouppolicy/group_policy_driver_api.py b/gbpservice/neutron/services/grouppolicy/group_policy_driver_api.py index 02ad68823..95778a8b9 100644 --- a/gbpservice/neutron/services/grouppolicy/group_policy_driver_api.py +++ b/gbpservice/neutron/services/grouppolicy/group_policy_driver_api.py @@ -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): diff --git a/gbpservice/neutron/services/grouppolicy/plugin.py b/gbpservice/neutron/services/grouppolicy/plugin.py index b18252c16..be8fd3297 100644 --- a/gbpservice/neutron/services/grouppolicy/plugin.py +++ b/gbpservice/neutron/services/grouppolicy/plugin.py @@ -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 diff --git a/gbpservice/neutron/services/grouppolicy/policy_driver_manager.py b/gbpservice/neutron/services/grouppolicy/policy_driver_manager.py index f994d1ae6..d9c2c9e50 100644 --- a/gbpservice/neutron/services/grouppolicy/policy_driver_manager.py +++ b/gbpservice/neutron/services/grouppolicy/policy_driver_manager.py @@ -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) diff --git a/gbpservice/neutron/tests/unit/db/grouppolicy/test_group_policy_db.py b/gbpservice/neutron/tests/unit/db/grouppolicy/test_group_policy_db.py index 5148f50d5..d837a3bdc 100644 --- a/gbpservice/neutron/tests/unit/db/grouppolicy/test_group_policy_db.py +++ b/gbpservice/neutron/tests/unit/db/grouppolicy/test_group_policy_db.py @@ -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) diff --git a/gbpservice/neutron/tests/unit/db/grouppolicy/test_servicechain_db.py b/gbpservice/neutron/tests/unit/db/grouppolicy/test_servicechain_db.py index 063914cab..ce4da0e3a 100644 --- a/gbpservice/neutron/tests/unit/db/grouppolicy/test_servicechain_db.py +++ b/gbpservice/neutron/tests/unit/db/grouppolicy/test_servicechain_db.py @@ -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, diff --git a/gbpservice/neutron/tests/unit/services/grouppolicy/test_grouppolicy_plugin.py b/gbpservice/neutron/tests/unit/services/grouppolicy/test_grouppolicy_plugin.py index 15560694f..29218c77d 100644 --- a/gbpservice/neutron/tests/unit/services/grouppolicy/test_grouppolicy_plugin.py +++ b/gbpservice/neutron/tests/unit/services/grouppolicy/test_grouppolicy_plugin.py @@ -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):