diff --git a/gbpservice/neutron/plugins/ml2/drivers/grouppolicy/nuage/__init__.py b/gbpservice/neutron/plugins/ml2/drivers/grouppolicy/nuage/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/gbpservice/neutron/plugins/ml2/drivers/grouppolicy/nuage/driver.py b/gbpservice/neutron/plugins/ml2/drivers/grouppolicy/nuage/driver.py deleted file mode 100644 index 5f54f008f..000000000 --- a/gbpservice/neutron/plugins/ml2/drivers/grouppolicy/nuage/driver.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2014 Alcatel-Lucent USA Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -from neutron.plugins.ml2 import driver_api as api - -from gbpservice.neutron.services.grouppolicy.drivers.nuage import driver - - -NOVA_PORT_OWNER_PREF = 'compute:' - - -class NuageMechanismGBPDriver(api.MechanismDriver): - - def initialize(self): - self._nuage_gbp = None - - @property - def nuage_gbp(self): - if not self._nuage_gbp: - self._nuage_gbp = (driver.NuageGBPDriver. - get_initialized_instance()) - return self._nuage_gbp - - def update_port_postcommit(self, context): - port = context.current - port_prefix = NOVA_PORT_OWNER_PREF - # Check two things prior to proceeding with - # talking to backend. - # 1) binding has happened successfully. - # 2) Its a VM port. - if ((not context.original_bound_segment and - context.bound_segment) and - port['device_owner'].startswith(port_prefix)): - self.nuage_gbp.create_nuage_policy_target( - context._plugin_context, context.current) diff --git a/gbpservice/neutron/plugins/ml2/drivers/grouppolicy/odl/__init__.py b/gbpservice/neutron/plugins/ml2/drivers/grouppolicy/odl/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/gbpservice/neutron/plugins/ml2/drivers/grouppolicy/odl/driver.py b/gbpservice/neutron/plugins/ml2/drivers/grouppolicy/odl/driver.py deleted file mode 100644 index 141ab4985..000000000 --- a/gbpservice/neutron/plugins/ml2/drivers/grouppolicy/odl/driver.py +++ /dev/null @@ -1,76 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from neutron.common import constants as n_constants -from neutron.extensions import portbindings -from neutron.plugins.common import constants -from neutron.plugins.ml2 import driver_api as api -from oslo_log import log as log - -from gbpservice.neutron.services.grouppolicy.drivers.odl import odl_mapping - - -LOG = log.getLogger(__name__) - - -class OdlMechanismGBPDriver(api.MechanismDriver): - - def initialize(self): - self._odl_gbp = None - self.vif_type = portbindings.VIF_TYPE_OVS - self.vif_details = {portbindings.CAP_PORT_FILTER: True} - - @property - def odl_gbp(self): - if not self._odl_gbp: - self._odl_gbp = (odl_mapping.OdlMappingDriver. - get_initialized_instance()) - return self._odl_gbp - - def create_port_postcommit(self, context): - # DHCP Ports are created implicitly by Neutron, need to inform GBP - if (context.current.get('device_owner') == - n_constants.DEVICE_OWNER_DHCP): - self.odl_gbp.create_dhcp_policy_target_if_needed( - context._plugin_context, context.current - ) - - def bind_port(self, context): - LOG.debug("Attempting to bind port %(port)s on " - "network %(network)s", - {'port': context.current['id'], - 'network': context.network.current['id']}) - for segment in context.network.network_segments: - if self._check_segment(segment): - context.set_binding(segment[api.ID], - self.vif_type, - self.vif_details, - status=n_constants.PORT_STATUS_ACTIVE) - LOG.debug("Bound using segment: %s", segment) - return - else: - LOG.debug("Refusing to bind port for segment ID %(id)s, " - "segment %(seg)s, phys net %(physnet)s, and " - "network type %(nettype)s", - {'id': segment[api.ID], - 'seg': segment[api.SEGMENTATION_ID], - 'physnet': segment[api.PHYSICAL_NETWORK], - 'nettype': segment[api.NETWORK_TYPE]}) - - def _check_segment(self, segment): - """Verify a segment is valid for the OpenDaylight MechanismDriver. - - Verify the requested segment is supported by ODL and return True or - False to indicate this to callers. - """ - network_type = segment[api.NETWORK_TYPE] - return network_type in [constants.TYPE_VXLAN, ] diff --git a/gbpservice/neutron/services/grouppolicy/drivers/odl/__init__.py b/gbpservice/neutron/services/grouppolicy/drivers/odl/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/gbpservice/neutron/services/grouppolicy/drivers/odl/config.py b/gbpservice/neutron/services/grouppolicy/drivers/odl/config.py deleted file mode 100644 index ac77c5faa..000000000 --- a/gbpservice/neutron/services/grouppolicy/drivers/odl/config.py +++ /dev/null @@ -1,32 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_config import cfg - - -od_driver_opts = [ - cfg.StrOpt('odl_username', - default='admin', - help=_("OpenDaylight Controller Username")), - cfg.StrOpt('odl_password', - default='admin', - help=_("OpenDaylight Controller Password")), - cfg.StrOpt('odl_host', - default='127.0.0.1', - help=_("OpenDaylight Controller host ip address")), - cfg.StrOpt('odl_port', - default='8080', - help=_("OpenDaylight Controller Rest API port number")), -] - - -cfg.CONF.register_opts(od_driver_opts, "odl_driver") diff --git a/gbpservice/neutron/services/grouppolicy/drivers/odl/odl_manager.py b/gbpservice/neutron/services/grouppolicy/drivers/odl/odl_manager.py deleted file mode 100644 index 9ee443474..000000000 --- a/gbpservice/neutron/services/grouppolicy/drivers/odl/odl_manager.py +++ /dev/null @@ -1,288 +0,0 @@ -# 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. - -import requests -from requests import auth - -from neutron._i18n import _LI -from oslo_config import cfg -from oslo_log import log as logging -from oslo_serialization import jsonutils - - -LOG = logging.getLogger(__name__) - -cfg.CONF.import_opt( - 'odl_username', - 'gbpservice.neutron.services.grouppolicy.drivers.odl.config', - group='odl_driver' -) -cfg.CONF.import_opt( - 'odl_password', - 'gbpservice.neutron.services.grouppolicy.drivers.odl.config', - group='odl_driver' -) -cfg.CONF.import_opt( - 'odl_host', - 'gbpservice.neutron.services.grouppolicy.drivers.odl.config', - group='odl_driver' -) -cfg.CONF.import_opt( - 'odl_port', - 'gbpservice.neutron.services.grouppolicy.drivers.odl.config', - group='odl_driver' -) - - -class OdlManager(object): - """Class to manage ODL translations and workflow. - - This class manages translation from Neutron objects to APIC - managed objects and contains workflows to implement these - translations. - """ - - def __init__(self): - - LOG.info(_LI("Configured ODL username: %s"), - cfg.CONF.odl_driver.odl_username) - LOG.info(_LI("Configured ODL password: %s"), - cfg.CONF.odl_driver.odl_password) - LOG.info(_LI("Configured ODL host: %s"), - cfg.CONF.odl_driver.odl_host) - LOG.info(_LI("Configured ODL port: %s"), - cfg.CONF.odl_driver.odl_port) - - self._username = cfg.CONF.odl_driver.odl_username - self._password = cfg.CONF.odl_driver.odl_password - self._host = cfg.CONF.odl_driver.odl_host - self._port = cfg.CONF.odl_driver.odl_port - self._headers = { - 'Content-type': 'application/yang.data+json', - 'Accept': 'application/yang.data+json', - } - - self._base_url = ( - "http://%(host)s:%(port)s/restconf" % - {'host': self._host, 'port': self._port} - ) - self._reg_ep_url = ( - self._base_url + - '/operations/endpoint:register-endpoint' - ) - self._unreg_ep_url = ( - self._base_url + - '/operations/endpoint:unregister-endpoint' - ) - self._policy_url = ( - self._base_url + - '/config/policy:tenants/policy:tenant/%(tenant_id)s' - ) - self._action_url = ( - self._policy_url + - '/subject-feature-instances/action-instance/%(action)s' - ) - self._classifier_url = ( - self._policy_url + - '/subject-feature-instances/classifier-instance/%(classifier)s' - ) - self._l3ctx_url = ( - self._policy_url + - '/l3-context/%(l3ctx)s' - ) - self._l2bd_url = ( - self._policy_url + - '/l2-bridge-domain/%(l2bd)s' - ) - self._l2fd_url = ( - self._policy_url + - '/l2-flood-domain/%(l2fd)s' - ) - self._epg_url = ( - self._policy_url + - '/policy:endpoint-group/%(epg)s' - ) - self._subnet_url = ( - self._policy_url + - '/subnet/%(subnet)s' - ) - self._contract_url = ( - self._policy_url + - '/policy:contract/%(contract)s' - ) - - def _convert2ascii(self, obj): - if isinstance(obj, dict): - return {self._convert2ascii(key): self._convert2ascii(value) for - key, value in obj.iteritems()} - elif isinstance(obj, list): - return [self._convert2ascii(element) for element in obj] - elif isinstance(obj, unicode): - return obj.encode('ascii', 'ignore') - else: - return obj - - def _sendjson(self, method, url, headers, obj=None): - """Send json to the ODL controller.""" - - medium = self._convert2ascii(obj) if obj else None - url = self._convert2ascii(url) - data = ( - jsonutils.dumps(medium, indent=4, sort_keys=True) if medium - else None - ) - LOG.debug("=========================================================") - LOG.debug("Sending METHOD (%(method)s) URL (%(url)s)", - {'method': method, 'url': url}) - LOG.debug("(%(data)s)", {'data': data}) - LOG.debug("=========================================================") - r = requests.request( - method, - url=url, - headers=headers, - data=data, - auth=auth.HTTPBasicAuth(self._username, - self._password) - ) - r.raise_for_status() - - def _is_tenant_created(self, tenant_id): - url = self._convert2ascii(self._policy_url % {'tenant_id': tenant_id}) - r = requests.request( - 'get', - url=url, - headers=self._headers, - auth=auth.HTTPBasicAuth(self._username, - self._password) - ) - if r.status_code == 200: - return True - elif r.status_code == 404: - return False - else: - r.raise_for_status() - - def register_endpoints(self, endpoints): - for ep in endpoints: - data = {"input": ep} - self._sendjson('post', self._reg_ep_url, self._headers, data) - - def unregister_endpoints(self, endpoints): - for ep in endpoints: - data = {"input": ep} - self._sendjson('post', self._unreg_ep_url, self._headers, data) - - def create_update_tenant(self, tenant_id, tenant): - url = (self._policy_url % {'tenant_id': tenant_id}) - data = {"tenant": tenant} - self._sendjson('put', url, self._headers, data) - - def create_action(self, tenant_id, action): - """Create policy action""" - self._touch_tenant(tenant_id) - url = (self._action_url % - {'tenant_id': tenant_id, 'action': action['name']}) - data = {"action-instance": action} - self._sendjson('put', url, self._headers, data) - - def delete_action(self, tenant_id, action): - """Delete policy action""" - url = (self._action_url % - {'tenant_id': tenant_id, 'action': action['name']}) - self._sendjson('delete', url, self._headers) - - def create_classifier(self, tenant_id, classifier): - """Create policy classifier""" - self._touch_tenant(tenant_id) - url = (self._classifier_url % - {'tenant_id': tenant_id, 'classifier': classifier['name']}) - data = {"classifier-instance": classifier} - self._sendjson('put', url, self._headers, data) - - def delete_classifier(self, tenant_id, classifier): - """Delete policy classifier""" - url = (self._classifier_url % - {'tenant_id': tenant_id, 'classifier': classifier['name']}) - self._sendjson('delete', url, self._headers) - - def create_update_l3_context(self, tenant_id, l3ctx): - self._touch_tenant(tenant_id) - url = (self._l3ctx_url % - {'tenant_id': tenant_id, 'l3ctx': l3ctx['id']}) - data = {"l3-context": l3ctx} - self._sendjson('put', url, self._headers, data) - - def delete_l3_context(self, tenant_id, l3ctx): - url = (self._l3ctx_url % - {'tenant_id': tenant_id, 'l3ctx': l3ctx['id']}) - self._sendjson('delete', url, self._headers) - - def create_update_l2_bridge_domain(self, tenant_id, l2bd): - self._touch_tenant(tenant_id) - url = (self._l2bd_url % - {'tenant_id': tenant_id, 'l2bd': l2bd['id']}) - data = {"l2-bridge-domain": l2bd} - self._sendjson('put', url, self._headers, data) - - def delete_l2_bridge_domain(self, tenant_id, l2bd): - url = (self._l2bd_url % - {'tenant_id': tenant_id, 'l2bd': l2bd['id']}) - self._sendjson('delete', url, self._headers) - - def create_update_l2_flood_domain(self, tenant_id, l2fd): - self._touch_tenant(tenant_id) - url = (self._l2fd_url % - {'tenant_id': tenant_id, 'l2fd': l2fd['id']}) - data = {"l2-flood-domain": l2fd} - self._sendjson('put', url, self._headers, data) - - def delete_l2_flood_domain(self, tenant_id, l2fd): - url = (self._l2fd_url % - {'tenant_id': tenant_id, 'l2fd': l2fd['id']}) - self._sendjson('delete', url, self._headers) - - def create_update_endpoint_group(self, tenant_id, epg): - self._touch_tenant(tenant_id) - url = (self._epg_url % - {'tenant_id': tenant_id, 'epg': epg['id']}) - data = {"endpoint-group": epg} - self._sendjson('put', url, self._headers, data) - - def delete_endpoint_group(self, tenant_id, epg): - url = (self._epg_url % - {'tenant_id': tenant_id, 'epg': epg['id']}) - self._sendjson('delete', url, self._headers) - - def create_update_subnet(self, tenant_id, subnet): - self._touch_tenant(tenant_id) - url = (self._subnet_url % - {'tenant_id': tenant_id, 'subnet': subnet['id']}) - data = {"subnet": subnet} - self._sendjson('put', url, self._headers, data) - - def delete_subnet(self, tenant_id, subnet): - url = (self._subnet_url % - {'tenant_id': tenant_id, 'subnet': subnet['id']}) - self._sendjson('delete', url, self._headers) - - def create_update_contract(self, tenant_id, contract): - url = (self._contract_url % - {'tenant_id': tenant_id, 'contract': contract['id']}) - data = {"contract": contract} - self._sendjson('put', url, self._headers, data) - - def _touch_tenant(self, tenant_id): - tenant = { - "id": tenant_id - } - if not self._is_tenant_created(tenant_id): - self.create_update_tenant(tenant_id, tenant) diff --git a/gbpservice/neutron/services/grouppolicy/drivers/odl/odl_mapping.py b/gbpservice/neutron/services/grouppolicy/drivers/odl/odl_mapping.py deleted file mode 100644 index 62f53991c..000000000 --- a/gbpservice/neutron/services/grouppolicy/drivers/odl/odl_mapping.py +++ /dev/null @@ -1,636 +0,0 @@ -# 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. - -import uuid - -from neutron.common import constants -from neutron import manager -from oslo_concurrency import lockutils # noqa -from oslo_log import log as logging - -from gbpservice.neutron.db.grouppolicy import group_policy_mapping_db as gpdb -from gbpservice.neutron.services.grouppolicy.common import constants as g_const -from gbpservice.neutron.services.grouppolicy.common import exceptions as gpexc -from gbpservice.neutron.services.grouppolicy.drivers import ( - resource_mapping as api) -from gbpservice.neutron.services.grouppolicy.drivers.odl import odl_manager - - -LOG = logging.getLogger(__name__) - - -class ExternalSegmentNotSupportedOnOdlDriver(gpexc.GroupPolicyBadRequest): - message = _("External Segment currently not supported on ODL GBP " - "driver.") - - -class UpdateL3PolicyNotSupportedOnOdlDriver(gpexc.GroupPolicyBadRequest): - message = _("Update L3 Policy currently not supported on ODL GBP " - "driver.") - - -class UpdateL2PolicyNotSupportedOnOdlDriver(gpexc.GroupPolicyBadRequest): - message = _("Update L2 Policy currently not supported on ODL GBP " - "driver.") - - -class UpdatePTNotSupportedOnOdlDriver(gpexc.GroupPolicyBadRequest): - message = _("Update Policy Target currently not supported on ODL GBP " - "driver.") - - -class UpdatePTGNotSupportedOnOdlDriver(gpexc.GroupPolicyBadRequest): - message = _("Update Policy Target Group currently not supported on ODL " - "GBP driver.") - - -class L2PolicyMultiplePolicyTargetGroupNotSupportedOnOdlDriver( - gpexc.GroupPolicyBadRequest): - message = _("An L2 policy can't have multiple policy target groups on " - "ODL GBP driver.") - - -class UpdatePolicyActionNotSupportedOnOdlDriver(gpexc.GroupPolicyBadRequest): - message = _("Update Policy Action currently not supported on ODL GBP " - "driver.") - - -class RedirectActionNotSupportedOnOdlDriver(gpexc.GroupPolicyBadRequest): - message = _("Redirect action is currently not supported for ODL GBP " - "driver.") - - -class OnlyAllowActionSupportedOnOdlDriver(gpexc.GroupPolicyBadRequest): - message = _("Currently only allow action is supported for ODL GBP " - "driver.") - - -class UpdateClassifierNotSupportedOnOdlDriver(gpexc.GroupPolicyBadRequest): - message = _("Update Policy Classifier currently not supported on ODL GBP " - "driver.") - - -class PolicyRuleUpdateNotSupportedOnOdlDriver(gpexc.GroupPolicyBadRequest): - message = _("Policy rule update is not supported on for ODL GBP " - "driver.") - - -class PolicyRuleSetUpdateNotSupportedOnOdlDriver(gpexc.GroupPolicyBadRequest): - message = _("Policy rule set update is not supported on for ODL GBP " - "driver.") - - -class ExactlyOneActionPerRuleIsSupportedOnOdlDriver( - gpexc.GroupPolicyBadRequest): - message = _("Exactly one action per rule is supported on ODL GBP driver.") - - -class ClassifierTcpUdpPortRangeNotSupportedOnOdlDriver( - gpexc.GroupPolicyBadRequest): - message = _("Tcp or Udp port range is not supported on ODL GBP driver.") - - -class ClassifierUnknownIPProtocolNotSupportedOnOdlDriver( - gpexc.GroupPolicyBadRequest): - message = _("Unknown IP Protocol is not supported on ODL GBP driver.") - - -class OdlMappingDriver(api.ResourceMappingDriver): - """ODL Mapping driver for Group Policy plugin. - - This driver implements group policy semantics by mapping group - policy resources to various other neutron resources, and leverages - ODL backend for enforcing the policies. - """ - - me = None - manager = None - - @staticmethod - def get_odl_manager(): - if not OdlMappingDriver.manager: - OdlMappingDriver.manager = odl_manager.OdlManager() - return OdlMappingDriver.manager - - def initialize(self): - super(OdlMappingDriver, self).initialize() - self.odl_manager = OdlMappingDriver.get_odl_manager() - self._gbp_plugin = None - OdlMappingDriver.me = self - - @property - def gbp_plugin(self): - if not self._gbp_plugin: - self._gbp_plugin = (manager.NeutronManager.get_service_plugins() - .get("GROUP_POLICY")) - return self._gbp_plugin - - @staticmethod - def get_initialized_instance(): - return OdlMappingDriver.me - - def create_dhcp_policy_target_if_needed(self, plugin_context, port): - session = plugin_context.session - if (self._port_is_owned(session, port['id'])): - # Nothing to do - return - - # Retrieve PTG - # TODO(ywu): optimize later - subnets = self._core_plugin._get_subnets_by_network( - plugin_context, port['network_id'] - ) - ptg = (plugin_context.session.query(gpdb.PolicyTargetGroupMapping). - join(gpdb.PolicyTargetGroupMapping.subnets). - filter(gpdb.PTGToSubnetAssociation.subnet_id == - subnets[0]['id']). - first()) - - # Create PolicyTarget - attrs = {'policy_target': - {'tenant_id': port['tenant_id'], - 'name': 'dhcp-%s' % ptg['id'], - 'description': ("Implicitly created DHCP policy " - "target"), - 'policy_target_group_id': ptg['id'], - 'port_id': port['id']}} - self.gbp_plugin.create_policy_target(plugin_context, attrs) - # TODO(ODL): security group is not required - # sg_id = self._ensure_default_security_group(plugin_context, - # port['tenant_id']) - # data = {'port': {'security_groups': [sg_id]}} - # self._core_plugin.update_port(plugin_context, port['id'], data) - - def create_external_segment_precommit(self, context): - raise ExternalSegmentNotSupportedOnOdlDriver() - - def update_external_segment_precommit(self, context): - raise ExternalSegmentNotSupportedOnOdlDriver() - - def delete_external_segment_precommit(self, context): - raise ExternalSegmentNotSupportedOnOdlDriver() - - def create_external_policy_precommit(self, context): - raise ExternalSegmentNotSupportedOnOdlDriver() - - def update_external_policy_precommit(self, context): - raise ExternalSegmentNotSupportedOnOdlDriver() - - def delete_external_policy_precommit(self, context): - raise ExternalSegmentNotSupportedOnOdlDriver() - - def create_nat_pool_precommit(self, context): - raise ExternalSegmentNotSupportedOnOdlDriver() - - def update_nat_pool_precommit(self, context): - raise ExternalSegmentNotSupportedOnOdlDriver() - - def delete_nat_pool_precommit(self, context): - raise ExternalSegmentNotSupportedOnOdlDriver() - - def create_policy_target_postcommit(self, context): - super(OdlMappingDriver, self).create_policy_target_postcommit(context) - pt = self._get_pt_detail(context) - ep = { - "endpoint-group": pt['ptg_id'], - "l2-context": pt['l2ctx_id'], - "l3-address": pt['l3_list'], - "mac-address": pt['mac_address'], - "port-name": pt['neutron_port_id'], - "tenant": pt['tenant_id'] - } - self.odl_manager.register_endpoints([ep]) - - def update_policy_target_precommit(self, context): - raise UpdatePTNotSupportedOnOdlDriver() - - def delete_policy_target_postcommit(self, context): - pt = self._get_pt_detail(context) - ep = { - "l2": pt['l2_list'], - "l3": pt['l3_list'] - } - self.odl_manager.unregister_endpoints([ep]) - # Delete Neutron's port - super(OdlMappingDriver, self).delete_policy_target_postcommit(context) - - def create_l3_policy_postcommit(self, context): - tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - l3ctx = { - "id": context.current['id'], - "name": context.current['name'], - "description": context.current['description'] - } - self.odl_manager.create_update_l3_context(tenant_id, l3ctx) - - def update_l3_policy_precommit(self, context): - raise UpdateL3PolicyNotSupportedOnOdlDriver() - - def delete_l3_policy_postcommit(self, context): - tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - l3ctx = { - "id": context.current['id'] - } - self.odl_manager.delete_l3_context(tenant_id, l3ctx) - - def create_l2_policy_postcommit(self, context): - super(OdlMappingDriver, self).create_l2_policy_postcommit(context) - tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - - # l2_policy mapped to l2_bridge_domain in ODL - l2bd = { - "id": context.current['id'], - "name": context.current['name'], - "description": context.current['description'], - "parent": context.current['l3_policy_id'] - } - self.odl_manager.create_update_l2_bridge_domain(tenant_id, l2bd) - - # Implicit network within l2 policy mapped to l2 FD in ODL - net_id = context.current['network_id'] - network = self._core_plugin.get_network(context._plugin_context, - net_id) - l2fd = { - "id": net_id, - "name": network['name'], - "parent": context.current['id'] - } - self.odl_manager.create_update_l2_flood_domain(tenant_id, l2fd) - - def update_l2_policy_precommit(self, context): - raise UpdateL2PolicyNotSupportedOnOdlDriver() - - def delete_l2_policy_postcommit(self, context): - super(OdlMappingDriver, self).delete_l2_policy_postcommit(context) - tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - - # l2_policy mapped to l2_bridge_domain in ODL - l2bd = { - "id": context.current['id'] - } - self.odl_manager.delete_l2_bridge_domain(tenant_id, l2bd) - - # Implicit network within l2 policy mapped to l2 FD in ODL - net_id = context.current['network_id'] - l2fd = { - "id": net_id, - } - self.odl_manager.delete_l2_flood_domain(tenant_id, l2fd) - - def create_policy_target_group_postcommit(self, context): - super(OdlMappingDriver, self).create_policy_target_group_postcommit( - context) - - # consumed_policy_rule_sets mapped to consumer_named_selectors - consumer_named_selectors = [] - for prs_id in context.current['consumed_policy_rule_sets']: - prs = context._plugin.get_policy_rule_set( - context._plugin_context, prs_id - ) - consumer_named_selectors.append( - { - "name": prs['name'], - "contract": prs_id - } - ) - - # provided_policy_rule_sets mapped to provider_named_selectors - provider_named_selectors = [] - for prs_id in context.current['provided_policy_rule_sets']: - prs = context._plugin.get_policy_rule_set( - context._plugin_context, prs_id - ) - provider_named_selectors.append( - { - "name": prs['name'], - "contract": prs_id - } - ) - - # PTG mapped to EPG in ODL - subnets = context.current['subnets'] - epg = { - "id": context.current['id'], - "name": context.current['name'], - "description": context.current['description'], - "network-domain": subnets[0], - "consumer-named-selector": consumer_named_selectors, - "provider-named-selector": provider_named_selectors - } - tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - self.odl_manager.create_update_endpoint_group(tenant_id, epg) - - # Implicit subnet within policy target group mapped to subnet in ODL - for subnet_id in subnets: - neutron_subnet = self._core_plugin.get_subnet( - context._plugin_context, subnet_id - ) - odl_subnet = { - "id": subnet_id, - "ip-prefix": neutron_subnet['cidr'], - "parent": neutron_subnet['network_id'], - "virtual-router-ip": neutron_subnet['gateway_ip'] - } - self.odl_manager.create_update_subnet(tenant_id, odl_subnet) - - def update_policy_target_group_precommit(self, context): - raise UpdatePTGNotSupportedOnOdlDriver() - - def delete_policy_target_group_postcommit(self, context): - tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - subnets = context.current['subnets'] - - # delete mapped subnets in ODL, and clean them up from neutron - for subnet_id in subnets: - self._cleanup_subnet(context._plugin_context, subnet_id, None) - odl_subnet = { - "id": subnet_id - } - self.odl_manager.delete_subnet(tenant_id, odl_subnet) - - # delete mapped EPG in ODL - epg = { - "id": context.current['id'], - } - self.odl_manager.delete_endpoint_group(tenant_id, epg) - - def create_policy_action_precommit(self, context): - # TODO(odl): allow redirect for service chaining - if context.current['action_type'] == g_const.GP_ACTION_REDIRECT: - raise RedirectActionNotSupportedOnOdlDriver() - - def create_policy_action_postcommit(self, context): - super(OdlMappingDriver, self).create_policy_action_postcommit(context) - # TODO(ODL): remove comment out after PoC - # tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - - # fill in action instance data - if context.current['action_type'] == g_const.GP_ACTION_ALLOW: - # TODO(ODL): remove the return and comment out after POC - return - # action_definition_id = "f942e8fd-e957-42b7-bd18-f73d11266d17" - # action_instance = { - # "action-definition-id": action_definition_id, - # "name": context.current['name'], - # "parameter-value": [ - # { - # "name": context.current['name'], - # "string-value": context.current['action_type'], - # } - # ] - # } - # self.odl_manager.create_action(tenant_id, action_instance) - else: - raise OnlyAllowActionSupportedOnOdlDriver() - - def update_policy_action_precommit(self, context): - raise UpdatePolicyActionNotSupportedOnOdlDriver() - - def delete_policy_action_postcommit(self, context): - super(OdlMappingDriver, self).delete_policy_action_postcommit(context) - # TODO(ODL): remove comment out after PoC - # tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - # - # # fill in action instance data - # action_instance = { - # "name": context.current['name'] - # } - # self.odl_manager.delete_action(tenant_id, action_instance) - - def create_policy_classifier_postcommit(self, context): - tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - classifiers = self._make_odl_classifiers(context.current) - - for classifier in classifiers: - classifier_instance = { - "classifier-definition-id": - classifier['classifier-definition-id'], - "name": classifier['name'], - "parameter-value": classifier['parameter-value'] - } - self.odl_manager.create_classifier(tenant_id, classifier_instance) - - def _make_odl_classifiers(self, stack_classifier): - classifiers = [] - if stack_classifier['protocol'] == constants.PROTO_NAME_ICMP: - direction = stack_classifier['direction'] - if direction == 'bi': - direction = "bidirectional" - classifier = { - # Use hard coded value based on current ODL implementation - "classifier-definition-id": - '79c6fdb2-1e1a-4832-af57-c65baf5c2335', - "name": stack_classifier['name'], - "parameter-value": [ - { - "name": "proto", - # TODO(yapeng): change the hard code value - "int-value": 1, - } - ], - "direction": direction - } - classifiers.append(classifier) - else: - # For TCP and UDP protoocol create two classifier (in and out) - for port in ['sourceport', 'destport']: - if stack_classifier['direction'] == 'in': - if port == 'destport': - direction = 'in' - else: - direction = 'out' - elif stack_classifier['direction'] == 'out': - if port == 'destport': - direction = 'out' - else: - direction = 'in' - else: - direction = 'bidirectional' - - classifier = { - # Use hard coded value based on current ODL implementation - "classifier-definition-id": - '4250ab32-e8b8-445a-aebb-e1bd2cdd291f', - "direction": direction, - "name": stack_classifier['name'] + '-' + port, - "parameter-value": [ - { - "name": "type", - "string-value": stack_classifier['protocol'], - }, - { - "name": port, - "int-value": stack_classifier['port_range'], - } - ] - } - classifiers.append(classifier) - return classifiers - - def update_policy_classifier_precommit(self, context): - raise UpdateClassifierNotSupportedOnOdlDriver() - - def delete_policy_classifier_postcommit(self, context): - tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - - if context.current['protocol'] == constants.PROTO_NAME_ICMP: - # fill in classifier instance data - classifier_instance = { - "name": context.current['name'] - } - self.odl_manager.delete_classifier(tenant_id, classifier_instance) - return - - # fill in classifier instance data - for port in ['sourceport', 'destport']: - classifier_instance = { - "name": context.current['name'] + '-' + port, - } - self.odl_manager.delete_classifier(tenant_id, classifier_instance) - - def create_policy_rule_precommit(self, context): - if ('policy_actions' in context.current and - len(context.current['policy_actions']) != 1): - # TODO(odl): to be fixed when redirect is supported - raise ExactlyOneActionPerRuleIsSupportedOnOdlDriver() - - def update_policy_rule_precommit(self, context): - # TODO(ivar): add support for action update on policy rules - raise PolicyRuleUpdateNotSupportedOnOdlDriver() - - def create_policy_rule_set_postcommit(self, context): - """Each Policy Rule Set is mapped to a contract, with a single clause - - Each included Policy Rule will be mapped to one subject, which includes - one rule. - - The clause has no matcher, but refers to all the subjects - """ - subjects = [] - subject_names = [] - for rule_id in context.current['policy_rules']: - subject = self._make_odl_subject(context, rule_id) - subjects.append(subject) - subject_names.append(subject['name']) - - clauses = [ - { - "name": context.current['name'], - "subject-refs": subject_names - } - ] - - contract_id = context.current['id'] - contract_desc = context.current['name'] - contract = { - "id": contract_id, - "description": contract_desc, - "clause": clauses, - "subject": subjects - } - - tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - self.odl_manager.create_update_contract(tenant_id, contract) - - def _make_odl_subject(self, context, rule_id): - gbp_rule = context._plugin.get_policy_rule( - context._plugin_context, rule_id - ) - odl_rules = [] - odl_rule = self._make_odl_rule(context, rule_id) - odl_rules.append(odl_rule) - return { - "name": gbp_rule['name'], - "rule": odl_rules - } - - def _make_odl_rule(self, context, rule_id): - rule = context._plugin.get_policy_rule( - context._plugin_context, rule_id - ) - stack_classifier = context._plugin.get_policy_classifier( - context._plugin_context, rule['policy_classifier_id'] - ) - - # while openstack supports only one classifier per rule, the classifier - # may mapped to multi classifier in ODL - classifier_refs = [] - classifiers = self._make_odl_classifiers(stack_classifier) - for classifier in classifiers: - classifier_ref = { - "name": classifier['name'] - } - if classifier['direction'] != "bidirectional": - classifier_ref['direction'] = classifier['direction'] - classifier_refs.append(classifier_ref) - action_refs = [] - for action_id in rule['policy_actions']: - action = context._plugin.get_policy_action( - context._plugin_context, action_id - ) - action_refs.append( - { - "name": action['name'] - } - ) - - # TODO(ODL): send action_refs later but not for PoC - return { - "name": rule['name'], - "classifier-ref": classifier_refs, - } - - def update_policy_rule_set_precommit(self, context): - # TODO(Yi): add support for action update on policy rule sets - raise PolicyRuleSetUpdateNotSupportedOnOdlDriver() - - def _get_pt_detail(self, context): - port_id = context.current['port_id'] - port = self._core_plugin.get_port(context._plugin_context, port_id) - tenant_id = uuid.UUID(context.current['tenant_id']).urn[9:] - ptg_id = context.current['policy_target_group_id'] - ptg = self.gbp_plugin.get_policy_target_group(context._plugin_context, - ptg_id) - l2ctx_id = ptg['l2_policy_id'] - l2ctx = self.gbp_plugin.get_l2_policy(context._plugin_context, - l2ctx_id) - l3ctx_id = l2ctx['l3_policy_id'] - mac_address = port['mac_address'] - neutron_port_id = 'tap' + port_id[:11] - - l3_list = [] - for fixed_ip in port['fixed_ips']: - l3_list.append( - { - "ip-address": fixed_ip['ip_address'], - "l3-context": l3ctx_id - } - ) - - l2_list = [ - { - "l2-context": l2ctx_id, - "mac-address": mac_address - } - ] - - return { - "port_id": port_id, - "tenant_id": tenant_id, - "ptg_id": ptg_id, - "l2ctx_id": l2ctx_id, - "l3ctx_id": l3ctx_id, - "mac_address": mac_address, - "neutron_port_id": neutron_port_id, - "l3_list": l3_list, - "l2_list": l2_list, - } diff --git a/gbpservice/neutron/tests/unit/services/grouppolicy/test_odl_manager.py b/gbpservice/neutron/tests/unit/services/grouppolicy/test_odl_manager.py deleted file mode 100644 index 4348c67ff..000000000 --- a/gbpservice/neutron/tests/unit/services/grouppolicy/test_odl_manager.py +++ /dev/null @@ -1,463 +0,0 @@ -# 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. - -import requests -import unittest - -import mock -from oslo_serialization import jsonutils - -from gbpservice.neutron.services.grouppolicy import config -from gbpservice.neutron.services.grouppolicy.drivers.odl import odl_manager - - -HOST = 'fake_host' -PORT = 'fake_port' -USERNAME = 'fake_username' -PASSWORD = 'fake_password' -HEADER = { - 'Content-type': 'application/yang.data+json', - 'Accept': 'application/yang.data+json', -} - -VALUE = 'fake_value' -TENANT_ID = 'fake_tenant_id' -TENANT = { - 'id': TENANT_ID, - 'value': VALUE -} -ENDPOINT = 'fake_endpoint' -ACTION_NAME = 'fake_action_name' -ACTION = { - 'name': ACTION_NAME, - 'value': VALUE -} -CLASSIFIER_NAME = 'fake_classifier_name' -CLASSIFIER = { - 'name': CLASSIFIER_NAME, - 'value': VALUE -} -L3CTX_ID = 'fake_l3ctx_id' -L3CTX = { - 'id': L3CTX_ID, - 'value': VALUE -} -L2BD_ID = 'fake_l2bd_id' -L2BD = { - 'id': L2BD_ID, - 'value': VALUE -} -L2FD_ID = 'fake_l2bd_id' -L2FD = { - 'id': L2FD_ID, - 'value': VALUE -} -EPG_ID = 'fake_epg_id' -EPG = { - 'id': EPG_ID, - 'value': VALUE -} -SUBNET_ID = 'fake_subnet_id' -SUBNET = { - 'id': SUBNET_ID, - 'value': VALUE -} -CONTRACT_ID = 'fake_contract_id' -CONTRACT = { - 'id': CONTRACT_ID, - 'value': VALUE -} - -URL_BASE = ("http://%(host)s:%(port)s/restconf" % - {'host': HOST, 'port': PORT}) -URL_REG_EP = (URL_BASE + - '/operations/endpoint:register-endpoint') -URL_UNREG_EP = (URL_BASE + - '/operations/endpoint:unregister-endpoint') -URL_TENANT = (URL_BASE + - '/config/policy:tenants/policy:tenant/%s' % - TENANT_ID) -URL_ACTION = (URL_TENANT + - '/subject-feature-instances/action-instance/%s' % - ACTION_NAME) -URL_CLASSIFIER = (URL_TENANT + - '/subject-feature-instances/classifier-instance/%s' % - CLASSIFIER_NAME) -URL_L3CTX = (URL_TENANT + '/l3-context/%s' % L3CTX_ID) -URL_L2BD = (URL_TENANT + '/l2-bridge-domain/%s' % L2BD_ID) -URL_L2FD = (URL_TENANT + '/l2-flood-domain/%s' % L2FD_ID) -URL_EPG = (URL_TENANT + '/policy:endpoint-group/%s' % EPG_ID) -URL_SUBNET = (URL_TENANT + '/subnet/%s' % SUBNET_ID) -URL_CONTRACT = (URL_TENANT + '/policy:contract/%s' % CONTRACT_ID) - - -class AuthMatcher(object): - """ A customized class to check if authentication object is matched or not - - AS authentication is passed as an object reference, we cannot test the - object directly, instead, we check if the correct username and password - is used - """ - - def __eq__(self, obj): - return (obj.username == USERNAME and obj.password == PASSWORD) - - -class DataMatcher(object): - """ A customized class to check if data is matched or not - - As data is passed as a string for HTTP request in ODL manager, we cannot - directly test the data object. Instead, we have to convert the data to - the string in the same format - """ - - def __init__(self, obj): - self._data = jsonutils.dumps( - obj, - indent=4, - sort_keys=True - ) - - def __eq__(self, obj): - return (self._data == obj) - - -class OdlManagerTestCase(unittest.TestCase): - """ Test case for ODL manager testing - - Set up the testing environment - """ - - def setUp(self): - config.cfg.CONF.set_override('odl_username', - USERNAME, - group='odl_driver') - config.cfg.CONF.set_override('odl_password', - PASSWORD, - group='odl_driver') - config.cfg.CONF.set_override('odl_host', - HOST, - group='odl_driver') - config.cfg.CONF.set_override('odl_port', - PORT, - group='odl_driver') - - self.manager = odl_manager.OdlManager() - - # test a single HTTP request - def _test_single_request_operation( - self, - http_method, - tested_method, - *args, - **kwargs - ): - with mock.patch('requests.request') as mock_request: - tested_method(*args) - mock_request.assert_called_once_with( - http_method, - **kwargs - ) - - # In some ODL manager operations, ODL manager needs to check if a tenant - # is existing or not, if not, the ODL manager needs to create the tenant - # first -- such a scenario needs to be tested with this method - def _test_multi_request_operations( - self, - http_method, - tested_method, - *args, - **kwargs - ): - with mock.patch.object(odl_manager.OdlManager, - '_is_tenant_created') as mock_is_tenant_created: - with mock.patch('requests.request') as mock_request: - mock_is_tenant_created.return_value = True - tested_method(*args) - mock_request.assert_called_once_with( - http_method, - **kwargs - ) - - mock_is_tenant_created.return_value = False - mock_request.reset_mock() - tested_method(*args) - mock_request.assert_any_call( - 'put', - url=URL_TENANT, - headers=HEADER, - data=DataMatcher({'tenant': {'id': TENANT_ID}}), - auth=AuthMatcher() - ) - mock_request.assert_any_call( - http_method, - **kwargs - ) - - @mock.patch.object(requests, 'request') - def test_is_tenant_created(self, mock_request): - - mock_request.return_value = mock.Mock( - status_code=200 - ) - assert self.manager._is_tenant_created(TENANT_ID) - mock_request.assert_called_once_with( - 'get', - url=URL_TENANT, - headers=HEADER, - auth=AuthMatcher() - ) - - mock_request.reset_mock() - mock_request.return_value = mock.Mock( - status_code=404 - ) - assert not self.manager._is_tenant_created(TENANT_ID) - mock_request.assert_called_once_with( - 'get', - url=URL_TENANT, - headers=HEADER, - auth=AuthMatcher() - ) - - def test_register_endpoints(self): - method = getattr(self.manager, 'register_endpoints') - self._test_single_request_operation( - 'post', - method, - [ENDPOINT], - url=URL_REG_EP, - headers=HEADER, - data=DataMatcher({'input': ENDPOINT}), - auth=AuthMatcher() - ) - - def test_unregister_endpoints(self): - method = getattr(self.manager, 'unregister_endpoints') - self._test_single_request_operation( - 'post', - method, - [ENDPOINT], - url=URL_UNREG_EP, - headers=HEADER, - data=DataMatcher({'input': ENDPOINT}), - auth=AuthMatcher() - ) - - def test_create_update_tenant(self): - method = getattr(self.manager, 'create_update_tenant') - self._test_single_request_operation( - 'put', - method, - TENANT_ID, - TENANT, - url=URL_TENANT, - headers=HEADER, - data=DataMatcher({'tenant': TENANT}), - auth=AuthMatcher() - ) - - def test_create_action(self): - method = getattr(self.manager, 'create_action') - self._test_multi_request_operations( - 'put', - method, - TENANT_ID, - ACTION, - url=URL_ACTION, - headers=HEADER, - data=DataMatcher({'action-instance': ACTION}), - auth=AuthMatcher() - ) - - def test_delete_action(self): - method = getattr(self.manager, 'delete_action') - self._test_single_request_operation( - 'delete', - method, - TENANT_ID, - ACTION, - url=URL_ACTION, - headers=HEADER, - data=None, - auth=AuthMatcher() - ) - - def test_create_classifier(self): - method = getattr(self.manager, 'create_classifier') - self._test_multi_request_operations( - 'put', - method, - TENANT_ID, - CLASSIFIER, - url=URL_CLASSIFIER, - headers=HEADER, - data=DataMatcher({'classifier-instance': CLASSIFIER}), - auth=AuthMatcher() - ) - - def test_delete_classifier(self): - method = getattr(self.manager, 'delete_classifier') - self._test_single_request_operation( - 'delete', - method, - TENANT_ID, - CLASSIFIER, - url=URL_CLASSIFIER, - headers=HEADER, - data=None, - auth=AuthMatcher() - ) - - def test_create_update_l3_context(self): - method = getattr(self.manager, 'create_update_l3_context') - self._test_multi_request_operations( - 'put', - method, - TENANT_ID, - L3CTX, - url=URL_L3CTX, - headers=HEADER, - data=DataMatcher({'l3-context': L3CTX}), - auth=AuthMatcher() - ) - - def test_delete_l3_context(self): - method = getattr(self.manager, 'delete_l3_context') - self._test_single_request_operation( - 'delete', - method, - TENANT_ID, - L3CTX, - url=URL_L3CTX, - headers=HEADER, - data=None, - auth=AuthMatcher() - ) - - def test_create_update_l2_bridge_domain(self): - method = getattr(self.manager, 'create_update_l2_bridge_domain') - self._test_multi_request_operations( - 'put', - method, - TENANT_ID, - L2BD, - url=URL_L2BD, - headers=HEADER, - data=DataMatcher({'l2-bridge-domain': L2BD}), - auth=AuthMatcher() - ) - - def test_delete_l2_bridge_domain(self): - method = getattr(self.manager, 'delete_l2_bridge_domain') - self._test_single_request_operation( - 'delete', - method, - TENANT_ID, - L2BD, - url=URL_L2BD, - headers=HEADER, - data=None, - auth=AuthMatcher() - ) - - def test_create_update_l2_flood_domain(self): - method = getattr(self.manager, 'create_update_l2_flood_domain') - self._test_multi_request_operations( - 'put', - method, - TENANT_ID, - L2FD, - url=URL_L2FD, - headers=HEADER, - data=DataMatcher({'l2-flood-domain': L2FD}), - auth=AuthMatcher() - ) - - def test_delete_l2_flood_domain(self): - method = getattr(self.manager, 'delete_l2_flood_domain') - self._test_single_request_operation( - 'delete', - method, - TENANT_ID, - L2FD, - url=URL_L2FD, - headers=HEADER, - data=None, - auth=AuthMatcher() - ) - - def test_create_update_endpoint_group(self): - method = getattr(self.manager, 'create_update_endpoint_group') - self._test_multi_request_operations( - 'put', - method, - TENANT_ID, - EPG, - url=URL_EPG, - headers=HEADER, - data=DataMatcher({'endpoint-group': EPG}), - auth=AuthMatcher() - ) - - def test_delete_endpoint_group(self): - method = getattr(self.manager, 'delete_endpoint_group') - self._test_single_request_operation( - 'delete', - method, - TENANT_ID, - EPG, - url=URL_EPG, - headers=HEADER, - data=None, - auth=AuthMatcher() - ) - - def test_create_update_subnet(self): - method = getattr(self.manager, 'create_update_subnet') - self._test_multi_request_operations( - 'put', - method, - TENANT_ID, - SUBNET, - url=URL_SUBNET, - headers=HEADER, - data=DataMatcher({'subnet': SUBNET}), - auth=AuthMatcher() - ) - - def test_delete_subnet(self): - method = getattr(self.manager, 'delete_subnet') - self._test_single_request_operation( - 'delete', - method, - TENANT_ID, - SUBNET, - url=URL_SUBNET, - headers=HEADER, - data=None, - auth=AuthMatcher() - ) - - def test_create_update_contract(self): - method = getattr(self.manager, 'create_update_contract') - self._test_single_request_operation( - 'put', - method, - TENANT_ID, - CONTRACT, - url=URL_CONTRACT, - headers=HEADER, - data=DataMatcher({'contract': CONTRACT}), - auth=AuthMatcher() - ) diff --git a/gbpservice/neutron/tests/unit/services/grouppolicy/test_odl_mapping.py b/gbpservice/neutron/tests/unit/services/grouppolicy/test_odl_mapping.py deleted file mode 100644 index 4522a4b2c..000000000 --- a/gbpservice/neutron/tests/unit/services/grouppolicy/test_odl_mapping.py +++ /dev/null @@ -1,1181 +0,0 @@ -# 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. - -import mock - -from gbpservice.neutron.services.grouppolicy.common import constants -from gbpservice.neutron.services.grouppolicy import config -from gbpservice.neutron.services.grouppolicy.drivers.odl import odl_manager -from gbpservice.neutron.services.grouppolicy.drivers.odl import odl_mapping -from gbpservice.neutron.services.grouppolicy.drivers import resource_mapping -from gbpservice.neutron.services.grouppolicy import plugin as g_plugin -from gbpservice.neutron.tests.unit.services.grouppolicy import ( - test_grouppolicy_plugin as test_gp_plugin) -from neutron.plugins.ml2 import plugin as ml2_plugin -from neutron.tests.unit.plugins.ml2 import test_plugin - -TENANT_ID = 'aaaabbbbccccaaaabbbbccccaaaabbbb' -TENANT_UUID = 'aaaabbbb-cccc-aaaa-bbbb-ccccaaaabbbb' - -ACTION_1_ID = '1111aaaa-1111-1111-1111-1111bbbb1111' -ACTION_1_NAME = 'fake_name_for_action_1' -ACTION_1_DESC = 'Fake policy action 1' -ACTION_1_TYPE = constants.GP_ACTION_ALLOW - -ACTION_2_ID = '1111aaaa-1111-2222-1111-1111bbbb1111' -ACTION_2_NAME = 'fake_name_for_action_2' -ACTION_2_DESC = 'Fake policy action 2' -ACTION_2_TYPE = constants.GP_ACTION_ALLOW - -# ACTION_3 is used for negative testing as this action -# is not supported at the moment -ACTION_3_ID = '1111aaaa-1111-3333-1111-1111bbbb1111' -ACTION_3_NAME = 'fake_name_for_action_3' -ACTION_3_DESC = 'Fake policy action 3' -ACTION_3_TYPE = constants.GP_ACTION_REDIRECT - -CLASSIFIER_1_ID = '1111aaaa-2222-1111-1111-1111bbbb1111' -CLASSIFIER_1_NAME = 'fake_name_for_classifier_1' -CLASSIFIER_1_DESC = 'Fake policy classifier 1' -CLASSIFIER_1_PROTOCOL = 'tcp' -CLASSIFIER_1_PORT = '321' -CLASSIFIER_1_DIRECTION = 'bi' -CLASSIFIER_1_DEFINITION_ID = '4250ab32-e8b8-445a-aebb-e1bd2cdd291f' - -CLASSIFIER_2_ID = '1111aaaa-2222-2222-1111-1111bbbb1111' -CLASSIFIER_2_NAME = 'fake_name_for_classifier_2' -CLASSIFIER_2_DESC = 'Fake policy classifier 2' -CLASSIFIER_2_PROTOCOL = 'tcp' -CLASSIFIER_2_PORT = '123' -CLASSIFIER_2_DIRECTION = 'in' -CLASSIFIER_2_DEFINITION_ID = '4250ab32-e8b8-445a-aebb-e1bd2cdd291f' - -CLASSIFIER_3_ID = '1111aaaa-2222-3333-1111-1111bbbb1111' -CLASSIFIER_3_NAME = 'fake_name_for_classifier_3' -CLASSIFIER_3_DESC = 'Fake policy classifier 3' -CLASSIFIER_3_PROTOCOL = 'icmp' -CLASSIFIER_3_DIRECTION = 'bi' -CLASSIFIER_3_DEFINITION_ID = '79c6fdb2-1e1a-4832-af57-c65baf5c2335' - -RULE_1_ID = '1111aaaa-3333-1111-1111-1111bbbb1111' -RULE_1_NAME = 'fake_name_for_policy_rule_1' -RULE_1_DESC = 'Fake policy rule 1' - -RULE_2_ID = '1111aaaa-3333-2222-1111-1111bbbb1111' -RULE_2_NAME = 'fake_name_for_policy_rule_2' -RULE_2_DESC = 'Fake policy rule 2' - -RULE_3_ID = '1111aaaa-3333-3333-1111-1111bbbb1111' -RULE_3_NAME = 'fake_name_for_policy_rule_3' -RULE_3_DESC = 'Fake policy rule 3' - -RULE_SET_1_ID = '1111aaaa-4444-1111-1111-1111bbbb1111' -RULE_SET_1_NAME = 'fake_name_for_rule_set_1' -RULE_SET_1_DESC = 'Fake policy rule set 1' - -RULE_SET_2_ID = '1111aaaa-4444-2222-1111-1111bbbb1111' -RULE_SET_2_NAME = 'fake_name_for_rule_set_2' -RULE_SET_2_DESC = 'Fake policy rule set 2' - -L3P_ID = '2222bbbb-1111-1111-1111-1111cccc1111' -L3P_NAME = 'fake_name_for_l3_policy' -L3P_DESC = 'Fake L3 policy' - -NETWORK_ID = '2222bbbb-2222-1111-1111-1111cccc1111' -NETWORK_NAME = 'fake_name_for_network' - -L2P_ID = '2222bbbb-3333-1111-1111-1111cccc1111' -L2P_NAME = 'fake_name_for_l2_policy' -L2P_DESC = 'Fake L2 policy' - -SUBNET_ID = '2222bbbb-4444-1111-1111-1111cccc1111' -SUBNET_CIDR = '10.10.1.0/24' -SUBNET_GATEWAY_IP = '10.10.1.1' - -GROUP_ID = '2222bbbb-5555-1111-1111-1111cccc1111' -GROUP_NAME = 'fake_name_for_ptg' -GROUP_DESC = 'Fake PTG' - -PORT_ID = '3333cccc-1111-1111-1111-1111dddd1111' -PORT_MAC = 'fa:33:33:11:11:11' -PORT_IP = '10.10.1.11' -NEUTRON_PORT_ID = 'tap3333cccc-11' - -POLICY_TARGET_ID = '3333cccc-2222-1111-1111-1111dddd1111' -POLICY_TARGET_NAME = 'fake_name_for_policy_target' -POLICY_TARGET_DESC = 'Fake Policy Target' - -FAKE_CONTEXT = 'fake_context' -FAKE_PLUGIN_CONTEXT = 'fake_plugin_context' - - -class FakeCorePlugin(object): - """ A fake plugin to simulate the ML2 plugin - - This plugin provides a minimum set of methods that - will be used during testing - """ - - def __init__(self): - self._networks = {} - self._subnets = {} - self._ports = {} - - def add_network(self, net_id, net): - self._networks[net_id] = net - - def get_network(self, plugin_context, net_id): - return self._networks[net_id] - - def add_subnet(self, subnet_id, subnet): - self._subnets[subnet_id] = subnet - - def get_subnet(self, plugin_context, subnet_id): - return self._subnets[subnet_id] - - def add_port(self, port_id, port): - self._ports[port_id] = port - - def get_port(self, plugin_context, port_id): - return self._ports[port_id] - - -class FakeGBPPlugin(object): - """ A fake plugin to simulate the GBP plugin - - This plugin provides a minimum set of methods that - will be used during testing - """ - - def __init__(self): - self._l3ps = {} - self._l2ps = {} - self._ptgs = {} - self._pts = {} - self._classifiers = {} - self._actions = {} - self._rules = {} - self._rule_sets = {} - - def add_l3_policy(self, l3p_id, l3p): - self._l3ps[l3p_id] = l3p - - def get_l3_policy(self, plugin_context, l3p_id): - return self._l3ps[l3p_id] - - def add_l2_policy(self, l2p_id, l2p): - self._l2ps[l2p_id] = l2p - - def get_l2_policy(self, plugin_context, l2p_id): - return self._l2ps[l2p_id] - - def add_policy_target_group(self, ptg_id, ptg): - self._ptgs[ptg_id] = ptg - - def get_policy_target_group(self, plugin_context, ptg_id): - return self._ptgs[ptg_id] - - def add_policy_target(self, pt_id, pt): - self._pts[pt_id] = pt - - def get_policy_target(self, plugin_context, pt_id): - return self._pts[pt_id] - - def add_policy_classifier(self, classifier_id, classifier): - self._classifiers[classifier_id] = classifier - - def get_policy_classifier(self, plugin_context, classifier_id): - return self._classifiers[classifier_id] - - def add_policy_action(self, action_id, action): - self._actions[action_id] = action - - def get_policy_action(self, plugin_context, action_id): - return self._actions[action_id] - - def add_policy_rule(self, rule_id, rule): - self._rules[rule_id] = rule - - def get_policy_rule(self, plugin_context, rule_id): - return self._rules[rule_id] - - def add_policy_rule_set(self, rule_set_id, rule_set): - self._rule_sets[rule_set_id] = rule_set - - def get_policy_rule_set(self, plugin_context, rule_set_id): - return self._rule_sets[rule_set_id] - - -class OdlMappingTestCase( - test_gp_plugin.GroupPolicyPluginTestCase): - """ Base test case for ODL mapping driver testing - - Set up the common testing environment - """ - - def setUp(self): - config.cfg.CONF.set_override('policy_drivers', - ['implicit_policy', 'odl'], - group='group_policy') - super(OdlMappingTestCase, self).setUp( - core_plugin=test_plugin.PLUGIN_NAME) - - self.fake_core_plugin = FakeCorePlugin() - self.fake_gbp_plugin = FakeGBPPlugin() - self.driver = odl_mapping.OdlMappingDriver.get_initialized_instance() - - self.fake_gbp_plugin.add_policy_action( - ACTION_1_ID, - { - 'id': ACTION_1_ID, - 'tenant_id': TENANT_ID, - 'name': ACTION_1_NAME, - 'description': ACTION_1_DESC, - 'action_type': ACTION_1_TYPE, - } - ) - - self.fake_gbp_plugin.add_policy_action( - ACTION_2_ID, - { - 'id': ACTION_2_ID, - 'tenant_id': TENANT_ID, - 'name': ACTION_2_NAME, - 'description': ACTION_2_DESC, - 'action_type': ACTION_2_TYPE, - } - ) - - self.fake_gbp_plugin.add_policy_action( - ACTION_3_ID, - { - 'id': ACTION_3_ID, - 'tenant_id': TENANT_ID, - 'name': ACTION_3_NAME, - 'description': ACTION_3_DESC, - 'action_type': ACTION_3_TYPE, - } - ) - - self.fake_gbp_plugin.add_policy_classifier( - CLASSIFIER_1_ID, - { - 'id': CLASSIFIER_1_ID, - 'tenant_id': TENANT_ID, - 'name': CLASSIFIER_1_NAME, - 'description': CLASSIFIER_1_DESC, - 'protocol': CLASSIFIER_1_PROTOCOL, - 'port_range': CLASSIFIER_1_PORT, - 'direction': CLASSIFIER_1_DIRECTION - } - ) - - self.fake_gbp_plugin.add_policy_classifier( - CLASSIFIER_2_ID, - { - 'id': CLASSIFIER_2_ID, - 'tenant_id': TENANT_ID, - 'name': CLASSIFIER_2_NAME, - 'description': CLASSIFIER_2_DESC, - 'protocol': CLASSIFIER_2_PROTOCOL, - 'port_range': CLASSIFIER_2_PORT, - 'direction': CLASSIFIER_2_DIRECTION - } - ) - - self.fake_gbp_plugin.add_policy_classifier( - CLASSIFIER_3_ID, - { - 'id': CLASSIFIER_3_ID, - 'tenant_id': TENANT_ID, - 'name': CLASSIFIER_3_NAME, - 'description': CLASSIFIER_3_DESC, - 'protocol': CLASSIFIER_3_PROTOCOL, - 'direction': CLASSIFIER_3_DIRECTION - } - ) - - self.fake_gbp_plugin.add_policy_rule( - RULE_1_ID, - { - 'id': RULE_1_ID, - 'tenant_id': TENANT_ID, - 'name': RULE_1_NAME, - 'description': RULE_1_DESC, - 'policy_classifier_id': CLASSIFIER_1_ID, - 'policy_actions': [ACTION_1_ID] - } - ) - - self.fake_gbp_plugin.add_policy_rule( - RULE_2_ID, - { - 'id': RULE_2_ID, - 'tenant_id': TENANT_ID, - 'name': RULE_2_NAME, - 'description': RULE_2_DESC, - 'policy_classifier_id': CLASSIFIER_2_ID, - 'policy_actions': [ACTION_2_ID] - } - ) - - self.fake_gbp_plugin.add_policy_rule( - RULE_3_ID, - { - 'id': RULE_3_ID, - 'tenant_id': TENANT_ID, - 'name': RULE_3_NAME, - 'description': RULE_3_DESC, - 'policy_classifier_id': CLASSIFIER_1_ID, - 'policy_actions': [ACTION_1_ID, ACTION_2_ID] - } - ) - - self.fake_gbp_plugin.add_policy_rule_set( - RULE_SET_1_ID, - { - 'id': RULE_SET_1_ID, - 'tenant_id': TENANT_ID, - 'name': RULE_SET_1_NAME, - 'description': RULE_SET_1_DESC, - 'policy_rules': [RULE_1_ID] - } - ) - - self.fake_gbp_plugin.add_policy_rule_set( - RULE_SET_2_ID, - { - 'id': RULE_SET_2_ID, - 'tenant_id': TENANT_ID, - 'name': RULE_SET_2_NAME, - 'description': RULE_SET_2_DESC, - 'policy_rules': [RULE_2_ID] - } - ) - - self.fake_gbp_plugin.add_l3_policy( - L3P_ID, - { - 'id': L3P_ID, - 'tenant_id': TENANT_ID, - 'name': L3P_NAME, - 'description': L3P_DESC - } - ) - - self.fake_core_plugin.add_network( - NETWORK_ID, - { - 'id': NETWORK_ID, - 'name': NETWORK_NAME - } - ) - - self.fake_gbp_plugin.add_l2_policy( - L2P_ID, - { - 'id': L2P_ID, - 'tenant_id': TENANT_ID, - 'name': L2P_NAME, - 'description': L2P_DESC, - 'l3_policy_id': L3P_ID, - 'network_id': NETWORK_ID - - } - ) - - self.fake_core_plugin.add_subnet( - SUBNET_ID, - { - 'id': SUBNET_ID, - 'cidr': SUBNET_CIDR, - 'network_id': NETWORK_ID, - 'gateway_ip': SUBNET_GATEWAY_IP - } - ) - - self.fake_gbp_plugin.add_policy_target_group( - GROUP_ID, - { - 'id': GROUP_ID, - 'tenant_id': TENANT_ID, - 'name': GROUP_NAME, - 'description': GROUP_DESC, - 'l2_policy_id': L2P_ID, - 'subnets': [SUBNET_ID], - 'provided_policy_rule_sets': [RULE_SET_1_ID], - 'consumed_policy_rule_sets': [RULE_SET_2_ID] - } - ) - - self.fake_core_plugin.add_port( - PORT_ID, - { - 'id': PORT_ID, - 'mac_address': PORT_MAC, - 'fixed_ips': [ - { - 'ip_address': PORT_IP, - 'subnet_id': SUBNET_ID - } - ], - 'network_id': NETWORK_ID - } - ) - - self.fake_gbp_plugin.add_policy_target( - POLICY_TARGET_ID, - { - 'id': POLICY_TARGET_ID, - 'tenant_id': TENANT_ID, - 'name': POLICY_TARGET_NAME, - 'description': POLICY_TARGET_DESC, - 'policy_target_group_id': GROUP_ID, - 'port_id': PORT_ID - } - ) - - -class ExternalSegmentTestCase(OdlMappingTestCase): - """ Test case related with external segment operations - - Currently, ODL cannot handle any external segment operations, - and should throw an exception in these cases. - """ - - def setUp(self): - super(ExternalSegmentTestCase, self).setUp() - - def _test_exception_handling(self, method): - func = getattr(self.driver, method) - self.assertRaises( - odl_mapping.ExternalSegmentNotSupportedOnOdlDriver, - func, - FAKE_CONTEXT - ) - - def test_create_external_segment_precommit(self): - self._test_exception_handling('create_external_segment_precommit') - - def test_update_external_segment_precommit(self): - self._test_exception_handling('update_external_segment_precommit') - - def test_delete_external_segment_precommit(self): - self._test_exception_handling('delete_external_segment_precommit') - - def test_create_external_policy_precommit(self): - self._test_exception_handling('create_external_policy_precommit') - - def test_update_external_policy_precommit(self): - self._test_exception_handling('update_external_policy_precommit') - - def test_delete_external_policy_precommit(self): - self._test_exception_handling('delete_external_policy_precommit') - - def test_create_nat_pool_precommit(self): - self._test_exception_handling('create_nat_pool_precommit') - - def test_update_nat_pool_precommit(self): - self._test_exception_handling('update_nat_pool_precommit') - - def test_delete_nat_pool_precommit(self): - self._test_exception_handling('delete_nat_pool_precommit') - - -class PolicyTargetTestCase(OdlMappingTestCase): - """ Test case for policy target operations - """ - - def setUp(self): - super(PolicyTargetTestCase, self).setUp() - self.context = mock.Mock( - current=self.fake_gbp_plugin.get_policy_target( - FAKE_CONTEXT, - POLICY_TARGET_ID - ), - _plugin_context=FAKE_PLUGIN_CONTEXT, - _plugin=self.fake_gbp_plugin - ) - - @mock.patch.object(g_plugin.GroupPolicyPlugin, 'get_l2_policy') - @mock.patch.object(g_plugin.GroupPolicyPlugin, 'get_policy_target_group') - @mock.patch.object(ml2_plugin.Ml2Plugin, 'get_port') - @mock.patch.object(odl_manager.OdlManager, 'register_endpoints') - @mock.patch.object(resource_mapping.ResourceMappingDriver, - 'create_policy_target_postcommit') - def test_create_policy_target_postcommit( - self, - mock_create_policy_target_postcommit, - mock_register_endpoints, - mock_get_port, - mock_get_policy_target_group, - mock_get_l2_policy): - - # core_plugin and gbp_plugin are mocked and simulated by - # the fake core plugin and fake gbp plugin - mock_get_port.side_effect = self.fake_core_plugin.get_port - mock_get_policy_target_group.side_effect = ( - self.fake_gbp_plugin.get_policy_target_group) - mock_get_l2_policy.side_effect = self.fake_gbp_plugin.get_l2_policy - ep = { - "endpoint-group": GROUP_ID, - "l2-context": L2P_ID, - "l3-address": [ - { - "ip-address": PORT_IP, - "l3-context": L3P_ID - } - ], - "mac-address": PORT_MAC, - "port-name": NEUTRON_PORT_ID, - "tenant": TENANT_UUID - } - - self.driver.create_policy_target_postcommit(self.context) - mock_create_policy_target_postcommit.assert_called_once_with( - self.context - ) - mock_register_endpoints.assert_called_once_with([ep]) - - def test_update_policy_target_precommit(self): - self.assertRaises( - odl_mapping.UpdatePTNotSupportedOnOdlDriver, - getattr(self.driver, 'update_policy_target_precommit'), - self.context - ) - - @mock.patch.object(g_plugin.GroupPolicyPlugin, 'get_l2_policy') - @mock.patch.object(g_plugin.GroupPolicyPlugin, 'get_policy_target_group') - @mock.patch.object(ml2_plugin.Ml2Plugin, 'get_port') - @mock.patch.object(odl_manager.OdlManager, 'unregister_endpoints') - @mock.patch.object(resource_mapping.ResourceMappingDriver, - 'delete_policy_target_postcommit') - def test_delete_policy_target_postcommit( - self, - mock_delete_policy_target_postcommit, - mock_unregister_endpoints, - mock_get_port, - mock_get_policy_target_group, - mock_get_l2_policy): - - # core_plugin and gbp_plugin are mocked and simulated by - # the fake core plugin and fake gbp plugin - mock_get_port.side_effect = self.fake_core_plugin.get_port - mock_get_policy_target_group.side_effect = ( - self.fake_gbp_plugin.get_policy_target_group) - mock_get_l2_policy.side_effect = self.fake_gbp_plugin.get_l2_policy - ep = { - "l2": [ - { - "l2-context": L2P_ID, - "mac-address": PORT_MAC - } - ], - "l3": [ - { - "ip-address": PORT_IP, - "l3-context": L3P_ID - } - ], - } - - self.driver.delete_policy_target_postcommit(self.context) - mock_delete_policy_target_postcommit.assert_called_once_with( - self.context - ) - mock_unregister_endpoints.assert_called_once_with([ep]) - - -class L3PolicyTestCase(OdlMappingTestCase): - """ Test case for L3 policy operations - """ - - def setUp(self): - super(L3PolicyTestCase, self).setUp() - self.context = mock.Mock( - current=self.fake_gbp_plugin.get_l3_policy( - FAKE_CONTEXT, - L3P_ID - ), - _plugin_context=FAKE_PLUGIN_CONTEXT, - _plugin=self.fake_gbp_plugin - ) - - @mock.patch.object(odl_manager.OdlManager, 'create_update_l3_context') - def test_create_l3_policy_postcommit( - self, - mock_create_update_l3_context): - - l3ctx = { - "id": L3P_ID, - "name": L3P_NAME, - "description": L3P_DESC - } - - self.driver.create_l3_policy_postcommit(self.context) - mock_create_update_l3_context.assert_called_once_with( - TENANT_UUID, l3ctx) - - def test_update_l3_policy_precommit(self): - self.assertRaises( - odl_mapping.UpdateL3PolicyNotSupportedOnOdlDriver, - getattr(self.driver, 'update_l3_policy_precommit'), - self.context - ) - - @mock.patch.object(odl_manager.OdlManager, 'delete_l3_context') - def test_delete_l3_policy_postcommit( - self, - mock_delete_l3_context): - - l3ctx = { - "id": L3P_ID, - } - - self.driver.delete_l3_policy_postcommit(self.context) - mock_delete_l3_context.assert_called_once_with(TENANT_UUID, l3ctx) - - -class L2PolicyTestCase(OdlMappingTestCase): - """ Test case for L2 policy operations - """ - def setUp(self): - super(L2PolicyTestCase, self).setUp() - self.context = mock.Mock( - current=self.fake_gbp_plugin.get_l2_policy( - FAKE_CONTEXT, - L2P_ID - ), - _plugin_context=FAKE_PLUGIN_CONTEXT, - _plugin=self.fake_gbp_plugin - ) - - @mock.patch.object(ml2_plugin.Ml2Plugin, 'get_network') - @mock.patch.object(odl_manager.OdlManager, - 'create_update_l2_flood_domain') - @mock.patch.object(odl_manager.OdlManager, - 'create_update_l2_bridge_domain') - @mock.patch.object(resource_mapping.ResourceMappingDriver, - 'create_l2_policy_postcommit') - def test_create_l2_policy_postcommit( - self, - mock_create_l2_policy_postcommit, - mock_create_update_l2_bridge_domain, - mock_create_update_l2_flood_domain, - mock_get_network): - - # core_plugin is mocked and simulated by the fake core plugin - mock_get_network.side_effect = self.fake_core_plugin.get_network - l2bd = { - "id": L2P_ID, - "name": L2P_NAME, - "description": L2P_DESC, - "parent": L3P_ID - } - l2fd = { - "id": NETWORK_ID, - "name": NETWORK_NAME, - "parent": L2P_ID - } - - self.driver.create_l2_policy_postcommit(self.context) - mock_create_l2_policy_postcommit.assert_called_once_with(self.context) - mock_create_update_l2_bridge_domain.assert_called_once_with( - TENANT_UUID, l2bd) - mock_create_update_l2_flood_domain.assert_called_with(TENANT_UUID, - l2fd) - - def test_update_l2_policy_precommit(self): - self.assertRaises( - odl_mapping.UpdateL2PolicyNotSupportedOnOdlDriver, - getattr(self.driver, 'update_l2_policy_precommit'), - self.context - ) - - @mock.patch.object(odl_manager.OdlManager, 'delete_l2_flood_domain') - @mock.patch.object(odl_manager.OdlManager, 'delete_l2_bridge_domain') - @mock.patch.object(resource_mapping.ResourceMappingDriver, - 'delete_l2_policy_postcommit') - def test_delete_l2_policy_postcommit( - self, - mock_delete_l2_policy_postcommit, - mock_delete_l2_bridge_domain, - mock_delete_l2_flood_domain): - - l2bd = { - "id": L2P_ID, - } - l2fd = { - "id": NETWORK_ID, - } - - self.driver.delete_l2_policy_postcommit(self.context) - mock_delete_l2_policy_postcommit.assert_called_once_with(self.context) - mock_delete_l2_bridge_domain.assert_called_once_with(TENANT_UUID, - l2bd) - mock_delete_l2_flood_domain.assert_called_with(TENANT_UUID, l2fd) - - -class PolicyTargetGroupTestCase(OdlMappingTestCase): - """ Test case for policy target group operations - """ - - def setUp(self): - super(PolicyTargetGroupTestCase, self).setUp() - self.context = mock.Mock( - current=self.fake_gbp_plugin.get_policy_target_group( - FAKE_CONTEXT, - GROUP_ID - ), - _plugin_context=FAKE_PLUGIN_CONTEXT, - _plugin=self.fake_gbp_plugin - ) - - @mock.patch.object(g_plugin.GroupPolicyPlugin, 'get_policy_rule_set') - @mock.patch.object(ml2_plugin.Ml2Plugin, 'get_subnet') - @mock.patch.object(odl_manager.OdlManager, 'create_update_subnet') - @mock.patch.object(odl_manager.OdlManager, 'create_update_endpoint_group') - @mock.patch.object(resource_mapping.ResourceMappingDriver, - 'create_policy_target_group_postcommit') - def test_create_policy_target_group_postcommit( - self, - mock_create_policy_target_group_postcommit, - mock_create_update_endpoint_group, - mock_create_update_subnet, - mock_get_subnet, - mock_get_policy_rule_set): - - # core_plugin and gbp_plugin are mocked and simulated by - # the fake core plugin and fake gbp plugin - mock_get_subnet.side_effect = self.fake_core_plugin.get_subnet - mock_get_policy_rule_set.side_effect = (self.fake_gbp_plugin. - get_policy_rule_set) - - epg = { - "id": GROUP_ID, - "name": GROUP_NAME, - "description": GROUP_DESC, - "network-domain": SUBNET_ID, - "provider-named-selector": [ - { - "name": RULE_SET_1_NAME, - "contract": RULE_SET_1_ID - } - ], - "consumer-named-selector": [ - { - "name": RULE_SET_2_NAME, - "contract": RULE_SET_2_ID - } - ] - } - odl_subnet = { - "id": SUBNET_ID, - "ip-prefix": SUBNET_CIDR, - "parent": NETWORK_ID, - "virtual-router-ip": SUBNET_GATEWAY_IP - } - - self.driver.create_policy_target_group_postcommit(self.context) - mock_create_policy_target_group_postcommit.assert_called_once_with( - self.context) - mock_create_update_endpoint_group.assert_called_once_with(TENANT_UUID, - epg) - mock_create_update_subnet.assert_called_once_with(TENANT_UUID, - odl_subnet) - - def test_update_policy_target_group_precommit(self): - self.assertRaises( - odl_mapping.UpdatePTGNotSupportedOnOdlDriver, - getattr(self.driver, 'update_policy_target_group_precommit'), - self.context - ) - - @mock.patch.object(odl_mapping.OdlMappingDriver, '_cleanup_subnet') - @mock.patch.object(odl_manager.OdlManager, 'delete_endpoint_group') - @mock.patch.object(odl_manager.OdlManager, 'delete_subnet') - def test_delete_policy_target_group_postcommit( - self, - mock_delete_subnet, - mock_delete_endpoint_group, - mock__cleanup_subnet): - - odl_subnet = { - "id": SUBNET_ID - } - epg = { - "id": GROUP_ID - } - - self.driver.delete_policy_target_group_postcommit(self.context) - mock_delete_subnet.assert_called_once_with(TENANT_UUID, odl_subnet) - mock_delete_endpoint_group.assert_called_once_with(TENANT_UUID, epg) - mock__cleanup_subnet.assert_called_once_with( - self.context._plugin_context, SUBNET_ID, None) - - -class PolicyActionTestCase(OdlMappingTestCase): - """ Test case for policy action operations - """ - - def setUp(self): - super(PolicyActionTestCase, self).setUp() - self.context_1 = mock.Mock( - current=self.fake_gbp_plugin.get_policy_action( - FAKE_CONTEXT, - ACTION_1_ID - ), - _plugin_context=FAKE_PLUGIN_CONTEXT, - _plugin=self.fake_gbp_plugin - ) - self.context_3 = mock.Mock( - current=self.fake_gbp_plugin.get_policy_action( - FAKE_CONTEXT, - ACTION_3_ID - ), - _plugin_context=FAKE_PLUGIN_CONTEXT, - _plugin=self.fake_gbp_plugin - ) - - def test_create_policy_action_precommit(self): - # No exception should be raised - self.driver.create_policy_action_precommit(self.context_1) - - # Exception should be raised only when ACTION is redirect - self.assertRaises( - odl_mapping.RedirectActionNotSupportedOnOdlDriver, - getattr(self.driver, 'create_policy_action_precommit'), - self.context_3 - ) - - @mock.patch.object(resource_mapping.ResourceMappingDriver, - 'create_policy_action_postcommit') - def test_create_policy_action_postcommit( - self, - mock_create_policy_action_postcommit): - - # Exception should be raised only when ACTION is redirect - self.driver.create_policy_action_postcommit(self.context_1) - mock_create_policy_action_postcommit.assert_called_once_with( - self.context_1) - self.assertRaises( - odl_mapping.OnlyAllowActionSupportedOnOdlDriver, - getattr(self.driver, 'create_policy_action_postcommit'), - self.context_3 - ) - - def test_update_policy_action_precommit(self): - self.assertRaises( - odl_mapping.UpdatePolicyActionNotSupportedOnOdlDriver, - getattr(self.driver, 'update_policy_action_precommit'), - self.context_1 - ) - - @mock.patch.object(resource_mapping.ResourceMappingDriver, - 'delete_policy_action_postcommit') - def test_delete_policy_action_postcommit( - self, - mock_delete_policy_action_postcommit): - self.driver.delete_policy_action_postcommit(self.context_1) - mock_delete_policy_action_postcommit.assert_called_once_with( - self.context_1) - - -class PolicyClassifierTestCase(OdlMappingTestCase): - """ Test case for policy classifier operations - """ - - def setUp(self): - super(PolicyClassifierTestCase, self).setUp() - self.context_1 = mock.Mock( - current=self.fake_gbp_plugin.get_policy_classifier( - FAKE_CONTEXT, - CLASSIFIER_1_ID - ), - _plugin_context=FAKE_PLUGIN_CONTEXT, - _plugin=self.fake_gbp_plugin - ) - self.context_3 = mock.Mock( - current=self.fake_gbp_plugin.get_policy_classifier( - FAKE_CONTEXT, - CLASSIFIER_3_ID - ), - _plugin_context=FAKE_PLUGIN_CONTEXT, - _plugin=self.fake_gbp_plugin - ) - - @mock.patch.object(odl_manager.OdlManager, 'create_classifier') - def test_create_policy_classifier_postcommit( - self, - mock_create_classifier): - - # Ensure two classifiers are created in ODL for TCP - classifier_instance_1_dest = { - "classifier-definition-id": CLASSIFIER_1_DEFINITION_ID, - "name": CLASSIFIER_1_NAME + "-destport", - "parameter-value": [ - { - "name": "type", - "string-value": CLASSIFIER_1_PROTOCOL - }, - { - "name": "destport", - "int-value": CLASSIFIER_1_PORT - } - ] - } - classifier_instance_1_source = { - "classifier-definition-id": CLASSIFIER_1_DEFINITION_ID, - "name": CLASSIFIER_1_NAME + "-sourceport", - "parameter-value": [ - { - "name": "type", - "string-value": CLASSIFIER_1_PROTOCOL - }, - { - "name": "sourceport", - "int-value": CLASSIFIER_1_PORT - } - ] - } - self.driver.create_policy_classifier_postcommit(self.context_1) - mock_create_classifier.assert_any_call(TENANT_UUID, - classifier_instance_1_source) - mock_create_classifier.assert_any_call(TENANT_UUID, - classifier_instance_1_dest) - mock_create_classifier.reset_mock() - - # only one classifier for ICMP - classifier_instance_3 = { - "classifier-definition-id": CLASSIFIER_3_DEFINITION_ID, - "name": CLASSIFIER_3_NAME, - "parameter-value": [ - { - "name": "proto", - "int-value": 1 - } - ] - } - self.driver.create_policy_classifier_postcommit(self.context_3) - mock_create_classifier.assert_called_once_with(TENANT_UUID, - classifier_instance_3) - - def test_update_policy_classifier_precommit(self): - self.assertRaises( - odl_mapping.UpdateClassifierNotSupportedOnOdlDriver, - getattr(self.driver, 'update_policy_classifier_precommit'), - self.context_1 - ) - - @mock.patch.object(odl_manager.OdlManager, 'delete_classifier') - def test_delete_policy_classifier_postcommit( - self, - mock_delete_classifier): - - # Ensure both classifiers are deleted for TCP/UDP - classifier_instance_1_dest = { - "name": CLASSIFIER_1_NAME + "-destport" - } - classifier_instance_1_source = { - "name": CLASSIFIER_1_NAME + "-sourceport" - } - self.driver.delete_policy_classifier_postcommit(self.context_1) - mock_delete_classifier.assert_any_call(TENANT_UUID, - classifier_instance_1_source) - mock_delete_classifier.assert_any_call(TENANT_UUID, - classifier_instance_1_dest) - mock_delete_classifier.reset_mock() - - # Ensure only one classifier is deleted for ICMP - classifier_instance_3 = { - "name": CLASSIFIER_3_NAME, - } - self.driver.delete_policy_classifier_postcommit(self.context_3) - mock_delete_classifier.assert_called_once_with(TENANT_UUID, - classifier_instance_3) - - -class PolicyRuleTestCase(OdlMappingTestCase): - """ Test case for policy rule operations - """ - def setUp(self): - super(PolicyRuleTestCase, self).setUp() - self.context_1 = mock.Mock( - current=self.fake_gbp_plugin.get_policy_rule( - FAKE_CONTEXT, - RULE_1_ID - ), - _plugin_context=FAKE_PLUGIN_CONTEXT, - _plugin=self.fake_gbp_plugin - ) - self.context_3 = mock.Mock( - current=self.fake_gbp_plugin.get_policy_rule( - FAKE_CONTEXT, - RULE_3_ID - ), - _plugin_context=FAKE_PLUGIN_CONTEXT, - _plugin=self.fake_gbp_plugin - ) - - def test_create_policy_rule_precommit(self): - # No exception should be raised - self.driver.create_policy_rule_precommit(self.context_1) - - # Ensure exception be raised only when multiple actions appear - self.assertRaises( - odl_mapping.ExactlyOneActionPerRuleIsSupportedOnOdlDriver, - getattr(self.driver, 'create_policy_rule_precommit'), - self.context_3 - ) - - def test_update_policy_rule_precommit(self): - self.assertRaises( - odl_mapping.PolicyRuleUpdateNotSupportedOnOdlDriver, - getattr(self.driver, 'update_policy_rule_precommit'), - self.context_1 - ) - - -class PolicyRuleSetTestCase(OdlMappingTestCase): - """ Test case for policy rule set operations - """ - def setUp(self): - super(PolicyRuleSetTestCase, self).setUp() - self.context_1 = mock.Mock( - current=self.fake_gbp_plugin.get_policy_rule_set( - FAKE_CONTEXT, - RULE_SET_1_ID - ), - _plugin_context=FAKE_PLUGIN_CONTEXT, - _plugin=self.fake_gbp_plugin - ) - - @mock.patch.object(g_plugin.GroupPolicyPlugin, 'get_policy_action') - @mock.patch.object(g_plugin.GroupPolicyPlugin, 'get_policy_classifier') - @mock.patch.object(g_plugin.GroupPolicyPlugin, 'get_policy_rule') - @mock.patch.object(odl_manager.OdlManager, 'create_update_contract') - def test_create_policy_rule_set_postcommit( - self, - mock_create_update_contract, - mock_get_policy_rule, - mock_get_policy_classifier, - mock_get_policy_action): - - mock_get_policy_rule.side_effect = (self.fake_gbp_plugin. - get_policy_rule) - mock_get_policy_classifier.side_effect = (self.fake_gbp_plugin. - get_policy_classifier) - mock_get_policy_action.side_effect = (self.fake_gbp_plugin. - get_policy_action) - - contract = { - "id": RULE_SET_1_ID, - "description": RULE_SET_1_NAME, - "clause": [ - { - "name": RULE_SET_1_NAME, - "subject-refs": [RULE_1_NAME] - } - ], - "subject": [ - { - "name": RULE_1_NAME, - "rule": [ - { - "name": RULE_1_NAME, - "classifier-ref": [ - { - "name": CLASSIFIER_1_NAME + '-sourceport' - }, - { - "name": CLASSIFIER_1_NAME + '-destport' - } - ] - } - ] - } - ] - } - - self.driver.create_policy_rule_set_postcommit(self.context_1) - mock_create_update_contract.assert_called_once_with(TENANT_UUID, - contract) - - def test_update_policy_rule_set_precommit(self): - self.assertRaises( - odl_mapping.PolicyRuleSetUpdateNotSupportedOnOdlDriver, - getattr(self.driver, 'update_policy_rule_set_precommit'), - self.context_1 - ) - - -class DHCPTestCase(OdlMappingTestCase): - """ Test case for DHCP related operations - """ - - def setUp(self): - super(DHCPTestCase, self).setUp() - mock_sql = mock.Mock() - mock_sql.query.return_value = mock_sql - mock_sql.join.return_value = mock_sql - mock_sql.filter.return_value = mock_sql - mock_sql.first.return_value = { - "id": GROUP_ID, - "name": GROUP_NAME - } - self.plugin_context = mock.Mock( - session=mock_sql - ) - self.port = { - "id": PORT_ID, - "network_id": NETWORK_ID, - "tenant_id": TENANT_ID - } - - @mock.patch.object(g_plugin.GroupPolicyPlugin, 'create_policy_target') - @mock.patch.object(odl_mapping.OdlMappingDriver, '_port_is_owned') - @mock.patch.object(ml2_plugin.Ml2Plugin, '_get_subnets_by_network') - def test_create_dhcp_policy_target_if_needed( - self, - mock_get_subnets_by_network, - mock_port_is_owned, - mock_create_policy_target): - - mock_get_subnets_by_network.return_value = [ - { - "id": SUBNET_ID - } - ] - attrs = { - "policy_target": { - "tenant_id": TENANT_ID, - "name": 'dhcp-' + GROUP_ID, - "description": "Implicitly created DHCP policy target", - "policy_target_group_id": GROUP_ID, - "port_id": PORT_ID - } - } - - # Test that gbp_plugin.create_policy_target was NOT called - mock_port_is_owned.return_value = True - self.driver.create_dhcp_policy_target_if_needed(self.plugin_context, - self.port) - self.assertFalse(mock_create_policy_target.called, - 'Failed not to create DHCP PT when not needed') - - # Test that gbp_plugin.create_policy_target was called indeed - mock_port_is_owned.return_value = False - self.driver.create_dhcp_policy_target_if_needed(self.plugin_context, - self.port) - mock_create_policy_target.assert_called_once_with(self.plugin_context, - attrs) diff --git a/setup.cfg b/setup.cfg index 710fb14c2..6d9bf91cd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -68,15 +68,10 @@ gbpservice.neutron.group_policy.policy_drivers = chain_mapping = gbpservice.neutron.services.grouppolicy.drivers.chain_mapping:ChainMappingDriver aim_mapping = gbpservice.neutron.services.grouppolicy.drivers.cisco.apic.aim_mapping:AIMMappingDriver apic = gbpservice.neutron.services.grouppolicy.drivers.cisco.apic.apic_mapping:ApicMappingDriver - odl = gbpservice.neutron.services.grouppolicy.drivers.odl.odl_mapping:OdlMappingDriver - oneconvergence_gbp_driver = gbpservice.neutron.services.grouppolicy.drivers.oneconvergence.nvsd_gbp_driver:NvsdGbpDriver - nuage_gbp_driver = gbpservice.neutron.services.grouppolicy.drivers.nuage.driver:NuageGBPDriver neutron.ml2.mechanism_drivers = logger_plus = gbpservice.neutron.tests.unit.plugins.ml2plus.drivers.mechanism_logger:LoggerPlusMechanismDriver apic_aim = gbpservice.neutron.plugins.ml2plus.drivers.apic_aim.mechanism_driver:ApicMechanismDriver apic_gbp = gbpservice.neutron.plugins.ml2.drivers.grouppolicy.apic.driver:APICMechanismGBPDriver - nuage_gbp = gbpservice.neutron.plugins.ml2.drivers.grouppolicy.nuage.driver:NuageMechanismGBPDriver - odl_gbp = gbpservice.neutron.plugins.ml2.drivers.grouppolicy.odl.driver:OdlMechanismGBPDriver stitching_gbp = gbpservice.neutron.plugins.ml2.drivers.grouppolicy.stitching.driver:TrafficStitchingMechanismGBPDriver neutron.ml2.extension_drivers = apic_aim = gbpservice.neutron.plugins.ml2plus.drivers.apic_aim.extension_driver:ApicExtensionDriver @@ -85,7 +80,6 @@ neutron.ml2.extension_drivers = gbpservice.neutron.servicechain.servicechain_drivers = dummy = gbpservice.neutron.services.servicechain.plugins.msc.drivers.dummy_driver:NoopDriver simplechain_driver = gbpservice.neutron.services.servicechain.plugins.msc.drivers.simplechain_driver:SimpleChainDriver - oneconvergence_servicechain_driver = gbpservice.neutron.services.servicechain.plugins.msc.drivers.oneconvergence_servicechain_driver:OneconvergenceServiceChainDriver gbpservice.neutron.servicechain.ncp_drivers = node_dummy = gbpservice.neutron.services.servicechain.plugins.ncp.node_drivers.dummy_driver:NoopNodeDriver heat_node_driver = gbpservice.neutron.services.servicechain.plugins.ncp.node_drivers.heat_node_driver:HeatNodeDriver