Merge "Remove FWaaS V1 code"

This commit is contained in:
Zuul 2019-02-05 08:10:16 +00:00 committed by Gerrit Code Review
commit b72c03449e
16 changed files with 9 additions and 1590 deletions

View File

@ -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
~~~~~~~~~~~~~~~~~

View File

@ -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

View File

@ -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'])

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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)

View File

@ -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 []

View File

@ -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 []

View File

@ -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 []

View File

@ -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

View File

@ -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):

View File

@ -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)

View File

@ -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)