diff --git a/doc/source/devstack.rst b/doc/source/devstack.rst index b9fdf2a14e..720cd3dabe 100644 --- a/doc/source/devstack.rst +++ b/doc/source/devstack.rst @@ -84,21 +84,6 @@ lines to the policy.json file:: "delete_flow_classifier": "rule:admin_only", "get_flow_classifier": "rule:admin_only" -FWaaS (V1) Driver -~~~~~~~~~~~~~~~~~ - -Add neutron-fwaas repo as an external repository and configure following flags in ``local.conf``:: - - [[local|localrc]] - enable_plugin neutron-fwaas https://git.openstack.org/openstack/neutron-fwaas - ENABLED_SERVICES+=,q-fwaas-v1 - Q_SERVICE_PLUGIN_CLASSES=neutron_fwaas.services.firewall.fwaas_plugin.FirewallPlugin - - [[post-config|$NEUTRON_CONF]] - [fwaas] - enabled = True - driver = vmware_nsxv_edge - Neutron dynamic routing plugin (bgp) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -197,22 +182,6 @@ Enable trunk service and configure following flags in ``local.conf``:: ENABLED_SERVICES+=,q-trunk Q_SERVICE_PLUGIN_CLASSES+=,trunk -FWaaS (V1) Driver -~~~~~~~~~~~~~~~~~ - -Add neutron-fwaas repo as an external repository and configure following flags in ``local.conf``:: - - [[local|localrc]] - enable_plugin neutron-fwaas https://git.openstack.org/openstack/neutron-fwaas - ENABLED_SERVICES+=,q-fwaas - Q_SERVICE_PLUGIN_CLASSES+=,neutron_fwaas.services.firewall.fwaas_plugin.FirewallPlugin - - [[post-config|$NEUTRON_CONF]] - [fwaas] - enabled = True - driver = vmware_nsxv3_edge_v1 - - FWaaS (V2) Driver ~~~~~~~~~~~~~~~~~ @@ -328,23 +297,6 @@ Configure the service provider:: [DEFAULT] api_extensions_path = $DEST/neutron-lbaas/neutron_lbaas/extensions -FWaaS (V1) Driver -~~~~~~~~~~~~~~~~~ - -Add neutron-fwaas repo as an external repository and configure following flags in ``local.conf``:: - - [[local|localrc]] - enable_plugin neutron-fwaas https://git.openstack.org/openstack/neutron-fwaas - ENABLED_SERVICES+=,q-fwaas - Q_SERVICE_PLUGIN_CLASSES=vmware_nsxtvd_fwaasv1 - - [[post-config|$NEUTRON_CONF]] - [fwaas] - enabled = True - driver = vmware_nsxtvd_edge_v1 - [DEFAULT] - api_extensions_path = $DEST/neutron-fwaas/neutron_fwaas/extensions - FWaaS (V2) Driver ~~~~~~~~~~~~~~~~~ diff --git a/setup.cfg b/setup.cfg index 4269416f72..4607cbb835 100644 --- a/setup.cfg +++ b/setup.cfg @@ -36,17 +36,13 @@ neutron.core_plugins = vmware_dvs = vmware_nsx.plugin:NsxDvsPlugin vmware_nsxtvd = vmware_nsx.plugin:NsxTVDPlugin firewall_drivers = - vmware_nsxv_edge = vmware_nsx.services.fwaas.nsx_v.edge_fwaas_driver:EdgeFwaasDriver vmware_nsxv3_edge = vmware_nsx.services.fwaas.nsx_v3.edge_fwaas_driver_v1:EdgeFwaasV3DriverV1 - vmware_nsxv3_edge_v1 = vmware_nsx.services.fwaas.nsx_v3.edge_fwaas_driver_v1:EdgeFwaasV3DriverV1 vmware_nsxv3_edge_v2 = vmware_nsx.services.fwaas.nsx_v3.edge_fwaas_driver_v2:EdgeFwaasV3DriverV2 - vmware_nsxtvd_edge_v1 = vmware_nsx.services.fwaas.nsx_tv.edge_fwaas_driver_v1:EdgeFwaasTVDriverV1 vmware_nsxtvd_edge_v2 = vmware_nsx.services.fwaas.nsx_tv.edge_fwaas_driver_v2:EdgeFwaasTVDriverV2 neutron.service_plugins = vmware_nsxv_qos = vmware_nsx.services.qos.nsx_v.plugin:NsxVQosPlugin vmware_nsx_lbaasv2 = vmware_nsx.services.lbaas.nsx_plugin:LoadBalancerNSXPluginV2 vmware_nsxtvd_lbaasv2 = vmware_nsx.services.lbaas.nsx.plugin:LoadBalancerTVPluginV2 - vmware_nsxtvd_fwaasv1 = vmware_nsx.services.fwaas.nsx_tv.plugin_v1:FwaasTVPluginV1 vmware_nsxtvd_fwaasv2 = vmware_nsx.services.fwaas.nsx_tv.plugin_v2:FwaasTVPluginV2 vmware_nsxtvd_l2gw = vmware_nsx.services.l2gateway.nsx_tvd.plugin:L2GatewayPlugin vmware_nsxtvd_qos = vmware_nsx.services.qos.nsx_tvd.plugin:QoSPlugin diff --git a/vmware_nsx/plugins/nsx_v/plugin.py b/vmware_nsx/plugins/nsx_v/plugin.py index 2f73cf144d..535da30c93 100644 --- a/vmware_nsx/plugins/nsx_v/plugin.py +++ b/vmware_nsx/plugins/nsx_v/plugin.py @@ -144,7 +144,6 @@ from vmware_nsx.plugins.nsx_v.vshield import edge_utils from vmware_nsx.plugins.nsx_v.vshield import securitygroup_utils from vmware_nsx.plugins.nsx_v.vshield import vcns_driver from vmware_nsx.services.flowclassifier.nsx_v import utils as fc_utils -from vmware_nsx.services.fwaas.nsx_v import fwaas_callbacks from vmware_nsx.services.lbaas.nsx_v.implementation import healthmon_mgr from vmware_nsx.services.lbaas.nsx_v.implementation import l7policy_mgr from vmware_nsx.services.lbaas.nsx_v.implementation import l7rule_mgr @@ -498,7 +497,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, def _init_fwaas(self): # Bind FWaaS callbacks to the driver - self.fwaas_callbacks = fwaas_callbacks.NsxvFwaasCallbacks() + #TODO(asarfaty): waiting for FWaaS v2 support + self.fwaas_callbacks = None def _create_security_group_container(self): name = "OpenStack Security Group container" @@ -3345,8 +3345,9 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, raise n_exc.InvalidInput(error_message=err_msg) # shared router cannot be attached to a fwaas - if self.fwaas_callbacks.should_apply_firewall_to_router( - context, router, router_id): + if (self.fwaas_callbacks and + self.fwaas_callbacks.should_apply_firewall_to_router( + context, router, router_id)): err_msg = _('Unable to create a shared router with FWaaS') raise n_exc.InvalidInput(error_message=err_msg) @@ -4023,8 +4024,9 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, # router['id'] is the id of the neutron router (=tlr) # and router_id is the plr/tlr (the one that is being updated) fwaas_rules = None - if (self.fwaas_callbacks.should_apply_firewall_to_router( - context, router_db, router_id)): + if (self.fwaas_callbacks and + self.fwaas_callbacks.should_apply_firewall_to_router( + context, router_db, router_id)): fwaas_rules = self.fwaas_callbacks.get_fwaas_rules_for_router( context, router_db['id']) diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index 4eb198a054..0bacc5357d 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -83,7 +83,6 @@ from vmware_nsx.plugins.nsx import utils as tvd_utils from vmware_nsx.plugins.nsx_v3 import availability_zones as nsx_az from vmware_nsx.plugins.nsx_v3 import utils as v3_utils from vmware_nsx.services.fwaas.common import utils as fwaas_utils -from vmware_nsx.services.fwaas.nsx_v3 import fwaas_callbacks_v1 from vmware_nsx.services.fwaas.nsx_v3 import fwaas_callbacks_v2 from vmware_nsx.services.lbaas.nsx_v3.implementation import healthmonitor_mgr from vmware_nsx.services.lbaas.nsx_v3.implementation import l7policy_mgr @@ -456,9 +455,6 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base, return listener_mgr.stats_getter def _init_fwaas(self): - if fwaas_utils.is_fwaas_v1_plugin_enabled(): - LOG.info("NSXv3 FWaaS v1 plugin enabled") - self.fwaas_callbacks = fwaas_callbacks_v1.Nsxv3FwaasCallbacksV1() if fwaas_utils.is_fwaas_v2_plugin_enabled(): LOG.info("NSXv3 FWaaS v2 plugin enabled") self.fwaas_callbacks = fwaas_callbacks_v2.Nsxv3FwaasCallbacksV2() @@ -2500,7 +2496,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base, def update_router_firewall(self, context, router_id, from_fw=False): """Rewrite all the rules in the router edge firewall - This method should be called on FWaaS v1/v2 updates, and on router + This method should be called on FWaaS v2 updates, and on router interfaces changes. When FWaaS is disabled, there is no need to update the NSX router FW, as the default rule is allow-all. diff --git a/vmware_nsx/services/fwaas/common/fwaas_callbacks_v1.py b/vmware_nsx/services/fwaas/common/fwaas_callbacks_v1.py deleted file mode 100644 index 7c756f04a4..0000000000 --- a/vmware_nsx/services/fwaas/common/fwaas_callbacks_v1.py +++ /dev/null @@ -1,158 +0,0 @@ -# Copyright 2017 VMware, Inc. -# All Rights Reserved -# -# 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 -from oslo_log import log as logging - -from neutron.agent.l3 import router_info -from neutron.common import config as neutron_config # noqa -from neutron_lib import constants as nl_constants -from neutron_lib import context as n_context -from neutron_lib.exceptions import firewall_v1 as exceptions -from neutron_lib.plugins import directory - -LOG = logging.getLogger(__name__) - -try: - from neutron_fwaas.db.firewall import firewall_db # noqa - from neutron_fwaas.db.firewall import firewall_router_insertion_db \ - as fw_r_ins_db - from neutron_fwaas.services.firewall.service_drivers.agents.l3reference \ - import firewall_l3_agent -except ImportError: - # FWaaS project no found - from vmware_nsx.services.fwaas.common import fwaas_mocks \ - as firewall_l3_agent - - -class NsxFwaasCallbacks(firewall_l3_agent.L3WithFWaaS): - """Common NSX RPC callbacks for Firewall As A Service - V1.""" - def __init__(self): - # The super code needs a configuration object with the neutron host - # and an agent_mode, which our driver doesn't use. - neutron_conf = cfg.CONF - neutron_conf.agent_mode = 'nsx' - super(NsxFwaasCallbacks, self).__init__(conf=neutron_conf) - self._core_plugin = None - - @property - def plugin_type(self): - pass - - @property - def core_plugin(self): - """Get the NSX-V3 core plugin""" - if not self._core_plugin: - self._core_plugin = directory.get_plugin() - if self._core_plugin.is_tvd_plugin(): - # get the plugin that match this driver - self._core_plugin = self._core_plugin.get_plugin_by_type( - self.plugin_type) - return self._core_plugin - - # Override functions using the agent_api that is not used by our plugin - def _get_router_ids_for_fw(self, context, fw, to_delete=False): - """Return the router_ids either from fw dict or tenant routers.""" - routers_in_proj = self._get_routers_in_project( - context, fw['tenant_id']) - if self._has_router_insertion_fields(fw): - # it is a new version of plugin (supports specific routers) - ids = (fw['del-router-ids'] if to_delete - else fw['add-router-ids']) - project_ids = [router['id'] for router in routers_in_proj - if router['id'] in ids] - if len(project_ids) < len(ids) and not to_delete: - # This means that there is a router from another project. - LOG.error("Failed to attach routers from a different project " - "to firewall %(fw)s: %(routers)s", - {'fw': fw['id'], - 'routers': list(set(ids) - set(project_ids))}) - self.fwplugin_rpc.set_firewall_status( - context, - fw['id'], - nl_constants.ERROR) - raise exceptions.FirewallInternalDriverError( - driver=self.fwaas_driver.driver_name) - return ids - else: - return [router['id'] for router in routers_in_proj] - - def _get_routers_in_project(self, context, project_id): - return self.core_plugin.get_routers( - context, - filters={'project_id': [project_id]}) - - def _router_dict_to_obj(self, r): - # The callbacks expect a router-info object with an agent config - agent_conf = cfg.CONF - agent_conf.metadata_access_mark = '0x1' - return router_info.RouterInfo( - None, r['id'], router=r, - agent_conf=agent_conf, - interface_driver=None, - use_ipv6=False) - - def _get_router_info_list_for_tenant(self, router_ids, tenant_id): - """Returns the list of router info objects on which to apply the fw.""" - context = n_context.get_admin_context() - tenant_routers = self._get_routers_in_project(context, tenant_id) - return [self._router_dict_to_obj(ri) for ri in tenant_routers - if ri['id'] in router_ids] - - def should_apply_firewall_to_router(self, context, router_id): - """Return True if the FWaaS rules should be added to this router.""" - if not self.fwaas_enabled: - return False - - ctx = context.elevated() - fw_id = self._get_router_firewall_id(ctx, router_id) - if fw_id is None: - # No FWaas Firewall was assigned to this router - return False - - # check the state of this firewall - firewall = self._get_fw_from_plugin(ctx, fw_id) - if firewall is not None: - if firewall.get('status') in (nl_constants.ERROR, - nl_constants.PENDING_DELETE): - # Do not add rules of firewalls with errors - LOG.warning("Router %(rtr)s will not get rules from firewall " - "%(fw)s which is in %(status)s", - {'rtr': router_id, 'fw': fw_id, - 'status': firewall['status']}) - return False - - return True - - # TODO(asarfaty): add this api to fwaas firewall-router-insertion-db - def _get_router_firewall_id(self, context, router_id): - entry = context.session.query( - fw_r_ins_db.FirewallRouterAssociation).filter_by( - router_id=router_id).first() - if entry: - return entry.fw_id - - def _get_fw_from_plugin(self, context, fw_id): - # NOTE(asarfaty): currently there is no api to get a specific firewall - fw_list = self.fwplugin_rpc.get_firewalls_for_tenant(context) - for fw in fw_list: - if fw['id'] == fw_id: - return fw - - def get_router_firewall(self, context, router_id): - ctx_elevated = context.elevated() - fw_id = self._get_router_firewall_id(ctx_elevated, router_id) - if fw_id: - return self._get_fw_from_plugin(ctx_elevated, fw_id) diff --git a/vmware_nsx/services/fwaas/common/fwaas_mocks.py b/vmware_nsx/services/fwaas/common/fwaas_mocks.py index 3cbbfff5dc..f54804b44a 100644 --- a/vmware_nsx/services/fwaas/common/fwaas_mocks.py +++ b/vmware_nsx/services/fwaas/common/fwaas_mocks.py @@ -16,7 +16,6 @@ # This file contains FWaaS mocks, to allow the vmware nsx plugins to work when # FWaaS code does not exist, and FWaaS is not configured in neutron -FIREWALL = 'FIREWALL' FIREWALL_V2 = 'FIREWALL_V2' @@ -29,10 +28,6 @@ class FwaasDriverBase(object): pass -class FirewallPlugin(object): - pass - - class FirewallPluginV2(object): pass diff --git a/vmware_nsx/services/fwaas/common/utils.py b/vmware_nsx/services/fwaas/common/utils.py index 57be037109..861af49551 100644 --- a/vmware_nsx/services/fwaas/common/utils.py +++ b/vmware_nsx/services/fwaas/common/utils.py @@ -23,12 +23,6 @@ except ImportError: as fwaas_constants -def is_fwaas_v1_plugin_enabled(): - fwaas_plugin = directory.get_plugin(fwaas_constants.FIREWALL) - if fwaas_plugin: - return True - - def is_fwaas_v2_plugin_enabled(): fwaas_plugin = directory.get_plugin(fwaas_constants.FIREWALL_V2) if fwaas_plugin: diff --git a/vmware_nsx/services/fwaas/nsx_tv/edge_fwaas_driver_v1.py b/vmware_nsx/services/fwaas/nsx_tv/edge_fwaas_driver_v1.py deleted file mode 100644 index 288d0c91fa..0000000000 --- a/vmware_nsx/services/fwaas/nsx_tv/edge_fwaas_driver_v1.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright 2017 VMware, Inc. -# All Rights Reserved -# -# 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_log import helpers as log_helpers -from oslo_log import log as logging - -from neutron_lib.exceptions import firewall_v1 as exceptions - -from vmware_nsx.extensions import projectpluginmap -from vmware_nsx.plugins.nsx import utils as tvd_utils -from vmware_nsx.services.fwaas.nsx_v import edge_fwaas_driver as v_driver -from vmware_nsx.services.fwaas.nsx_v3 import edge_fwaas_driver_v1 as t_driver - -LOG = logging.getLogger(__name__) -FWAAS_DRIVER_NAME = 'FwaaS V1 NSX-TV driver' - -try: - from neutron_fwaas.services.firewall.service_drivers.agents.drivers \ - import fwaas_base -except ImportError: - # FWaaS project no found - from vmware_nsx.services.fwaas.common import fwaas_mocks \ - as fwaas_base - - -class EdgeFwaasTVDriverV1(fwaas_base.FwaasDriverBase): - """NSX-TV driver for Firewall As A Service - V1. - - This driver is just a wrapper calling the relevant nsx-v/t driver - """ - - def __init__(self): - super(EdgeFwaasTVDriverV1, self).__init__() - self.driver_name = FWAAS_DRIVER_NAME - - # supported drivers: - self.drivers = {} - try: - self.drivers[projectpluginmap.NsxPlugins.NSX_T] = ( - t_driver.EdgeFwaasV3DriverV1()) - except Exception: - LOG.warning("EdgeFwaasTVDriverV1 failed to initialize the NSX-T " - "driver") - self.drivers[projectpluginmap.NsxPlugins.NSX_T] = None - try: - self.drivers[projectpluginmap.NsxPlugins.NSX_V] = ( - v_driver.EdgeFwaasDriver()) - except Exception: - LOG.warning("EdgeFwaasTVDriverV1 failed to initialize the NSX-V " - "driver") - self.drivers[projectpluginmap.NsxPlugins.NSX_V] = None - - def get_T_driver(self): - return self.drivers[projectpluginmap.NsxPlugins.NSX_T] - - def get_V_driver(self): - return self.drivers[projectpluginmap.NsxPlugins.NSX_V] - - def _get_driver_for_project(self, project): - plugin_type = tvd_utils.get_tvd_plugin_type_for_project(project) - if not self.drivers.get(plugin_type): - LOG.error("Project %(project)s with plugin %(plugin)s has no " - "support for FWaaS V1", {'project': project, - 'plugin': plugin_type}) - raise exceptions.FirewallInternalDriverError( - driver=self.driver_name) - return self.drivers[plugin_type] - - @log_helpers.log_method_call - def create_firewall(self, agent_mode, apply_list, firewall): - d = self._get_driver_for_project(firewall['tenant_id']) - return d.create_firewall(agent_mode, apply_list, firewall) - - @log_helpers.log_method_call - def update_firewall(self, agent_mode, apply_list, firewall): - d = self._get_driver_for_project(firewall['tenant_id']) - return d.update_firewall(agent_mode, apply_list, firewall) - - @log_helpers.log_method_call - def delete_firewall(self, agent_mode, apply_list, firewall): - d = self._get_driver_for_project(firewall['tenant_id']) - return d.delete_firewall(agent_mode, apply_list, firewall) - - @log_helpers.log_method_call - def apply_default_policy(self, agent_mode, apply_list, firewall): - d = self._get_driver_for_project(firewall['tenant_id']) - return d.apply_default_policy(agent_mode, apply_list, firewall) diff --git a/vmware_nsx/services/fwaas/nsx_tv/plugin_v1.py b/vmware_nsx/services/fwaas/nsx_tv/plugin_v1.py deleted file mode 100644 index c832be2ca5..0000000000 --- a/vmware_nsx/services/fwaas/nsx_tv/plugin_v1.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 2018 VMware, Inc. -# All Rights Reserved -# -# 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_lib import exceptions as n_exc -from neutron_lib.plugins import directory - -from vmware_nsx.plugins.nsx import utils as tvd_utils - -try: - from neutron_fwaas.services.firewall import fwaas_plugin -except ImportError: - # FWaaS project no found - from vmware_nsx.services.fwaas.common import fwaas_mocks \ - as fwaas_plugin - - -@tvd_utils.filter_plugins -class FwaasTVPluginV1(fwaas_plugin.FirewallPlugin): - """NSX-TV plugin for Firewall As A Service - V1. - - This plugin adds separation between T/V instances - """ - methods_to_separate = ['get_firewalls', - 'get_firewall_policies', - 'get_firewall_rules'] - - def validate_firewall_routers_not_in_use( - self, context, router_ids, fwid=None): - # Override this method to verify that the router & firewall belongs to - # the same plugin - context_plugin_type = tvd_utils.get_tvd_plugin_type_for_project( - context.project_id, context) - core_plugin = directory.get_plugin() - for rtr_id in router_ids: - rtr_plugin = core_plugin._get_plugin_from_router_id( - context, rtr_id) - if rtr_plugin.plugin_type() != context_plugin_type: - err_msg = (_('Router should belong to the %s plugin ' - 'as the firewall') % context_plugin_type) - raise n_exc.InvalidInput(error_message=err_msg) diff --git a/vmware_nsx/services/fwaas/nsx_v/edge_fwaas_driver.py b/vmware_nsx/services/fwaas/nsx_v/edge_fwaas_driver.py deleted file mode 100644 index 40b9bf3697..0000000000 --- a/vmware_nsx/services/fwaas/nsx_v/edge_fwaas_driver.py +++ /dev/null @@ -1,269 +0,0 @@ -# Copyright 2017 VMware, Inc. -# All Rights Reserved -# -# 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_lib import context as n_context -from neutron_lib.exceptions import firewall_v1 as exceptions -from neutron_lib.plugins import directory -from oslo_log import helpers as log_helpers -from oslo_log import log as logging - -from vmware_nsx.common import locking -from vmware_nsx.extensions import projectpluginmap -from vmware_nsx.plugins.nsx_v.vshield import edge_utils - -LOG = logging.getLogger(__name__) -FWAAS_DRIVER_NAME = 'Fwaas V1 NSX-V driver' -RULE_NAME_PREFIX = 'Fwaas-' - -try: - from neutron_fwaas.services.firewall.service_drivers.agents.drivers \ - import fwaas_base -except ImportError: - # FWaaS project no found - from vmware_nsx.services.fwaas.common import fwaas_mocks \ - as fwaas_base - - -class EdgeFwaasDriver(fwaas_base.FwaasDriverBase): - """NSX-V driver for Firewall As A Service - V1.""" - - @property - def core_plugin(self): - if not self._core_plugin: - self._core_plugin = directory.get_plugin() - if self._core_plugin.is_tvd_plugin(): - self._core_plugin = self._core_plugin.get_plugin_by_type( - projectpluginmap.NsxPlugins.NSX_V) - # make sure plugin init was completed - if not self._core_plugin.init_is_complete: - self._core_plugin.init_complete(None, None, {}) - return self._core_plugin - - @property - def edge_manager(self): - return self.core_plugin.edge_manager - - def __init__(self): - LOG.debug("Loading FWaaS V1 NsxVDriver.") - super(EdgeFwaasDriver, self).__init__() - self.driver_name = FWAAS_DRIVER_NAME - self._core_plugin = None - - def should_apply_firewall_to_router(self, router_data, - raise_exception=True): - """Return True if the firewall rules should be added the router - - Return False in those cases: - - router without an external gateway (rule may be added later when - there is a gateway) - - Raise an exception if the router is unsupported - (and raise_exception is True): - - shared router (not supported) - - md proxy router (not supported) - - """ - if (not router_data.get('distributed') and - router_data.get('router_type') == 'shared'): - LOG.error("Cannot apply firewall to shared router %s", - router_data['id']) - if raise_exception: - raise exceptions.FirewallInternalDriverError( - driver=self.driver_name) - return False - - if router_data.get('name', '').startswith('metadata_proxy_router'): - LOG.error("Cannot apply firewall to the metadata proxy router %s", - router_data['id']) - if raise_exception: - raise exceptions.FirewallInternalDriverError( - driver=self.driver_name) - return False - - if not router_data.get('external_gateway_info'): - LOG.info("Cannot apply firewall to router %s with no gateway", - router_data['id']) - return False - - return True - - def _get_routers_edges(self, context, apply_list, delete_fw=False): - # Get edges for all the routers in the apply list. - # note that shared routers are currently not supported - edge_manager = self.edge_manager - edges_map = {} - for router_info in apply_list: - - # No FWaaS rules needed if there is no external gateway - if not self.should_apply_firewall_to_router( - router_info.router, raise_exception=(not delete_fw)): - continue - - lookup_id = None - router_id = router_info.router_id - if router_info.router.get('distributed'): - # Distributed router - # we need the plr edge id - lookup_id = edge_manager.get_plr_by_tlr_id( - context, router_id) - else: - # Exclusive router - lookup_id = router_id - if lookup_id: - # look for the edge id in the DB - edge_id = edge_utils.get_router_edge_id(context, lookup_id) - if edge_id: - edges_map[router_id] = {'edge_id': edge_id, - 'lookup_id': lookup_id} - return edges_map - - def _translate_rules(self, fwaas_rules, logged=False): - translated_rules = [] - for rule in fwaas_rules: - if not rule['enabled']: - # skip disabled rules - continue - # Make sure the rule has a name, and it starts with the prefix - # (backend max name length is 30) - if rule.get('name'): - rule['name'] = RULE_NAME_PREFIX + rule['name'] - else: - rule['name'] = RULE_NAME_PREFIX + rule['id'] - rule['name'] = rule['name'][:30] - # source & destination should be lists - if rule.get('destination_ip_address'): - rule['destination_ip_address'] = [ - rule['destination_ip_address']] - if rule.get('source_ip_address'): - rule['source_ip_address'] = [rule['source_ip_address']] - if logged: - rule['logged'] = True - translated_rules.append(rule) - - return translated_rules - - def _set_rules_on_router_edge(self, context, router_id, neutron_id, - edge_id, fw_id, translated_rules, - delete_fw=False): - """Recreate router edge firewall rules - - Using the plugin code to recreate all the rules with the additional - FWaaS rules. - - router_id is the is of the router about to be updated - (in case of distributed router - the plr) - neutron_id is the neutron router id - """ - # update the backend - router_db = self.core_plugin._get_router(context, neutron_id) - try: - with locking.LockManager.get_lock(str(edge_id)): - self.core_plugin.update_router_firewall( - context, router_id, router_db, - fwaas_rules=translated_rules) - except Exception as e: - # catch known library exceptions and raise Fwaas generic exception - LOG.error("Failed to update firewall %(fw)s on edge %(edge_id)s: " - "%(e)s", {'e': e, 'fw': fw_id, 'edge_id': edge_id}) - raise exceptions.FirewallInternalDriverError( - driver=self.driver_name) - - def _create_or_update_firewall(self, agent_mode, apply_list, firewall): - # admin state down means default block rule firewall - if not firewall['admin_state_up']: - self.apply_default_policy(agent_mode, apply_list, firewall) - return - - # get router-edge mapping - context = n_context.get_admin_context() - edges_map = self._get_routers_edges(context, apply_list) - if not edges_map: - routers = [r.router_id for r in apply_list] - LOG.warning("Cannot apply the firewall %(fw)s to any of the " - "routers %(rtrs)s", - {'fw': firewall['id'], 'rtrs': routers}) - return - - # Translate the FWaaS rules - # TODO(asarfaty): get this value from the firewall extensions - logged = False - rules = self._translate_rules(firewall['firewall_rule_list'], - logged=logged) - - # update each relevant edge with the new rules - for router_info in apply_list: - neutron_id = router_info.router_id - info = edges_map.get(neutron_id) - if info: - self._set_rules_on_router_edge( - context, info['lookup_id'], neutron_id, info['edge_id'], - firewall['id'], rules) - - @log_helpers.log_method_call - def create_firewall(self, agent_mode, apply_list, firewall): - """Create the Firewall with a given policy. """ - self._create_or_update_firewall(agent_mode, apply_list, firewall) - - @log_helpers.log_method_call - def update_firewall(self, agent_mode, apply_list, firewall): - """Remove previous policy and apply the new policy.""" - self._create_or_update_firewall(agent_mode, apply_list, firewall) - - def _delete_firewall_or_set_default_policy(self, apply_list, firewall, - delete_fw=False): - # get router-edge mapping - context = n_context.get_admin_context() - edges_map = self._get_routers_edges(context, apply_list, - delete_fw=delete_fw) - - # if the firewall is deleted, rules should be None - rules = None if delete_fw else [] - - # Go over all routers and update them on backend - for router_info in apply_list: - neutron_id = router_info.router_id - info = edges_map.get(neutron_id) - if info: - self._set_rules_on_router_edge( - context, info['lookup_id'], neutron_id, info['edge_id'], - firewall['id'], rules, delete_fw=delete_fw) - - @log_helpers.log_method_call - def delete_firewall(self, agent_mode, apply_list, firewall): - """Delete firewall. - - Removes rules created by this instance from the backend firewall - And add the default allow-external rule. - """ - self._delete_firewall_or_set_default_policy(apply_list, firewall, - delete_fw=True) - - @log_helpers.log_method_call - def apply_default_policy(self, agent_mode, apply_list, firewall): - """Apply the default policy (deny all). - - The backend firewall always has this policy (=deny all) as default, - so we only need to delete the current rules. - """ - self._delete_firewall_or_set_default_policy(apply_list, firewall, - delete_fw=False) - - def get_firewall_translated_rules(self, firewall): - if firewall['admin_state_up']: - # TODO(asarfaty): get this value from the firewall extensions - logged = False - return self._translate_rules(firewall['firewall_rule_list'], - logged=logged) - return [] diff --git a/vmware_nsx/services/fwaas/nsx_v/fwaas_callbacks.py b/vmware_nsx/services/fwaas/nsx_v/fwaas_callbacks.py deleted file mode 100644 index e07706b705..0000000000 --- a/vmware_nsx/services/fwaas/nsx_v/fwaas_callbacks.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright 2017 VMware, Inc. -# All Rights Reserved -# -# 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_log import log as logging - -from vmware_nsx.extensions import projectpluginmap -from vmware_nsx.services.fwaas.common import fwaas_callbacks_v1 as com_clbcks -from vmware_nsx.services.fwaas.nsx_tv import edge_fwaas_driver_v1 as tv_driver - -LOG = logging.getLogger(__name__) - - -class NsxvFwaasCallbacks(com_clbcks.NsxFwaasCallbacks): - """NSX-V RPC callbacks for Firewall As A Service - V1.""" - - def __init__(self): - super(NsxvFwaasCallbacks, self).__init__() - # update the fwaas driver in case of TV plugin - if self.fwaas_enabled: - if self.fwaas_driver.driver_name == tv_driver.FWAAS_DRIVER_NAME: - self.internal_driver = self.fwaas_driver.get_V_driver() - else: - self.internal_driver = self.fwaas_driver - - @property - def plugin_type(self): - return projectpluginmap.NsxPlugins.NSX_V - - def should_apply_firewall_to_router(self, context, router, router_id): - """Return True if the FWaaS rules should be added to this router.""" - # in case of a distributed-router: - # router['id'] is the id of the neutron router (=tlr) - # and router_id is the plr/tlr (the one that is being updated) - if not super(NsxvFwaasCallbacks, self).should_apply_firewall_to_router( - context, router['id']): - return False - - # get all the relevant router info - # ("router" does not have all the fields) - ctx_elevated = context.elevated() - router_data = self.core_plugin.get_router(ctx_elevated, router['id']) - if not router_data: - LOG.error("Couldn't read router %s data", router['id']) - return False - - if router_data.get('distributed'): - if router_id == router['id']: - # Do not add firewall rules on the tlr router. - return False - - # Check if the FWaaS driver supports this router - if not self.internal_driver.should_apply_firewall_to_router( - router_data, raise_exception=False): - return False - - return True - - def get_fwaas_rules_for_router(self, context, router_id): - """Return the list of (translated) FWaaS rules for this router.""" - ctx_elevated = context.elevated() - fw_id = self._get_router_firewall_id(ctx_elevated, router_id) - if fw_id: - return self._get_fw_applicable_rules(ctx_elevated, fw_id) - return [] - - def _get_fw_applicable_rules(self, context, fw_id): - fw = self._get_fw_from_plugin(context, fw_id) - if fw is not None and fw['id'] == fw_id: - return self.internal_driver.get_firewall_translated_rules(fw) - return [] diff --git a/vmware_nsx/services/fwaas/nsx_v3/edge_fwaas_driver_v1.py b/vmware_nsx/services/fwaas/nsx_v3/edge_fwaas_driver_v1.py deleted file mode 100644 index aa2aa9b829..0000000000 --- a/vmware_nsx/services/fwaas/nsx_v3/edge_fwaas_driver_v1.py +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright 2017 VMware, Inc. -# All Rights Reserved -# -# 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_lib import context as n_context -from oslo_log import helpers as log_helpers -from oslo_log import log as logging - -from neutron_lib.exceptions import firewall_v1 as exceptions - -from vmware_nsx.services.fwaas.nsx_v3 import edge_fwaas_driver_base as \ - base_driver - -LOG = logging.getLogger(__name__) -FWAAS_DRIVER_NAME = 'Fwaas V1 NSX-V3 driver' -NSX_FW_TAG = 'os-neutron-fw-id' - - -class EdgeFwaasV3DriverV1(base_driver.CommonEdgeFwaasV3Driver): - """NSX-V3 driver for Firewall As A Service - V1.""" - - def __init__(self): - exception_cls = exceptions.FirewallInternalDriverError - super(EdgeFwaasV3DriverV1, self).__init__(exception_cls, - FWAAS_DRIVER_NAME) - - @log_helpers.log_method_call - def create_firewall(self, agent_mode, apply_list, firewall): - """Create the Firewall with a given policy. """ - self._update_backend_routers(apply_list, firewall['id']) - - @log_helpers.log_method_call - def update_firewall(self, agent_mode, apply_list, firewall): - """Remove previous policy and apply the new policy.""" - self._update_backend_routers(apply_list, firewall['id']) - - @log_helpers.log_method_call - def delete_firewall(self, agent_mode, apply_list, firewall): - """Delete firewall. - - Removes rules created by this instance from the backend firewall - And add the default allow rule. - """ - self._update_backend_routers(apply_list, firewall['id']) - - @log_helpers.log_method_call - def apply_default_policy(self, agent_mode, apply_list, firewall): - """Apply the default policy (deny all). - - The backend firewall always has this policy (=deny all) as default, - so we only need to delete the current rules. - """ - self._update_backend_routers(apply_list, firewall['id']) - - def _update_backend_routers(self, apply_list, fw_id): - """"Update each router on the backend using the core plugin code""" - self.validate_backend_version() - context = n_context.get_admin_context() - for router_info in apply_list: - # Skip unsupported routers - if not self.should_apply_firewall_to_router(router_info.router): - continue - - self.core_plugin.update_router_firewall( - context, router_info.router_id) - - def update_nsx_router_tags(self, nsx_router_id, fw_id=None): - """Update the backend router with tags marking the attached fw id""" - # Get the current tags - nsx_router = self.nsx_router.get(nsx_router_id) - if 'tags' not in nsx_router: - nsx_router['tags'] = [] - tags = nsx_router['tags'] - - # Look for the firewall tag and update/remove it - update_tags = False - found_tag = False - for tag in tags: - if tag.get('scope') == NSX_FW_TAG: - found_tag = True - if not fw_id: - tags.remove(tag) - update_tags = True - break - if fw_id != tag.get('tag'): - tag['tag'] = fw_id - update_tags = True - break - # Add the tag if not found - if fw_id and not found_tag: - tags.append({'scope': NSX_FW_TAG, - 'tag': fw_id}) - update_tags = True - - # update tags on the backend router - if update_tags: - self.nsx_router.update(nsx_router_id, tags=tags) - - def get_router_translated_rules(self, router_id, firewall): - """Return the list of translated rules - - The default drop all will be added later - """ - # Return the firewall rules only if the fw is up - if firewall['admin_state_up']: - # TODO(asarfaty): get this value from the firewall extensions - logged = False - return self._translate_rules(firewall['firewall_rule_list'], - logged=logged) - - return [] diff --git a/vmware_nsx/services/fwaas/nsx_v3/fwaas_callbacks_v1.py b/vmware_nsx/services/fwaas/nsx_v3/fwaas_callbacks_v1.py deleted file mode 100644 index 1f2451cc9a..0000000000 --- a/vmware_nsx/services/fwaas/nsx_v3/fwaas_callbacks_v1.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright 2017 VMware, Inc. -# All Rights Reserved -# -# 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_log import log as logging - -from vmware_nsx.extensions import projectpluginmap -from vmware_nsx.services.fwaas.common import fwaas_callbacks_v1 as com_clbcks -from vmware_nsx.services.fwaas.nsx_tv import edge_fwaas_driver_v1 as tv_driver - -LOG = logging.getLogger(__name__) - - -class Nsxv3FwaasCallbacksV1(com_clbcks.NsxFwaasCallbacks): - """NSX-V3 RPC callbacks for Firewall As A Service - V1.""" - - def __init__(self): - super(Nsxv3FwaasCallbacksV1, self).__init__() - # update the fwaas driver in case of TV plugin - if self.fwaas_enabled: - if self.fwaas_driver.driver_name == tv_driver.FWAAS_DRIVER_NAME: - self.internal_driver = self.fwaas_driver.get_T_driver() - else: - self.internal_driver = self.fwaas_driver - - @property - def plugin_type(self): - return projectpluginmap.NsxPlugins.NSX_T - - def should_apply_firewall_to_router(self, context, router_id): - """Return True if the FWaaS rules should be added to this router.""" - if not super(Nsxv3FwaasCallbacksV1, - self).should_apply_firewall_to_router(context, - router_id): - return False - - # get all the relevant router info - ctx_elevated = context.elevated() - router_data = self.core_plugin.get_router(ctx_elevated, router_id) - if not router_data: - LOG.error("Couldn't read router %s data", router_id) - return False - - # Check if the FWaaS driver supports this router - if not self.internal_driver.should_apply_firewall_to_router( - router_data): - return False - - return True - - def update_router_firewall(self, context, nsxlib, router_id, - router_interfaces, nsx_router_id, section_id, - from_fw=False): - """Rewrite all the FWaaS v1 rules in the router edge firewall - - This method should be called on FWaaS updates, and on router - interfaces changes. - """ - fw_rules = [] - fw_id = None - if self.should_apply_firewall_to_router(context, router_id): - # Find the firewall attached to this router - # (must have one since should_apply returned true) - firewall = self.get_router_firewall(context, router_id) - fw_id = firewall['id'] - - # Add the FW rules - fw_rules.extend(self.internal_driver.get_router_translated_rules( - router_id, firewall)) - - # Add plugin additional allow rules - fw_rules.extend(self.core_plugin.get_extra_fw_rules( - context, router_id)) - - # Add the default drop all rule - fw_rules.append(self.internal_driver.get_default_backend_rule( - section_id, allow_all=False)) - else: - # default allow all rule - fw_rules.append(self.internal_driver.get_default_backend_rule( - section_id, allow_all=True)) - - # update the backend - nsxlib.firewall_section.update(section_id, rules=fw_rules) - - # Also update the router tags - self.internal_driver.update_nsx_router_tags(nsx_router_id, fw_id=fw_id) - - def delete_port(self, context, port_id): - # nothing to do in FWaaS v1 - pass diff --git a/vmware_nsx/shell/admin/plugins/nsxv3/resources/utils.py b/vmware_nsx/shell/admin/plugins/nsxv3/resources/utils.py index f3e59d2fa3..2fab464b8c 100644 --- a/vmware_nsx/shell/admin/plugins/nsxv3/resources/utils.py +++ b/vmware_nsx/shell/admin/plugins/nsxv3/resources/utils.py @@ -27,19 +27,10 @@ from vmware_nsx.db import db as nsx_db from vmware_nsx.extensions import projectpluginmap from vmware_nsx.plugins.nsx_v3 import plugin from vmware_nsx.plugins.nsx_v3 import utils as v3_utils -from vmware_nsx.services.fwaas.nsx_v3 import fwaas_callbacks_v1 from vmware_nsx.services.fwaas.nsx_v3 import fwaas_callbacks_v2 from vmware_nsx.shell.admin.plugins.common import utils as admin_utils from vmware_nsxlib.v3 import nsx_constants -try: - from neutron_fwaas.services.firewall import fwaas_plugin as fwaas_plugin_v1 -except ImportError: - # FWaaS project no found - from vmware_nsx.services.fwaas.common import fwaas_mocks \ - as fwaas_plugin_v1 - - _NSXLIB = None @@ -162,12 +153,6 @@ class NsxV3PluginWrapper(plugin.NsxV3Plugin): 'firewall_v2', fwaas_callbacks_v2.Nsxv3FwaasCallbacksV2, None) - else: - # FWaaS V1 - self._init_fwaas_plugin( - 'firewall', - fwaas_callbacks_v1.Nsxv3FwaasCallbacksV1, - fwaas_plugin_v1.FirewallCallbacks) return def _init_dhcp_metadata(self): diff --git a/vmware_nsx/tests/unit/nsx_v/test_fwaas_driver.py b/vmware_nsx/tests/unit/nsx_v/test_fwaas_driver.py deleted file mode 100644 index 7b8f0d5779..0000000000 --- a/vmware_nsx/tests/unit/nsx_v/test_fwaas_driver.py +++ /dev/null @@ -1,247 +0,0 @@ -# Copyright 2017 VMware, Inc. -# All Rights Reserved -# -# 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 copy - -import mock -from neutron_lib.exceptions import firewall_v1 as exceptions -from oslo_utils import uuidutils - -from vmware_nsx.services.fwaas.nsx_v import edge_fwaas_driver -from vmware_nsx.tests.unit.nsx_v import test_plugin as test_v_plugin - -FAKE_FW_ID = 'fake_fw_uuid' - - -class NsxvFwaasTestCase(test_v_plugin.NsxVPluginV2TestCase): - def setUp(self): - super(NsxvFwaasTestCase, self).setUp() - self.firewall = edge_fwaas_driver.EdgeFwaasDriver() - - def _fake_rules_v4(self): - rule1 = {'enabled': True, - 'action': 'allow', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '80', - 'source_port': '1-65535', - 'source_ip_address': '10.24.4.2', - 'id': 'fake-fw-rule1'} - rule2 = {'enabled': True, - 'action': 'deny', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '22', - 'id': 'fake-fw-rule2'} - rule3 = {'enabled': True, - 'action': 'reject', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '23', - 'id': 'fake-fw-rule3'} - return [rule1, rule2, rule3] - - def _fake_backend_rules_v4(self, logged=False): - rule1 = {'enabled': True, - 'action': 'allow', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '80', - 'source_port': '1-65535', - 'source_ip_address': ['10.24.4.2'], - 'position': '0', - 'id': 'fake-fw-rule1', - 'name': 'Fwaas-fake-fw-rule1'} - rule2 = {'enabled': True, - 'action': 'deny', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '22', - 'id': 'fake-fw-rule2', - 'position': '1', - 'name': 'Fwaas-fake-fw-rule2'} - rule3 = {'enabled': True, - 'action': 'reject', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '23', - 'position': '2', - 'id': 'fake-fw-rule3', - 'name': 'Fwaas-fake-fw-rule3'} - if logged: - for rule in (rule1, rule2, rule3): - rule['loggingEnabled'] = logged - return [rule1, rule2, rule3] - - def _fake_firewall_no_rule(self): - rule_list = [] - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': True, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': rule_list} - return fw_inst - - def _fake_firewall(self, rule_list): - _rule_list = copy.deepcopy(rule_list) - for rule in _rule_list: - rule['position'] = str(_rule_list.index(rule)) - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': True, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': _rule_list} - return fw_inst - - def _fake_firewall_with_admin_down(self, rule_list): - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': False, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': rule_list} - return fw_inst - - def _fake_apply_list(self, router_count=1): - apply_list = [] - while router_count > 0: - rtr_id = uuidutils.generate_uuid() - router_inst = {'id': rtr_id} - router_info_inst = mock.Mock() - router_info_inst.router = router_inst - router_info_inst.router_id = rtr_id - apply_list.append(router_info_inst) - router_count -= 1 - return apply_list - - def _get_fake_mapping(self, apply_list): - router_edge_map = {} - for router_info in apply_list: - router_edge_map[router_info.router_id] = { - 'edge_id': 'edge-1', - 'lookup_id': router_info.router_id} - return router_edge_map - - def _setup_firewall_with_rules(self, func, router_count=1): - apply_list = self._fake_apply_list(router_count=router_count) - rule_list = self._fake_rules_v4() - firewall = self._fake_firewall(rule_list) - edges = self._get_fake_mapping(apply_list) - - with mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2." - "update_router_firewall") as update_fw,\ - mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2." - "_get_router"),\ - mock.patch.object(self.firewall, - "_get_routers_edges", return_value=edges): - func('nsx', apply_list, firewall) - self.assertEqual(router_count, update_fw.call_count) - # Validate the args of the last call - self.assertEqual(apply_list[-1].router_id, - update_fw.call_args[0][1]) - backend_rules = update_fw.call_args[1]['fwaas_rules'] - self.assertEqual(len(rule_list), len(backend_rules)) - self.assertEqual(self._fake_backend_rules_v4(), backend_rules) - - def test_create_firewall_no_rules(self): - apply_list = self._fake_apply_list() - firewall = self._fake_firewall_no_rule() - edges = self._get_fake_mapping(apply_list) - with mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2." - "update_router_firewall") as update_fw,\ - mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2." - "_get_router"),\ - mock.patch.object(self.firewall, - "_get_routers_edges", return_value=edges): - self.firewall.create_firewall('nsx', apply_list, firewall) - self.assertEqual(1, update_fw.call_count) - # Validate the args of the last call - self.assertEqual(apply_list[0].router_id, - update_fw.call_args[0][1]) - backend_rules = update_fw.call_args[1]['fwaas_rules'] - self.assertEqual([], backend_rules) - - def test_create_firewall_with_rules(self): - self._setup_firewall_with_rules(self.firewall.create_firewall) - - def test_create_firewall_with_rules_two_routers(self): - self._setup_firewall_with_rules(self.firewall.create_firewall, - router_count=2) - - def test_update_firewall_with_rules(self): - self._setup_firewall_with_rules(self.firewall.update_firewall) - - def test_delete_firewall(self): - apply_list = self._fake_apply_list() - firewall = self._fake_firewall_no_rule() - edges = self._get_fake_mapping(apply_list) - with mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2." - "update_router_firewall") as update_fw,\ - mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2." - "_get_router"),\ - mock.patch.object(self.firewall, - "_get_routers_edges", return_value=edges): - self.firewall.delete_firewall('nsx', apply_list, firewall) - self.assertEqual(1, update_fw.call_count) - # Validate the args of the last call - self.assertEqual(apply_list[0].router_id, - update_fw.call_args[0][1]) - backend_rules = update_fw.call_args[1]['fwaas_rules'] - self.assertIsNone(backend_rules) - - def test_create_firewall_with_admin_down(self): - apply_list = self._fake_apply_list() - rule_list = self._fake_rules_v4() - firewall = self._fake_firewall_with_admin_down(rule_list) - edges = self._get_fake_mapping(apply_list) - with mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2." - "update_router_firewall") as update_fw,\ - mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2." - "_get_router"),\ - mock.patch.object(self.firewall, - "_get_routers_edges", return_value=edges): - self.firewall.create_firewall('nsx', apply_list, firewall) - self.assertEqual(1, update_fw.call_count) - # Validate the args of the last call - self.assertEqual(apply_list[0].router_id, - update_fw.call_args[0][1]) - backend_rules = update_fw.call_args[1]['fwaas_rules'] - self.assertEqual([], backend_rules) - - def test_should_apply_firewall_to_router(self): - router = {'id': 'fake_id', - 'external_gateway_info': 'fake_data', - 'router_type': 'exclusive', - 'distributed': False} - self.assertTrue(self.firewall.should_apply_firewall_to_router(router)) - - # no external gateway: - router['external_gateway_info'] = None - self.assertFalse(self.firewall.should_apply_firewall_to_router(router)) - router['external_gateway_info'] = 'Dummy' - - # not for shared router: - router['router_type'] = 'shared' - router['distributed'] = False - self.assertRaises(exceptions.FirewallInternalDriverError, - self.firewall.should_apply_firewall_to_router, - router) - - # should work for distributed router - router['router_type'] = 'exclusive' - router['distributed'] = True - self.assertTrue(self.firewall.should_apply_firewall_to_router(router)) - - # not for mdproxy router: - router['name'] = 'metadata_proxy_router' - self.assertRaises(exceptions.FirewallInternalDriverError, - self.firewall.should_apply_firewall_to_router, - router) diff --git a/vmware_nsx/tests/unit/nsx_v3/test_fwaas_v1_driver.py b/vmware_nsx/tests/unit/nsx_v3/test_fwaas_v1_driver.py deleted file mode 100644 index aa70e993f4..0000000000 --- a/vmware_nsx/tests/unit/nsx_v3/test_fwaas_v1_driver.py +++ /dev/null @@ -1,370 +0,0 @@ -# Copyright 2017 VMware, Inc. -# All Rights Reserved -# -# 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 copy - -import mock -from neutron_lib.plugins import directory - -from vmware_nsx.services.fwaas.nsx_v3 import edge_fwaas_driver_base -from vmware_nsx.services.fwaas.nsx_v3 import edge_fwaas_driver_v1 as \ - edge_fwaas_driver -from vmware_nsx.services.fwaas.nsx_v3 import fwaas_callbacks_v1 -from vmware_nsx.tests.unit.nsx_v3 import test_plugin as test_v3_plugin -from vmware_nsxlib.v3 import nsx_constants as consts - -FAKE_FW_ID = 'fake_fw_uuid' -FAKE_ROUTER_ID = 'fake_rtr_uuid' -MOCK_NSX_ID = 'nsx_router_id' -FAKE_PORT_ID = 'fake_port_uuid' -FAKE_NET_ID = 'fake_net_uuid' -FAKE_NSX_PORT_ID = 'fake_nsx_port_uuid' -MOCK_DEFAULT_RULE_ID = 'nsx_default_rule_id' -MOCK_SECTION_ID = 'sec_id' -DEFAULT_RULE = {'is_default': True, - 'display_name': edge_fwaas_driver_base.DEFAULT_RULE_NAME, - 'id': MOCK_DEFAULT_RULE_ID, - 'action': consts.FW_ACTION_DROP} - - -class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin): - def setUp(self): - super(Nsxv3FwaasTestCase, self).setUp() - self.firewall = edge_fwaas_driver.EdgeFwaasV3DriverV1() - - # Start some nsxlib/DB mocks - mock.patch( - "vmware_nsxlib.v3.core_resources.NsxLibLogicalRouter." - "get_firewall_section_id", - return_value=MOCK_SECTION_ID).start() - - mock.patch( - "vmware_nsxlib.v3.security.NsxLibFirewallSection." - "get_default_rule", - return_value={'id': MOCK_DEFAULT_RULE_ID}).start() - - mock.patch( - "vmware_nsx.db.db.get_nsx_router_id", - return_value=MOCK_NSX_ID).start() - - self.plugin = directory.get_plugin() - self.plugin.fwaas_callbacks = fwaas_callbacks_v1.\ - Nsxv3FwaasCallbacksV1() - self.plugin.fwaas_callbacks.fwaas_enabled = True - self.plugin.fwaas_callbacks.fwaas_driver = self.firewall - self.plugin.fwaas_callbacks.internal_driver = self.firewall - self.plugin.init_is_complete = True - - def _default_rule(self, drop=True): - rule = DEFAULT_RULE - if drop: - rule['action'] = consts.FW_ACTION_DROP - else: - rule['action'] = consts.FW_ACTION_ALLOW - return rule - - def _fake_rules_v4(self, cidr='10.24.4.0/24'): - rule1 = {'enabled': True, - 'action': 'allow', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '80', - 'source_ip_address': cidr, - 'id': 'fake-fw-rule1', - 'description': 'first rule'} - rule2 = {'enabled': True, - 'action': 'reject', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '22:24', - 'source_port': '1:65535', - 'id': 'fake-fw-rule2'} - rule3 = {'enabled': True, - 'action': 'deny', - 'ip_version': 4, - 'protocol': 'icmp', - 'id': 'fake-fw-rule3'} - rule4 = {'enabled': True, - 'action': 'deny', - 'ip_version': 4, - 'source_ip_address': cidr, - 'id': 'fake-fw-rule4'} - return [rule1, rule2, rule3, rule4] - - def _translated_cidr(self, cidr): - if cidr is None: - return [] - else: - return [{'target_id': cidr, - 'target_type': 'IPv4Address'}] - - def _fake_translated_rules(self, logged=False, cidr='10.24.4.0/24'): - # The expected translation of the rules in _fake_rules_v4 - service1 = {'l4_protocol': 'TCP', - 'resource_type': 'L4PortSetNSService', - 'destination_ports': ['80'], - 'source_ports': []} - rule1 = {'action': 'ALLOW', - 'services': [{'service': service1}], - 'sources': self._translated_cidr(cidr), - 'display_name': 'Fwaas-fake-fw-rule1', - 'notes': 'first rule'} - service2 = {'l4_protocol': 'TCP', - 'resource_type': 'L4PortSetNSService', - 'destination_ports': ['22-24'], - 'source_ports': ['1-65535']} - rule2 = {'action': 'DROP', # Reject is replaced with deny - 'services': [{'service': service2}], - 'display_name': 'Fwaas-fake-fw-rule2'} - service3_1 = {'resource_type': 'ICMPTypeNSService', - 'protocol': 'ICMPv4'} - service3_2 = {'resource_type': 'ICMPTypeNSService', - 'protocol': 'ICMPv6'} - rule3 = {'action': 'DROP', - # icmp is translated to icmp v4 & v6 - 'services': [{'service': service3_1}, - {'service': service3_2}], - 'display_name': 'Fwaas-fake-fw-rule3'} - rule4 = {'action': 'DROP', - 'sources': self._translated_cidr(cidr), - 'display_name': 'Fwaas-fake-fw-rule4'} - - if logged: - for rule in (rule1, rule2, rule3, rule4): - rule['logged'] = logged - return [rule1, rule2, rule3, rule4] - - def _fake_firewall_no_rule(self): - rule_list = [] - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': True, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': rule_list} - return fw_inst - - def _fake_firewall(self, rule_list): - _rule_list = copy.deepcopy(rule_list) - for rule in _rule_list: - rule['position'] = str(_rule_list.index(rule)) - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': True, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': _rule_list} - return fw_inst - - def _fake_firewall_with_admin_down(self, rule_list): - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': False, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': rule_list} - return fw_inst - - def _fake_apply_list(self, router_count=1): - apply_list = [] - while router_count > 0: - router_inst = {'id': FAKE_ROUTER_ID} - router_info_inst = mock.Mock() - router_info_inst.router = router_inst - apply_list.append(router_info_inst) - router_count -= 1 - return apply_list - - def _setup_firewall_with_rules(self, func, router_count=1): - apply_list = self._fake_apply_list(router_count=router_count) - rule_list = self._fake_rules_v4() - firewall = self._fake_firewall(rule_list) - with mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." - "update") as update_fw, \ - mock.patch.object(self.plugin, '_get_router_interfaces', - return_value=[]), \ - mock.patch.object(self.plugin, 'get_ports', - return_value=[]), \ - mock.patch.object(self.plugin, 'get_router', - return_value=apply_list[0]), \ - mock.patch.object(self.plugin.fwaas_callbacks, - '_get_router_firewall_id', - return_value=firewall['id']), \ - mock.patch.object(self.plugin.fwaas_callbacks, - '_get_fw_from_plugin', - return_value=firewall): - func('nsx', apply_list, firewall) - self.assertEqual(router_count, update_fw.call_count) - update_fw.assert_called_with( - MOCK_SECTION_ID, - rules=self._fake_translated_rules() + [self._default_rule()]) - - def test_create_firewall_no_rules(self): - apply_list = self._fake_apply_list() - firewall = self._fake_firewall_no_rule() - initial_tags = [{'scope': 'xxx', 'tag': 'yyy'}] - with mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." - "update") as update_fw,\ - mock.patch.object(self.plugin, '_get_router_interfaces', - return_value=[]), \ - mock.patch.object(self.plugin, 'get_ports', - return_value=[]), \ - mock.patch.object(self.plugin, 'get_router', - return_value=apply_list[0]), \ - mock.patch.object(self.plugin.fwaas_callbacks, - '_get_router_firewall_id', - return_value=firewall['id']), \ - mock.patch.object(self.plugin.fwaas_callbacks, - '_get_fw_from_plugin', - return_value=firewall), \ - mock.patch("vmware_nsxlib.v3.core_resources.NsxLibLogicalRouter." - "update") as update_rtr,\ - mock.patch("vmware_nsxlib.v3.core_resources.NsxLibLogicalRouter." - "get", return_value={'tags': initial_tags}) as get_rtr: - self.firewall.create_firewall('nsx', apply_list, firewall) - update_fw.assert_called_once_with( - MOCK_SECTION_ID, - rules=[self._default_rule()]) - get_rtr.assert_called_once_with(MOCK_NSX_ID) - expected_tags = initial_tags - expected_tags.append({'scope': edge_fwaas_driver.NSX_FW_TAG, - 'tag': firewall['id']}) - update_rtr.assert_called_once_with(MOCK_NSX_ID, tags=expected_tags) - - def test_create_firewall_with_rules(self): - self._setup_firewall_with_rules(self.firewall.create_firewall) - - def test_create_firewall_with_rules_two_routers(self): - self._setup_firewall_with_rules(self.firewall.create_firewall, - router_count=2) - - def test_update_firewall_with_rules(self): - self._setup_firewall_with_rules(self.firewall.update_firewall) - - def test_create_firewall_with_illegal_cidr(self): - apply_list = self._fake_apply_list() - rule_list = self._fake_rules_v4(cidr='0.0.0.0/24') - firewall = self._fake_firewall(rule_list) - with mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." - "update") as update_fw, \ - mock.patch.object(self.plugin, '_get_router_interfaces', - return_value=[]), \ - mock.patch.object(self.plugin, 'get_ports', - return_value=[]), \ - mock.patch.object(self.plugin, 'get_router', - return_value=apply_list[0]), \ - mock.patch.object(self.plugin.fwaas_callbacks, - '_get_router_firewall_id', - return_value=firewall['id']), \ - mock.patch.object(self.plugin.fwaas_callbacks, - '_get_fw_from_plugin', - return_value=firewall): - self.firewall.create_firewall('nsx', apply_list, firewall) - self.assertEqual(1, update_fw.call_count) - update_fw.assert_called_with( - MOCK_SECTION_ID, - rules=(self._fake_translated_rules(cidr=None) + - [self._default_rule()])) - - def test_delete_firewall(self): - apply_list = self._fake_apply_list() - firewall = self._fake_firewall_no_rule() - initial_tags = [{'scope': 'xxx', 'tag': 'yyy'}, - {'scope': edge_fwaas_driver.NSX_FW_TAG, - 'tag': firewall['id']}] - with mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." - "update") as update_fw,\ - mock.patch.object(self.plugin, '_get_router_interfaces', - return_value=[]), \ - mock.patch.object(self.plugin, 'get_router', - return_value=apply_list[0]), \ - mock.patch.object(self.plugin.fwaas_callbacks, - '_get_router_firewall_id', - return_value=None), \ - mock.patch("vmware_nsxlib.v3.core_resources.NsxLibLogicalRouter." - "update") as update_rtr,\ - mock.patch("vmware_nsxlib.v3.core_resources.NsxLibLogicalRouter." - "get", return_value={'tags': initial_tags}) as get_rtr: - self.firewall.delete_firewall('nsx', apply_list, firewall) - update_fw.assert_called_once_with( - MOCK_SECTION_ID, - rules=[self._default_rule(drop=False)]) - get_rtr.assert_called_once_with(MOCK_NSX_ID) - expected_tags = initial_tags - expected_tags.pop() - expected_tags.append({'scope': edge_fwaas_driver.NSX_FW_TAG, - 'tag': firewall['id']}) - update_rtr.assert_called_once_with(MOCK_NSX_ID, tags=expected_tags) - - def test_create_firewall_with_admin_down(self): - apply_list = self._fake_apply_list() - rule_list = self._fake_rules_v4() - firewall = self._fake_firewall_with_admin_down(rule_list) - with mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." - "update") as update_fw, \ - mock.patch.object(self.plugin, '_get_router_interfaces', - return_value=[]), \ - mock.patch.object(self.plugin, 'get_ports', - return_value=[]), \ - mock.patch.object(self.plugin, 'get_router', - return_value=apply_list[0]), \ - mock.patch.object(self.plugin.fwaas_callbacks, - '_get_router_firewall_id', - return_value=firewall['id']), \ - mock.patch.object(self.plugin.fwaas_callbacks, - '_get_fw_from_plugin', - return_value=firewall): - self.firewall.create_firewall('nsx', apply_list, firewall) - update_fw.assert_called_once_with( - MOCK_SECTION_ID, - rules=[self._default_rule()]) - - def test_create_firewall_with_dhcp_relay(self): - apply_list = self._fake_apply_list() - firewall = self._fake_firewall_no_rule() - relay_server = '1.1.1.1' - port = {'id': FAKE_PORT_ID, 'network_id': FAKE_NET_ID} - with mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." - "update") as update_fw,\ - mock.patch.object(self.plugin, '_get_router_interfaces', - return_value=[port]), \ - mock.patch.object(self.plugin, 'get_ports', - return_value=[port]), \ - mock.patch.object(self.plugin, 'get_router', - return_value=apply_list[0]), \ - mock.patch.object(self.plugin, '_get_port_relay_servers', - return_value=[relay_server]),\ - mock.patch.object(self.plugin.fwaas_callbacks, - '_get_router_firewall_id', - return_value=firewall['id']), \ - mock.patch.object(self.plugin.fwaas_callbacks, - '_get_fw_from_plugin', - return_value=firewall): - self.firewall.create_firewall('nsx', apply_list, firewall) - # expecting 2 allow rules for the relay servers + default rule - expected_rules = expected_rules = [ - {'display_name': "DHCP Relay ingress traffic", - 'action': consts.FW_ACTION_ALLOW, - 'destinations': None, - 'sources': [{'target_id': relay_server, - 'target_type': 'IPv4Address'}], - 'services': self.plugin._get_port_relay_services(), - 'direction': 'IN'}, - {'display_name': "DHCP Relay egress traffic", - 'action': consts.FW_ACTION_ALLOW, - 'sources': None, - 'destinations': [{'target_id': relay_server, - 'target_type': 'IPv4Address'}], - 'services': self.plugin._get_port_relay_services(), - 'direction': 'OUT'}, - self._default_rule() - ] - update_fw.assert_called_once_with( - MOCK_SECTION_ID, - rules=expected_rules)