Application Policy Groups

Change-Id: I7dcab3b9920ac9bd298115c6744735ba59bff419
Implements: blueprint application-group
This commit is contained in:
Sumit Naiksatam 2017-02-07 23:40:42 -08:00
parent 2f1c734586
commit 2aa3643e6e
14 changed files with 809 additions and 2 deletions

View File

@ -92,6 +92,9 @@ class PolicyTargetGroup(model_base.BASEV2, BaseSharedGbpResource):
} }
policy_targets = orm.relationship(PolicyTarget, policy_targets = orm.relationship(PolicyTarget,
backref='policy_target_group') backref='policy_target_group')
application_policy_group_id = sa.Column(
sa.String(36), sa.ForeignKey('gp_application_policy_groups.id'),
nullable=True)
l2_policy_id = sa.Column(sa.String(36), l2_policy_id = sa.Column(sa.String(36),
sa.ForeignKey('gp_l2_policies.id'), sa.ForeignKey('gp_l2_policies.id'),
nullable=True) nullable=True)
@ -107,6 +110,13 @@ class PolicyTargetGroup(model_base.BASEV2, BaseSharedGbpResource):
service_management = sa.Column(sa.Boolean) service_management = sa.Column(sa.Boolean)
class ApplicationPolicyGroup(model_base.BASEV2, BaseSharedGbpResource):
"""It is a collection of policy_targets."""
__tablename__ = 'gp_application_policy_groups'
policy_target_groups = orm.relationship(
PolicyTargetGroup, backref='application_policy_group')
class L2Policy(model_base.BASEV2, BaseSharedGbpResource): class L2Policy(model_base.BASEV2, BaseSharedGbpResource):
"""Represents a L2 Policy for a collection of policy_target_groups.""" """Represents a L2 Policy for a collection of policy_target_groups."""
__tablename__ = 'gp_l2_policies' __tablename__ = 'gp_l2_policies'
@ -400,6 +410,15 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
raise gpolicy.PolicyTargetGroupNotFound( raise gpolicy.PolicyTargetGroupNotFound(
policy_target_group_id=policy_target_group_id) policy_target_group_id=policy_target_group_id)
def _get_application_policy_group(self, context,
application_policy_group_id):
try:
return self._get_by_id(
context, ApplicationPolicyGroup, application_policy_group_id)
except exc.NoResultFound:
raise gpolicy.ApplicationPolicyGroupNotFound(
application_policy_group_id=application_policy_group_id)
def _get_l2_policy(self, context, l2_policy_id): def _get_l2_policy(self, context, l2_policy_id):
try: try:
return self._get_by_id(context, L2Policy, l2_policy_id) return self._get_by_id(context, L2Policy, l2_policy_id)
@ -674,6 +693,12 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
ptg_db = self._get_policy_target_group(context, ptg_id) ptg_db = self._get_policy_target_group(context, ptg_id)
ptg_db.l2_policy_id = l2p_id ptg_db.l2_policy_id = l2p_id
def _set_application_policy_group_for_policy_target_group(
self, context, ptg_id, apg_id):
with context.session.begin(subtransactions=True):
ptg_db = self._get_policy_target_group(context, ptg_id)
ptg_db.application_policy_group_id = apg_id
def _set_network_service_policy_for_policy_target_group( def _set_network_service_policy_for_policy_target_group(
self, context, ptg_id, nsp_id): self, context, ptg_id, nsp_id):
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
@ -792,6 +817,8 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
def _make_policy_target_group_dict(self, ptg, fields=None): def _make_policy_target_group_dict(self, ptg, fields=None):
res = self._populate_common_fields_in_dict(ptg) res = self._populate_common_fields_in_dict(ptg)
res['l2_policy_id'] = ptg['l2_policy_id'] res['l2_policy_id'] = ptg['l2_policy_id']
res['application_policy_group_id'] = ptg.get(
'application_policy_group_id', None)
res['network_service_policy_id'] = ptg['network_service_policy_id'] res['network_service_policy_id'] = ptg['network_service_policy_id']
res['service_management'] = ptg.get('service_management', False) res['service_management'] = ptg.get('service_management', False)
res['policy_targets'] = [ res['policy_targets'] = [
@ -804,6 +831,12 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
'consumed_policy_rule_sets']]) 'consumed_policy_rule_sets']])
return self._fields(res, fields) return self._fields(res, fields)
def _make_application_policy_group_dict(self, apg, fields=None):
res = self._populate_common_fields_in_dict(apg)
res['policy_target_groups'] = [
ptg['id'] for ptg in apg['policy_target_groups']]
return self._fields(res, fields)
def _make_l2_policy_dict(self, l2p, fields=None): def _make_l2_policy_dict(self, l2p, fields=None):
res = self._populate_common_fields_in_dict(l2p) res = self._populate_common_fields_in_dict(l2p)
res['l3_policy_id'] = l2p['l3_policy_id'] res['l3_policy_id'] = l2p['l3_policy_id']
@ -1111,6 +1144,8 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
id=uuidutils.generate_uuid(), tenant_id=tenant_id, id=uuidutils.generate_uuid(), tenant_id=tenant_id,
name=ptg['name'], description=ptg['description'], name=ptg['name'], description=ptg['description'],
l2_policy_id=ptg['l2_policy_id'], l2_policy_id=ptg['l2_policy_id'],
application_policy_group_id=ptg.get(
'application_policy_group_id', None),
network_service_policy_id=ptg['network_service_policy_id'], network_service_policy_id=ptg['network_service_policy_id'],
shared=ptg.get('shared', False), shared=ptg.get('shared', False),
service_management=ptg.get('service_management', False), service_management=ptg.get('service_management', False),
@ -1173,6 +1208,65 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
return self._get_collection_count(context, PolicyTargetGroup, return self._get_collection_count(context, PolicyTargetGroup,
filters=filters) filters=filters)
@log.log_method_call
def create_application_policy_group(self, context,
application_policy_group):
apg = application_policy_group['application_policy_group']
tenant_id = self._get_tenant_id_for_create(context, apg)
with context.session.begin(subtransactions=True):
apg_db = ApplicationPolicyGroup(
id=uuidutils.generate_uuid(), tenant_id=tenant_id,
name=apg['name'], description=apg['description'],
shared=apg.get('shared', False),
status=apg.get('status'),
status_details=apg.get('status_details'))
context.session.add(apg_db)
return self._make_application_policy_group_dict(apg_db)
@log.log_method_call
def update_application_policy_group(self, context,
application_policy_group_id,
application_policy_group):
apg = application_policy_group['application_policy_group']
with context.session.begin(subtransactions=True):
apg_db = self._get_application_policy_group(
context, application_policy_group_id)
apg_db.update(apg)
return self._make_application_policy_group_dict(apg_db)
@log.log_method_call
def delete_application_policy_group(self, context,
application_policy_group_id):
with context.session.begin(subtransactions=True):
apg_db = self._get_application_policy_group(
context, application_policy_group_id)
context.session.delete(apg_db)
@log.log_method_call
def get_application_policy_group(self, context,
application_policy_group_id, fields=None):
apg = self._get_application_policy_group(context,
application_policy_group_id)
return self._make_application_policy_group_dict(apg, fields)
@log.log_method_call
def get_application_policy_groups(self, context, filters=None,
fields=None, sorts=None, limit=None,
marker=None, page_reverse=False):
marker_obj = self._get_marker_obj(
context, 'application_policy_group', limit, marker)
return self._get_collection(context, ApplicationPolicyGroup,
self._make_application_policy_group_dict,
filters=filters, fields=fields,
sorts=sorts, limit=limit,
marker_obj=marker_obj,
page_reverse=page_reverse)
@log.log_method_call
def get_application_policy_groups_count(self, context, filters=None):
return self._get_collection_count(context, ApplicationPolicyGroup,
filters=filters)
@log.log_method_call @log.log_method_call
def create_l2_policy(self, context, l2_policy): def create_l2_policy(self, context, l2_policy):
l2p = l2_policy['l2_policy'] l2p = l2_policy['l2_policy']

