Remove FWaaS V1 code
FWaaS is about to be removed from neutron, and should be removed from vmware_nsx as well. Change-Id: I6e621e63896dc6a6e6bbacc464c79319fce1f92d
This commit is contained in:
parent
e3613af0a1
commit
df47dde1cc
@ -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
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
@ -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
|
||||
|
@ -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'])
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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)
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)
|
@ -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)
|
@ -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 []
|
@ -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 []
|
@ -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 []
|
@ -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
|
@ -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):
|
||||
|
@ -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)
|
@ -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)
|
Loading…
Reference in New Issue
Block a user