View File

@ -450,6 +450,8 @@ class GroupPolicyMappingDbPlugin(gpdb.GroupPolicyDbPlugin):
id=uuid, tenant_id=tenant_id, id=uuid, tenant_id=tenant_id,
name=ptg['name'], description=ptg['description'], name=ptg['name'], description=ptg['description'],
l2_policy_id=ptg['l2_policy_id'], l2_policy_id=ptg['l2_policy_id'],
application_policy_group_id=ptg.get(
'application_policy_group_id', None),
network_service_policy_id=ptg['network_service_policy_id'], network_service_policy_id=ptg['network_service_policy_id'],
shared=ptg.get('shared', False), shared=ptg.get('shared', False),
service_management=ptg.get('service_management', False)) service_management=ptg.get('service_management', False))

View File

@ -1 +1 @@
daaa11a358a2 b6e301d5757f

View File

@ -0,0 +1,55 @@
# 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.
#
"""application_policy_group
Revision ID: b6e301d5757f
Revises: daaa11a358a2
Create Date: 2017-02-10 01:15:32.361753
"""
# revision identifiers, used by Alembic.
revision = 'b6e301d5757f'
down_revision = 'daaa11a358a2'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'gp_application_policy_groups',
sa.Column('id', sa.String(36), nullable=False),
sa.Column('tenant_id', sa.String(length=255), nullable=True),
sa.Column('name', sa.String(length=50), nullable=True),
sa.Column('description', sa.String(length=255), nullable=True),
sa.Column('status', sa.String(length=16), nullable=True),
sa.Column('status_details', sa.String(length=4096), nullable=True),
sa.PrimaryKeyConstraint('id'))
op.add_column(
'gp_policy_target_groups',
sa.Column('application_policy_group_id', sa.String(length=36),
nullable=True))
op.create_foreign_key('gp_application_policy_group_ibfk_1',
source='gp_policy_target_groups',
referent='gp_application_policy_groups',
local_cols=['application_policy_group_id'],
remote_cols=['id'])
def downgrade():
pass

View File

@ -55,6 +55,11 @@ class PolicyTargetGroupNotFound(nexc.NotFound):
"be found") "be found")
class ApplicationPolicyGroupNotFound(nexc.NotFound):
message = _("Application Policy Group %(application_policy_group_id)s "
"could not be found")
class ManagementPolicyTargetGroupExists(nexc.BadRequest): class ManagementPolicyTargetGroupExists(nexc.BadRequest):
message = _("Service Management Policy Target Group already exists for " message = _("Service Management Policy Target Group already exists for "
"this tenant.") "this tenant.")
@ -404,6 +409,8 @@ NETWORK_SERVICE_POLICIES = 'network_service_policies'
EXTERNAL_POLICIES = 'external_policies' EXTERNAL_POLICIES = 'external_policies'
EXTERNAL_SEGMENTS = 'external_segments' EXTERNAL_SEGMENTS = 'external_segments'
NAT_POOLS = 'nat_pools' NAT_POOLS = 'nat_pools'
APPLICATION_POLICY_GROUPS = 'application_policy_groups'
RESOURCE_ATTRIBUTE_MAP = { RESOURCE_ATTRIBUTE_MAP = {
POLICY_TARGETS: { POLICY_TARGETS: {
@ -454,6 +461,10 @@ RESOURCE_ATTRIBUTE_MAP = {
'l2_policy_id': {'allow_post': True, 'allow_put': True, 'l2_policy_id': {'allow_post': True, 'allow_put': True,
'validate': {'type:uuid_or_none': None}, 'validate': {'type:uuid_or_none': None},
'default': None, 'is_visible': True}, 'default': None, 'is_visible': True},
'application_policy_group_id': {'allow_post': True, 'allow_put': True,
'validate':
{'type:uuid_or_none': None},
'default': None, 'is_visible': True},
'provided_policy_rule_sets': {'allow_post': True, 'allow_put': True, 'provided_policy_rule_sets': {'allow_post': True, 'allow_put': True,
'validate': {'type:dict_or_none': None}, 'validate': {'type:dict_or_none': None},
'convert_to': 'convert_to':
@ -477,6 +488,32 @@ RESOURCE_ATTRIBUTE_MAP = {
'is_visible': True, 'required_by_policy': True, 'is_visible': True, 'required_by_policy': True,
'enforce_policy': True}, 'enforce_policy': True},
}, },
APPLICATION_POLICY_GROUPS: {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None}, 'is_visible': True,
'primary_key': True},
'name': {'allow_post': True, 'allow_put': True,
'validate': {'type:gbp_resource_name': None},
'default': '', 'is_visible': True},
'description': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': None},
'is_visible': True, 'default': ''},
'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,
'default': None, '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,
'enforce_policy': True},
},
L2_POLICIES: { L2_POLICIES: {
'id': {'allow_post': False, 'allow_put': False, 'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None}, 'is_visible': True, 'validate': {'type:uuid': None}, 'is_visible': True,
@ -860,6 +897,10 @@ group_based_policy_quota_opts = [
default=-1, default=-1,
help=_('Number of L2 Policies allowed per tenant. ' help=_('Number of L2 Policies allowed per tenant. '
'A negative value means unlimited.')), 'A negative value means unlimited.')),
cfg.IntOpt('quota_application_policy_group',
default=-1,
help=_('Number of Application Policy Groups allowed per tenant.'
' A negative value means unlimited.')),
cfg.IntOpt('quota_policy_target_group', cfg.IntOpt('quota_policy_target_group',
default=-1, default=-1,
help=_('Number of Policy Target Groups allowed per tenant. ' help=_('Number of Policy Target Groups allowed per tenant. '
@ -1009,6 +1050,33 @@ class GroupPolicyPluginBase(service_base.ServicePluginBase):
def delete_policy_target_group(self, context, policy_target_group_id): def delete_policy_target_group(self, context, policy_target_group_id):
pass pass
@abc.abstractmethod
def get_application_policy_groups(self, context, filters=None,
fields=None):
pass
@abc.abstractmethod
def get_application_policy_group(self, context,
application_policy_group_id,
fields=None):
pass
@abc.abstractmethod
def create_application_policy_group(self, context,
application_policy_group):
pass
@abc.abstractmethod
def update_application_policy_group(self, context,
application_policy_group_id,
application_policy_group):
pass
@abc.abstractmethod
def delete_application_policy_group(self, context,
application_policy_group_id):
pass
@abc.abstractmethod @abc.abstractmethod
def get_l2_policies(self, context, filters=None, fields=None): def get_l2_policies(self, context, filters=None, fields=None):
pass pass

View File

@ -70,6 +70,30 @@ class NoopDriver(api.PolicyDriver):
def delete_policy_target_group_postcommit(self, context): def delete_policy_target_group_postcommit(self, context):
pass pass
@log.log_method_call
def create_application_policy_group_precommit(self, context):
pass
@log.log_method_call
def create_application_policy_group_postcommit(self, context):
pass
@log.log_method_call
def update_application_policy_group_precommit(self, context):
pass
@log.log_method_call
def update_application_policy_group_postcommit(self, context):
pass
@log.log_method_call
def delete_application_policy_group_precommit(self, context):
pass
@log.log_method_call
def delete_application_policy_group_postcommit(self, context):
pass
@log.log_method_call @log.log_method_call
def create_l2_policy_precommit(self, context): def create_l2_policy_precommit(self, context):
pass pass

View File

@ -118,6 +118,21 @@ class ExtensionManager(stevedore.named.NamedExtensionManager):
for driver in self.ordered_ext_drivers: for driver in self.ordered_ext_drivers:
driver.obj.extend_policy_target_group_dict(session, result) driver.obj.extend_policy_target_group_dict(session, result)
def process_create_application_policy_group(self, session, data, result):
"""Call all extension drivers during PTG creation."""
self._call_on_ext_drivers("process_create_application_policy_group",
session, data, result)
def process_update_application_policy_group(self, session, data, result):
"""Call all extension drivers during PTG update."""
self._call_on_ext_drivers("process_update_application_policy_group",
session, data, result)
def extend_application_policy_group_dict(self, session, result):
"""Call all extension drivers to extend PTG dictionary."""
for driver in self.ordered_ext_drivers:
driver.obj.extend_application_policy_group_dict(session, result)
def process_create_l2_policy(self, session, data, result): def process_create_l2_policy(self, session, data, result):
"""Call all extension drivers during L2P creation.""" """Call all extension drivers during L2P creation."""
self._call_on_ext_drivers("process_create_l2_policy", self._call_on_ext_drivers("process_create_l2_policy",

View File

@ -69,6 +69,16 @@ class PolicyTargetGroupContext(GroupPolicyContext,
l2_policy_id) l2_policy_id)
self._policy_target_group['l2_policy_id'] = l2_policy_id self._policy_target_group['l2_policy_id'] = l2_policy_id
def set_application_policy_group_id(self, application_policy_group_id):
self._plugin._validate_shared_create(
self._plugin, self._plugin_context, self._policy_target_group,
'policy_target_group')
self._plugin._set_application_policy_group_for_policy_target_group(
self._plugin_context, self._policy_target_group['id'],
application_policy_group_id)
self._policy_target_group['application_policy_group_id'] = (
application_policy_group_id)
def set_network_service_policy_id(self, network_service_policy_id): def set_network_service_policy_id(self, network_service_policy_id):
nsp_id = network_service_policy_id nsp_id = network_service_policy_id
self._plugin._set_network_service_policy_for_policy_target_group( self._plugin._set_network_service_policy_for_policy_target_group(
@ -85,6 +95,26 @@ class PolicyTargetGroupContext(GroupPolicyContext,
self.add_subnet(subnet_id) self.add_subnet(subnet_id)
class ApplicationPolicyGroupContext(GroupPolicyContext,
api.ApplicationPolicyGroupContext):
def __init__(self, plugin, plugin_context, application_policy_group,
original_application_policy_group=None):
super(ApplicationPolicyGroupContext, self).__init__(
plugin, plugin_context)
self._application_policy_group = application_policy_group
self._original_application_policy_group = (
original_application_policy_group)
@property
def current(self):
return self._application_policy_group
@property
def original(self):
return self._original_application_policy_group
class L2PolicyContext(GroupPolicyContext, api.L2PolicyContext): class L2PolicyContext(GroupPolicyContext, api.L2PolicyContext):
def __init__(self, plugin, plugin_context, l2_policy, def __init__(self, plugin, plugin_context, l2_policy,

View File

@ -97,6 +97,17 @@ class PolicyTargetGroupContext(object):
""" """
pass pass
@abc.abstractmethod
def set_application_policy_group_id(self, application_policy_group_id):
"""Set the application_policy_group for the policy_target_group.
:param application_policy_group_id: application_policy_group for
the policy_target_group.
Set the application_policy_group for the policy_target_group.
"""
pass
@abc.abstractmethod @abc.abstractmethod
def set_network_service_policy_id(self, network_service_policy_id): def set_network_service_policy_id(self, network_service_policy_id):
"""Set the network_service_policy for the policy_target_group. """Set the network_service_policy for the policy_target_group.
@ -119,6 +130,37 @@ class PolicyTargetGroupContext(object):
pass pass
@six.add_metaclass(abc.ABCMeta)
class ApplicationPolicyGroupContext(object):
"""Context passed to policy engine for APG resource changes.
ApplicationPolicyGroupContext instance wraps a application_policy_group
resource. It provides helper methods for accessing other relevant
information. Results from expensive operations are cached for convenient
access.
"""
@abc.abstractproperty
def current(self):
"""Return the current state of the application_policy_group.
Return the current state of the application_policy_group, as defined by
GroupPolicyPlugin.create_application_policy_group.
"""
pass
@abc.abstractproperty
def original(self):
"""Return the original state of the application_policy_group.
Return the original state of the application_policy_group, prior to a
call to update_application_policy_group. Method is only valid within
calls to update_application_policy_group_precommit and
update_application_policy_group_postcommit.
"""
pass
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class L2PolicyContext(object): class L2PolicyContext(object):
"""Context passed to policy engine for l2_policy resource changes. """Context passed to policy engine for l2_policy resource changes.
@ -648,6 +690,69 @@ class PolicyDriver(object):
""" """
pass pass
def create_application_policy_group_precommit(self, context):
"""Allocate resources for a new application_policy_group.
:param context: ApplicationPolicyGroupContext instance describing the
new application_policy_group.
"""
pass
def create_application_policy_group_postcommit(self, context):
"""Create a application_policy_group.
:param context: ApplicationPolicyGroupContext instance describing the
new application_policy_group.
"""
pass
def update_application_policy_group_precommit(self, context):
"""Update resources of a application_policy_group.
:param context: ApplicationPolicyGroupContext instance describing the
new state of the application_policy_group, as well as the original
state prior to the update_application_policy_group call.
"""
pass
def update_application_policy_group_postcommit(self, context):
"""Update a application_policy_group.
:param context: ApplicationPolicyGroupContext instance describing the
new state of the application_policy_group, as well as the original
state prior to the update_application_policy_group call.
"""
pass
def delete_application_policy_group_precommit(self, context):
"""Delete resources for a application_policy_group.
:param context: ApplicationPolicyGroupContext instance describing the
current state of the application_policy_group, prior to the call to
delete it.
"""
pass
def delete_application_policy_group_postcommit(self, context):
"""Delete a application_policy_group.
:param context: ApplicationPolicyGroupContext instance describing the
current state of the application_policy_group, prior to the call to
delete it.
"""
pass
def get_application_policy_group_status(self, context):
"""Get most recent status of a application_policy_group.
:param context: ApplicationPolicyGroupContext instance describing the
current state of the application_policy_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): def create_l2_policy_precommit(self, context):
"""Allocate resources for a new l2_policy. """Allocate resources for a new l2_policy.
@ -1390,6 +1495,48 @@ class ExtensionDriver(object):
""" """
pass pass
def process_create_application_policy_group(self, session, data, result):
"""Process extended attributes for application_policy_group creation.
:param session: database session
:param data: dictionary of incoming application_policy_group data
:param result: application_policy_group dictionary to extend
Called inside transaction context on session to validate and
persist any extended application_policy_group attributes defined by
this driver. Extended attribute values must also be added to
result.
"""
pass
def process_update_application_policy_group(self, session, data, result):
"""Process extended attributes for application_policy_group update.
:param session: database session
:param data: dictionary of incoming application_policy_group data
:param result: application_policy_group dictionary to extend
Called inside transaction context on session to validate and
update any extended application_policy_group attributes defined by
this driver. Extended attribute values, whether updated or
not, must also be added to result.
"""
pass
def extend_application_policy_group_dict(self, session, result):
"""Add extended attributes to application_policy_group dictionary.
:param session: database session
:param result: application_policy_group dictionary to extend
Called inside transaction context on session to add any
extended attributes defined by this driver to a
application_policy_group dictionary to be used for mechanism driver
calls and/or returned as the result of a application_policy_group
operation.
"""
pass
def process_create_l2_policy(self, session, data, result): def process_create_l2_policy(self, session, data, result):
"""Process extended attributes for l2_policy creation. """Process extended attributes for l2_policy creation.

View File

@ -112,7 +112,8 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
'nat_pool': {'external_segment_id': 'nat_pool': {'external_segment_id':
'external_segment'}, 'external_segment'},
'policy_target': {'policy_target_group_id': 'policy_target': {'policy_target_group_id':
'policy_target_group'} 'policy_target_group'},
'application_policy_group': {}
} }
_plurals = None _plurals = None
@ -421,6 +422,7 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
l2_policy=group_policy_mapping_db.L2PolicyMapping, l2_policy=group_policy_mapping_db.L2PolicyMapping,
policy_target=group_policy_mapping_db.PolicyTargetMapping, policy_target=group_policy_mapping_db.PolicyTargetMapping,
policy_target_group=group_policy_mapping_db.PolicyTargetGroupMapping, policy_target_group=group_policy_mapping_db.PolicyTargetGroupMapping,
application_policy_group=gpdb.ApplicationPolicyGroup,
policy_classifier=gpdb.PolicyClassifier, policy_classifier=gpdb.PolicyClassifier,
policy_action=gpdb.PolicyAction, policy_action=gpdb.PolicyAction,
policy_rule=gpdb.PolicyRule, policy_rule=gpdb.PolicyRule,
@ -683,6 +685,107 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
filters=filters, fields=fields, sorts=sorts, limit=limit, filters=filters, fields=fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse) marker=marker, page_reverse=page_reverse)
@log.log_method_call
def create_application_policy_group(self, context,
application_policy_group):
self._ensure_tenant(
context, application_policy_group['application_policy_group'])
session = context.session
pdm = self.policy_driver_manager
with session.begin(subtransactions=True):
result = super(GroupPolicyPlugin,
self).create_application_policy_group(
context, application_policy_group)
self.extension_manager.process_create_application_policy_group(
session, application_policy_group, result)
self._validate_shared_create(self, context, result,
'application_policy_group')
policy_context = p_context.ApplicationPolicyGroupContext(
self, context, result)
pdm.create_application_policy_group_precommit(policy_context)
try:
pdm.create_application_policy_group_postcommit(policy_context)
except Exception:
with excutils.save_and_reraise_exception():
LOG.exception(_LE("create_application_policy_group_postcommit "
"failed, deleting APG %s"),
result['id'])
self.delete_application_policy_group(context, result['id'])
return self.get_application_policy_group(context, result['id'])
@log.log_method_call
def update_application_policy_group(self, context,
application_policy_group_id,
application_policy_group):
session = context.session
pdm = self.policy_driver_manager
with session.begin(subtransactions=True):
original_application_policy_group = (
self.get_application_policy_group(
context, application_policy_group_id))
updated_application_policy_group = super(
GroupPolicyPlugin, self).update_application_policy_group(
context, application_policy_group_id,
application_policy_group)
self.extension_manager.process_update_application_policy_group(
session, application_policy_group,
updated_application_policy_group)
self._validate_shared_update(
self, context, original_application_policy_group,
updated_application_policy_group, 'application_policy_group')
policy_context = p_context.ApplicationPolicyGroupContext(
self, context, updated_application_policy_group,
original_application_policy_group=
original_application_policy_group)
pdm.update_application_policy_group_precommit(policy_context)
pdm.update_application_policy_group_postcommit(policy_context)
return self.get_application_policy_group(context,
application_policy_group_id)
@log.log_method_call
def delete_application_policy_group(self, context,
application_policy_group_id):
session = context.session
pdm = self.policy_driver_manager
with session.begin(subtransactions=True):
application_policy_group = self.get_application_policy_group(
context, application_policy_group_id)
policy_context = p_context.ApplicationPolicyGroupContext(
self, context, application_policy_group)
pdm.delete_application_policy_group_precommit(policy_context)
super(GroupPolicyPlugin, self).delete_application_policy_group(
context, application_policy_group_id)
try:
pdm.delete_application_policy_group_postcommit(policy_context)
except Exception:
LOG.exception(_LE("delete_application_policy_group_postcommit "
"failed for application_policy_group %s"),
application_policy_group_id)
@log.log_method_call
def get_application_policy_group(self, context,
application_policy_group_id, fields=None):
return self._get_resource(context, 'application_policy_group',
application_policy_group_id,
'ApplicationPolicyGroupContext',
fields=fields)
@log.log_method_call
def get_application_policy_groups(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
return self._get_resources(
context, 'application_policy_group',
'ApplicationPolicyGroupContext', filters=filters, fields=fields,
sorts=sorts, limit=limit, marker=marker, page_reverse=page_reverse)
@log.log_method_call @log.log_method_call
def create_l2_policy(self, context, l2_policy): def create_l2_policy(self, context, l2_policy):
self._ensure_tenant(context, l2_policy['l2_policy']) self._ensure_tenant(context, l2_policy['l2_policy'])

View File

@ -194,6 +194,33 @@ class PolicyDriverManager(stevedore.named.NamedExtensionManager):
def get_policy_target_group_status(self, context): def get_policy_target_group_status(self, context):
self._call_on_drivers("get_policy_target_group_status", context) self._call_on_drivers("get_policy_target_group_status", context)
def create_application_policy_group_precommit(self, context):
self._call_on_drivers("create_application_policy_group_precommit",
context)
def create_application_policy_group_postcommit(self, context):
self._call_on_drivers("create_application_policy_group_postcommit",
context)
def update_application_policy_group_precommit(self, context):
self._call_on_drivers("update_application_policy_group_precommit",
context)
def update_application_policy_group_postcommit(self, context):
self._call_on_drivers("update_application_policy_group_postcommit",
context)
def delete_application_policy_group_precommit(self, context):
self._call_on_drivers("delete_application_policy_group_precommit",
context)
def delete_application_policy_group_postcommit(self, context):
self._call_on_drivers("delete_application_policy_group_postcommit",
context, continue_on_failure=True)
def get_application_policy_group_status(self, context):
self._call_on_drivers("get_application_policy_group_status", context)
def create_l2_policy_precommit(self, context): def create_l2_policy_precommit(self, context):
self._call_on_drivers("create_l2_policy_precommit", context) self._call_on_drivers("create_l2_policy_precommit", context)

View File

@ -41,9 +41,27 @@ def get_update_policy_target_attrs():
return {'name': 'new_name'} return {'name': 'new_name'}
@gbp_attributes
def get_create_application_policy_group_default_attrs():
return {'name': '', 'description': '', 'shared': False}
@gbp_attributes
def get_create_application_policy_group_attrs():
return {'name': 'apg1', 'tenant_id': _uuid(),
'description': 'test application_policy_group',
'shared': False}
@gbp_attributes
def get_update_application_policy_group_attrs():
return {'name': 'new_name'}
@gbp_attributes @gbp_attributes
def get_create_policy_target_group_default_attrs(): def get_create_policy_target_group_default_attrs():
return {'name': '', 'description': '', 'l2_policy_id': None, return {'name': '', 'description': '', 'l2_policy_id': None,
'application_policy_group_id': None,
'provided_policy_rule_sets': {}, 'provided_policy_rule_sets': {},
'consumed_policy_rule_sets': {}, 'consumed_policy_rule_sets': {},
'network_service_policy_id': None, 'shared': False, 'network_service_policy_id': None, 'shared': False,
@ -55,6 +73,7 @@ def get_create_policy_target_group_attrs():
return {'name': 'ptg1', 'tenant_id': _uuid(), return {'name': 'ptg1', 'tenant_id': _uuid(),
'description': 'test policy_target group', 'description': 'test policy_target group',
'l2_policy_id': _uuid(), 'l2_policy_id': _uuid(),
'application_policy_group_id': _uuid(),
'provided_policy_rule_sets': {_uuid(): None}, 'provided_policy_rule_sets': {_uuid(): None},
'consumed_policy_rule_sets': {_uuid(): None}, 'consumed_policy_rule_sets': {_uuid(): None},
'network_service_policy_id': _uuid(), 'network_service_policy_id': _uuid(),

View File

@ -506,6 +506,78 @@ class TestGroupResources(GroupPolicyDbTestCase):
self.assertEqual( self.assertEqual(
res['policy_target_group']['network_service_policy_id'], None) res['policy_target_group']['network_service_policy_id'], None)
def _test_create_and_show_application_policy_group(self):
name = "apg1"
attrs = cm.get_create_application_policy_group_default_attrs(
name=name)
apg = self.create_application_policy_group(
name=name)
for k, v in attrs.iteritems():
self.assertEqual(apg['application_policy_group'][k], v)
self._test_show_resource('application_policy_group',
apg['application_policy_group']['id'], attrs)
return apg
def test_create_associate_apg_with_ptgs(self):
apg = self._test_create_and_show_application_policy_group()
apg_id = apg['application_policy_group']['id']
# Create two PTGs that use this NSP
name = "ptg1"
attrs = cm.get_create_policy_target_group_default_attrs(
name=name, application_policy_group_id=apg_id)
attrs['provided_policy_rule_sets'] = []
attrs['consumed_policy_rule_sets'] = []
ptg1 = self.create_policy_target_group(
name=name,
application_policy_group_id=apg_id)['policy_target_group']
for k, v in attrs.iteritems():
self.assertEqual(v, ptg1[k])
self._test_show_resource(
'policy_target_group', ptg1['id'], attrs)
apg = self._show_resource(apg_id, 'application_policy_groups')[
'application_policy_group']
self.assertEqual([ptg1['id']], apg['policy_target_groups'])
ptg2 = self.create_policy_target_group(name=name)[
'policy_target_group']
del attrs['application_policy_group_id']
for k, v in attrs.iteritems():
self.assertEqual(v, ptg2[k])
self._test_show_resource('policy_target_group', ptg2['id'], attrs)
apg = self._show_resource(apg_id, 'application_policy_groups')[
'application_policy_group']
self.assertEqual([ptg1['id']], apg['policy_target_groups'])
# Update the PTG to set the APG
data = {'policy_target_group': {'application_policy_group_id': apg_id}}
req = self.new_update_request('policy_target_groups', data, ptg2['id'])
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
self.assertEqual(
apg_id, res['policy_target_group']['application_policy_group_id'])
apg = self._show_resource(apg_id, 'application_policy_groups')[
'application_policy_group']
self.assertItemsEqual([ptg1['id'], ptg2['id']],
apg['policy_target_groups'])
# Update the PTG to unset the APG
data = {'policy_target_group': {'application_policy_group_id': None}}
req = self.new_update_request('policy_target_groups', data, ptg2['id'])
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
self.assertEqual(
None, res['policy_target_group']['application_policy_group_id'])
apg = self._show_resource(apg_id, 'application_policy_groups')[
'application_policy_group']
self.assertEqual([ptg1['id']], apg['policy_target_groups'])
def test_list_policy_target_groups(self): def test_list_policy_target_groups(self):
ptgs = ( ptgs = (
[self.create_policy_target_group(name='ptg1', description='ptg'), [self.create_policy_target_group(name='ptg1', description='ptg'),
@ -561,6 +633,51 @@ class TestGroupResources(GroupPolicyDbTestCase):
self.assertRaises(gpolicy.PolicyTargetGroupNotFound, self.assertRaises(gpolicy.PolicyTargetGroupNotFound,
self.plugin.get_policy_target_group, ctx, ptg_id) self.plugin.get_policy_target_group, ctx, ptg_id)
def test_create_and_show_application_policy_group(self):
self._test_create_and_show_application_policy_group()
def test_list_application_policy_groups(self):
apgs = (
[self.create_application_policy_group(name='apg1',
description='apg'),
self.create_application_policy_group(name='apg2',
description='apg'),
self.create_application_policy_group(name='apg3',
description='apg')])
self._test_list_resources('application_policy_group', apgs,
query_params='description=apg')
def test_update_application_policy_group(self):
name = "new_application_policy_group1"
description = 'new desc'
attrs = cm.get_create_application_policy_group_default_attrs(
name=name, description=description)
apg = self.create_application_policy_group()
data = {'application_policy_group':
{'name': name, 'description': description}}
req = self.new_update_request('application_policy_groups', data,
apg['application_policy_group']['id'])
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
for k, v in attrs.iteritems():
self.assertEqual(res['application_policy_group'][k], v)
self._test_show_resource('application_policy_group',
apg['application_policy_group']['id'], attrs)
def test_delete_application_policy_group(self):
ctx = context.get_admin_context()
apg = self.create_application_policy_group()
apg_id = apg['application_policy_group']['id']
req = self.new_delete_request('application_policy_groups', apg_id)
res = req.get_response(self.ext_api)
self.assertEqual(webob.exc.HTTPNoContent.code, res.status_int)
self.assertRaises(gpolicy.ApplicationPolicyGroupNotFound,
self.plugin.get_application_policy_group, ctx,
apg_id)
def test_create_and_show_l2_policy(self): def test_create_and_show_l2_policy(self):
l3p_id = self.create_l3_policy()['l3_policy']['id'] l3p_id = self.create_l3_policy()['l3_policy']['id']
attrs = cm.get_create_l2_policy_default_attrs(l3_policy_id=l3p_id) attrs = cm.get_create_l2_policy_default_attrs(l3_policy_id=l3p_id)

View File

@ -34,6 +34,8 @@ GP_PLUGIN_BASE_NAME = (
GROUPPOLICY_URI = 'grouppolicy' GROUPPOLICY_URI = 'grouppolicy'
POLICY_TARGETS_URI = GROUPPOLICY_URI + '/' + 'policy_targets' POLICY_TARGETS_URI = GROUPPOLICY_URI + '/' + 'policy_targets'
POLICY_TARGET_GROUPS_URI = GROUPPOLICY_URI + '/' + 'policy_target_groups' POLICY_TARGET_GROUPS_URI = GROUPPOLICY_URI + '/' + 'policy_target_groups'
APPLICATION_POLICY_GROUPS_URI = (
GROUPPOLICY_URI + '/' + 'application_policy_groups')
L2_POLICIES_URI = GROUPPOLICY_URI + '/' + 'l2_policies' L2_POLICIES_URI = GROUPPOLICY_URI + '/' + 'l2_policies'
L3_POLICIES_URI = GROUPPOLICY_URI + '/' + 'l3_policies' L3_POLICIES_URI = GROUPPOLICY_URI + '/' + 'l3_policies'
POLICY_RULES_URI = GROUPPOLICY_URI + '/' + 'policy_rules' POLICY_RULES_URI = GROUPPOLICY_URI + '/' + 'policy_rules'
@ -262,6 +264,110 @@ class GroupPolicyExtensionTestCase(test_extensions_base.ExtensionTestCase):
def test_delete_policy_target_group(self): def test_delete_policy_target_group(self):
self._test_entity_delete('policy_target_group') self._test_entity_delete('policy_target_group')
def _test_create_application_policy_group(self, data, expected_value,
default_data=None):
if not default_data:
default_data = data
self.instance.create_application_policy_group.return_value = (
expected_value)
res = self.api.post(_get_path(APPLICATION_POLICY_GROUPS_URI,
fmt=self.fmt),
self.serialize(data),
content_type='application/%s' % self.fmt)
self.instance.create_application_policy_group.assert_called_once_with(
mock.ANY, application_policy_group=default_data)
self.assertEqual(exc.HTTPCreated.code, res.status_int)
res = self.deserialize(res)
self.assertIn('application_policy_group', res)
self.assertEqual(expected_value, res['application_policy_group'])
def test_create_application_policy_group_with_defaults(self):
application_policy_group_id = _uuid()
data = {'application_policy_group': {'tenant_id': _uuid()}}
default_attrs = (
self.get_create_application_policy_group_default_attrs())
default_data = copy.copy(data)
default_data['application_policy_group'].update(default_attrs)
expected_value = copy.deepcopy(
default_data['application_policy_group'])
expected_value['id'] = application_policy_group_id
self._test_create_application_policy_group(data, expected_value,
default_data)
def test_create_application_policy_group(self):
application_policy_group_id = _uuid()
data = {'application_policy_group':
self.get_create_application_policy_group_attrs()}
expected_value = copy.deepcopy(data['application_policy_group'])
expected_value['id'] = application_policy_group_id
self._test_create_application_policy_group(data, expected_value)
def test_list_application_policy_groups(self):
application_policy_group_id = _uuid()
expected_value = [{'tenant_id': _uuid(),
'id': application_policy_group_id}]
self.instance.get_application_policy_groups.return_value = (
expected_value)
res = self.api.get(_get_path(APPLICATION_POLICY_GROUPS_URI,
fmt=self.fmt))
self.instance.get_application_policy_groups.assert_called_once_with(
mock.ANY, fields=mock.ANY, filters=mock.ANY)
self.assertEqual(exc.HTTPOk.code, res.status_int)
res = self.deserialize(res)
self.assertIn('application_policy_groups', res)
self.assertEqual(expected_value, res['application_policy_groups'])
def test_get_application_policy_group(self):
application_policy_group_id = _uuid()
expected_value = {'tenant_id': _uuid(),
'id': application_policy_group_id}
self.instance.get_application_policy_group.return_value = (
expected_value)
res = self.api.get(_get_path(APPLICATION_POLICY_GROUPS_URI,
id=application_policy_group_id,
fmt=self.fmt))
self.instance.get_application_policy_group.assert_called_once_with(
mock.ANY, application_policy_group_id, fields=mock.ANY)
self.assertEqual(exc.HTTPOk.code, res.status_int)
res = self.deserialize(res)
self.assertIn('application_policy_group', res)
self.assertEqual(expected_value, res['application_policy_group'])
def test_update_application_policy_group(self):
application_policy_group_id = _uuid()
update_data = {'application_policy_group':
self.get_update_application_policy_group_attrs()}
expected_value = {'tenant_id': _uuid(),
'id': application_policy_group_id}
self.instance.update_application_policy_group.return_value = (
expected_value)
res = self.api.put(_get_path(APPLICATION_POLICY_GROUPS_URI,
id=application_policy_group_id,
fmt=self.fmt),
self.serialize(update_data))
self.instance.update_application_policy_group.assert_called_once_with(
mock.ANY, application_policy_group_id,
application_policy_group=update_data)
self.assertEqual(exc.HTTPOk.code, res.status_int)
res = self.deserialize(res)
self.assertIn('application_policy_group', res)
self.assertEqual(expected_value, res['application_policy_group'])
def test_delete_application_policy_group(self):
self._test_entity_delete('application_policy_group')
def _test_create_l2_policy(self, data, expected_value, default_data=None): def _test_create_l2_policy(self, data, expected_value, default_data=None):
if not default_data: if not default_data:
default_data = data default_data = data