NSX|V3: Add DHCP relay firewall rules
When FWaaS v1 or v2 are used, there is a need to add FW rules to allow the dhcp traffic to the relay server. Those rules are added to the firewall before the default deny rule. In case of FWaaS v2 - for each port separately. The admin utility handling a change in the DHCP relay configuration will now update the rules as well. Change-Id: I30e666085fe5cdf17d48984518c73f79bf8cdf55
This commit is contained in:
parent
afdb9ea7ac
commit
96c1e57a7f
@ -181,7 +181,7 @@ class NsxV3AvailabilityZone(common_az.ConfiguredAvailabilityZone):
|
|||||||
nsxlib.feature_supported(nsxlib_consts.FEATURE_DHCP_RELAY)):
|
nsxlib.feature_supported(nsxlib_consts.FEATURE_DHCP_RELAY)):
|
||||||
relay_id = None
|
relay_id = None
|
||||||
if cfg.CONF.nsx_v3.init_objects_by_tags:
|
if cfg.CONF.nsx_v3.init_objects_by_tags:
|
||||||
# Find the TZ by its tag
|
# Find the relay service by its tag
|
||||||
relay_id = nsxlib.get_id_by_resource_and_tag(
|
relay_id = nsxlib.get_id_by_resource_and_tag(
|
||||||
nsxlib.relay_service.resource_type,
|
nsxlib.relay_service.resource_type,
|
||||||
cfg.CONF.nsx_v3.search_objects_scope,
|
cfg.CONF.nsx_v3.search_objects_scope,
|
||||||
@ -191,8 +191,13 @@ class NsxV3AvailabilityZone(common_az.ConfiguredAvailabilityZone):
|
|||||||
relay_id = nsxlib.relay_service.get_id_by_name_or_id(
|
relay_id = nsxlib.relay_service.get_id_by_name_or_id(
|
||||||
self.dhcp_relay_service)
|
self.dhcp_relay_service)
|
||||||
self.dhcp_relay_service = relay_id
|
self.dhcp_relay_service = relay_id
|
||||||
|
# if there is a relay service - also find the server ips
|
||||||
|
if self.dhcp_relay_service:
|
||||||
|
self.dhcp_relay_servers = nsxlib.relay_service.get_server_ips(
|
||||||
|
self.dhcp_relay_service)
|
||||||
else:
|
else:
|
||||||
self.dhcp_relay_service = None
|
self.dhcp_relay_service = None
|
||||||
|
self.dhcp_relay_servers = None
|
||||||
|
|
||||||
|
|
||||||
class NsxV3AvailabilityZones(common_az.ConfiguredAvailabilityZones):
|
class NsxV3AvailabilityZones(common_az.ConfiguredAvailabilityZones):
|
||||||
|
@ -3305,6 +3305,26 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
return self.fwaas_callbacks.update_router_firewall(
|
return self.fwaas_callbacks.update_router_firewall(
|
||||||
context, self.nsxlib, router_id, ports)
|
context, self.nsxlib, router_id, ports)
|
||||||
|
|
||||||
|
def _get_port_relay_servers(self, context, port_id, network_id=None):
|
||||||
|
if not network_id:
|
||||||
|
port = self.get_port(context, port_id)
|
||||||
|
network_id = port['network_id']
|
||||||
|
net_az = self.get_network_az_by_net_id(context, network_id)
|
||||||
|
return net_az.dhcp_relay_servers
|
||||||
|
|
||||||
|
def _get_port_relay_services(self):
|
||||||
|
# DHCP services: UDP 67, 68, 2535
|
||||||
|
#TODO(asarfaty): use configurable ports
|
||||||
|
service1 = self.nsxlib.firewall_section.get_nsservice(
|
||||||
|
nsxlib_consts.L4_PORT_SET_NSSERVICE,
|
||||||
|
l4_protocol=nsxlib_consts.UDP,
|
||||||
|
destination_ports=['67-68'])
|
||||||
|
service2 = self.nsxlib.firewall_section.get_nsservice(
|
||||||
|
nsxlib_consts.L4_PORT_SET_NSSERVICE,
|
||||||
|
l4_protocol=nsxlib_consts.UDP,
|
||||||
|
destination_ports=['2535'])
|
||||||
|
return [service1, service2]
|
||||||
|
|
||||||
def get_extra_fw_rules(self, context, router_id, port_id=None):
|
def get_extra_fw_rules(self, context, router_id, port_id=None):
|
||||||
"""Return firewall rules that should be added to the router firewall
|
"""Return firewall rules that should be added to the router firewall
|
||||||
|
|
||||||
@ -3317,8 +3337,59 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
port should be returned, and the rules should be ingress/egress
|
port should be returned, and the rules should be ingress/egress
|
||||||
(but not both) and include the source/dest nsx logical port.
|
(but not both) and include the source/dest nsx logical port.
|
||||||
"""
|
"""
|
||||||
#TODO(asarfaty): DHCP relay rules
|
extra_rules = []
|
||||||
return []
|
# DHCP relay rules:
|
||||||
|
# get the list of relevant relay servers
|
||||||
|
elv_ctx = context.elevated()
|
||||||
|
if port_id:
|
||||||
|
relay_servers = self._get_port_relay_servers(elv_ctx, port_id)
|
||||||
|
else:
|
||||||
|
relay_servers = []
|
||||||
|
filters = {'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF],
|
||||||
|
'device_id': [router_id]}
|
||||||
|
ports = self.get_ports(elv_ctx, filters=filters)
|
||||||
|
for port in ports:
|
||||||
|
port_relay_servers = self._get_port_relay_servers(
|
||||||
|
elv_ctx, port['id'], network_id=port['network_id'])
|
||||||
|
if port_relay_servers:
|
||||||
|
relay_servers.extend(port_relay_servers)
|
||||||
|
|
||||||
|
# Add rules to allow dhcp traffic relay servers
|
||||||
|
if relay_servers:
|
||||||
|
# if it is a single port, the source/dest is this logical port
|
||||||
|
if port_id:
|
||||||
|
_net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
|
||||||
|
context.session, port_id)
|
||||||
|
port_target = [{'target_type': 'LogicalPort',
|
||||||
|
'target_id': nsx_port_id}]
|
||||||
|
else:
|
||||||
|
port_target = None
|
||||||
|
# translate the relay server ips to the firewall format
|
||||||
|
relay_target = []
|
||||||
|
if self.fwaas_callbacks:
|
||||||
|
relay_target = (self.fwaas_callbacks.fwaas_driver.
|
||||||
|
translate_addresses_to_target(set(relay_servers)))
|
||||||
|
|
||||||
|
dhcp_services = self._get_port_relay_services()
|
||||||
|
|
||||||
|
# ingress rule
|
||||||
|
extra_rules.append({
|
||||||
|
'display_name': "DHCP Relay ingress traffic",
|
||||||
|
'action': nsxlib_consts.FW_ACTION_ALLOW,
|
||||||
|
'sources': relay_target,
|
||||||
|
'destinations': port_target,
|
||||||
|
'services': dhcp_services,
|
||||||
|
'direction': 'IN'})
|
||||||
|
# egress rule
|
||||||
|
extra_rules.append({
|
||||||
|
'display_name': "DHCP Relay egress traffic",
|
||||||
|
'action': nsxlib_consts.FW_ACTION_ALLOW,
|
||||||
|
'destinations': relay_target,
|
||||||
|
'sources': port_target,
|
||||||
|
'services': dhcp_services,
|
||||||
|
'direction': 'OUT'})
|
||||||
|
|
||||||
|
return extra_rules
|
||||||
|
|
||||||
def _get_ports_and_address_groups(self, context, router_id, network_id,
|
def _get_ports_and_address_groups(self, context, router_id, network_id,
|
||||||
exclude_sub_ids=None):
|
exclude_sub_ids=None):
|
||||||
|
@ -98,7 +98,7 @@ class CommonEdgeFwaasV3Driver(fwaas_base.FwaasDriverBase):
|
|||||||
cidr,
|
cidr,
|
||||||
consts.IPV6 if netaddr.valid_ipv6(cidr) else consts.IPV4)
|
consts.IPV6 if netaddr.valid_ipv6(cidr) else consts.IPV4)
|
||||||
|
|
||||||
def _translate_addresses(self, cidrs):
|
def translate_addresses_to_target(self, cidrs):
|
||||||
return [self._translate_cidr(ip) for ip in cidrs]
|
return [self._translate_cidr(ip) for ip in cidrs]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -170,7 +170,7 @@ class CommonEdgeFwaasV3Driver(fwaas_base.FwaasDriverBase):
|
|||||||
'target_id': replace_dest}]
|
'target_id': replace_dest}]
|
||||||
nsx_rule['direction'] = 'IN'
|
nsx_rule['direction'] = 'IN'
|
||||||
elif rule.get('destination_ip_address'):
|
elif rule.get('destination_ip_address'):
|
||||||
nsx_rule['destinations'] = self._translate_addresses(
|
nsx_rule['destinations'] = self.translate_addresses_to_target(
|
||||||
[rule['destination_ip_address']])
|
[rule['destination_ip_address']])
|
||||||
if replace_src:
|
if replace_src:
|
||||||
# set this value as the source logical port,
|
# set this value as the source logical port,
|
||||||
@ -179,7 +179,7 @@ class CommonEdgeFwaasV3Driver(fwaas_base.FwaasDriverBase):
|
|||||||
'target_id': replace_src}]
|
'target_id': replace_src}]
|
||||||
nsx_rule['direction'] = 'OUT'
|
nsx_rule['direction'] = 'OUT'
|
||||||
elif rule.get('source_ip_address'):
|
elif rule.get('source_ip_address'):
|
||||||
nsx_rule['sources'] = self._translate_addresses(
|
nsx_rule['sources'] = self.translate_addresses_to_target(
|
||||||
[rule['source_ip_address']])
|
[rule['source_ip_address']])
|
||||||
if rule.get('protocol'):
|
if rule.get('protocol'):
|
||||||
nsx_rule['services'] = self._translate_services(rule)
|
nsx_rule['services'] = self._translate_services(rule)
|
||||||
|
@ -53,7 +53,6 @@ class Nsxv3FwaasCallbacksV1(com_clbcks.NsxFwaasCallbacks):
|
|||||||
This method should be called on FWaaS updates, and on router
|
This method should be called on FWaaS updates, and on router
|
||||||
interfaces changes.
|
interfaces changes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# find the backend router and its firewall section
|
# find the backend router and its firewall section
|
||||||
nsx_id, sect_id = self.fwaas_driver.get_backend_router_and_fw_section(
|
nsx_id, sect_id = self.fwaas_driver.get_backend_router_and_fw_section(
|
||||||
context, router_id)
|
context, router_id)
|
||||||
|
@ -188,27 +188,37 @@ def update_dhcp_relay(resource, event, trigger, **kwargs):
|
|||||||
# initialize the availability zones and nsxlib
|
# initialize the availability zones and nsxlib
|
||||||
config.register_nsxv3_azs(cfg.CONF, cfg.CONF.nsx_v3.availability_zones)
|
config.register_nsxv3_azs(cfg.CONF, cfg.CONF.nsx_v3.availability_zones)
|
||||||
|
|
||||||
# get all neutron router interfaces ports
|
|
||||||
admin_cxt = neutron_context.get_admin_context()
|
admin_cxt = neutron_context.get_admin_context()
|
||||||
with utils.NsxV3PluginWrapper() as plugin:
|
with utils.NsxV3PluginWrapper() as plugin:
|
||||||
filters = {'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF]}
|
# Make sure FWaaS was initialized
|
||||||
ports = plugin.get_ports(admin_cxt, filters=filters)
|
plugin.init_fwaas_for_admin_utils()
|
||||||
for port in ports:
|
|
||||||
# get the backend router port by the tag
|
# get all neutron routers and interfaces ports
|
||||||
nsx_port_id = nsxlib.get_id_by_resource_and_tag(
|
routers = plugin.get_routers(admin_cxt)
|
||||||
'LogicalRouterDownLinkPort',
|
for router in routers:
|
||||||
'os-neutron-rport-id', port['id'])
|
LOG.info("Updating router %s", router['id'])
|
||||||
if not nsx_port_id:
|
filters = {'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF],
|
||||||
LOG.warning("Couldn't find nsx router port for interface %s",
|
'device_id': [router['id']]}
|
||||||
port['id'])
|
ports = plugin.get_ports(admin_cxt, filters=filters)
|
||||||
continue
|
for port in ports:
|
||||||
# get the network of this port
|
# get the backend router port by the tag
|
||||||
network_id = port['network_id']
|
nsx_port_id = nsxlib.get_id_by_resource_and_tag(
|
||||||
# check the relay service on the az of the network
|
'LogicalRouterDownLinkPort',
|
||||||
az = plugin.get_network_az_by_net_id(admin_cxt, network_id)
|
'os-neutron-rport-id', port['id'])
|
||||||
nsxlib.logical_router_port.update(
|
if not nsx_port_id:
|
||||||
nsx_port_id, relay_service_uuid=az.dhcp_relay_service)
|
LOG.warning("Couldn't find nsx router port for interface "
|
||||||
#TODO(asarfaty) also update the firewall rules of the routers
|
"%s", port['id'])
|
||||||
|
continue
|
||||||
|
# get the network of this port
|
||||||
|
network_id = port['network_id']
|
||||||
|
# check the relay service on the az of the network
|
||||||
|
az = plugin.get_network_az_by_net_id(admin_cxt, network_id)
|
||||||
|
nsxlib.logical_router_port.update(
|
||||||
|
nsx_port_id, relay_service_uuid=az.dhcp_relay_service)
|
||||||
|
|
||||||
|
# if FWaaS is enables, also update the firewall rules
|
||||||
|
plugin.update_router_firewall(admin_cxt, router['id'])
|
||||||
|
|
||||||
LOG.info("Done.")
|
LOG.info("Done.")
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,14 +13,22 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
from neutron.db import db_base_plugin_v2
|
from neutron.db import db_base_plugin_v2
|
||||||
|
from neutron import manager
|
||||||
from neutron_lib import context
|
from neutron_lib import context
|
||||||
from neutron_lib.plugins import constants as const
|
from neutron_lib.plugins import constants as const
|
||||||
from neutron_lib.plugins import directory
|
from neutron_lib.plugins import directory
|
||||||
|
|
||||||
|
from neutron_fwaas.services.firewall import fwaas_plugin as fwaas_plugin_v1
|
||||||
|
from neutron_fwaas.services.firewall import fwaas_plugin_v2
|
||||||
|
|
||||||
from vmware_nsx.db import db as nsx_db
|
from vmware_nsx.db import db as nsx_db
|
||||||
from vmware_nsx.plugins.nsx_v3 import plugin
|
from vmware_nsx.plugins.nsx_v3 import plugin
|
||||||
from vmware_nsx.plugins.nsx_v3 import utils as v3_utils
|
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_nsxlib.v3 import nsx_constants
|
from vmware_nsxlib.v3 import nsx_constants
|
||||||
|
|
||||||
_NSXLIB = None
|
_NSXLIB = None
|
||||||
@ -107,6 +115,35 @@ class NsxV3PluginWrapper(plugin.NsxV3Plugin):
|
|||||||
def __exit__(self, exc_type, exc_value, traceback):
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
directory.add_plugin(const.CORE, None)
|
directory.add_plugin(const.CORE, None)
|
||||||
|
|
||||||
|
def _init_fwaas_plugin(self, provider, callbacks_class, plugin_callbacks):
|
||||||
|
fwaas_plugin_class = manager.NeutronManager.load_class_for_provider(
|
||||||
|
'neutron.service_plugins', provider)
|
||||||
|
fwaas_plugin = fwaas_plugin_class()
|
||||||
|
self.fwaas_callbacks = callbacks_class(self.nsxlib)
|
||||||
|
# override the fwplugin_rpc since there is no RPC support in adminutils
|
||||||
|
self.fwaas_callbacks.fwplugin_rpc = plugin_callbacks(fwaas_plugin)
|
||||||
|
|
||||||
|
def init_fwaas_for_admin_utils(self):
|
||||||
|
# initialize the FWaaS plugin and callbacks
|
||||||
|
self.fwaas_callbacks = None
|
||||||
|
# This is an ugly patch to find out if it is v1 or v2
|
||||||
|
service_plugins = cfg.CONF.service_plugins
|
||||||
|
for srv_plugin in service_plugins:
|
||||||
|
if 'firewall' in srv_plugin:
|
||||||
|
if 'v2' in srv_plugin:
|
||||||
|
# FWaaS V2
|
||||||
|
self._init_fwaas_plugin(
|
||||||
|
'firewall_v2',
|
||||||
|
fwaas_callbacks_v2.Nsxv3FwaasCallbacksV2,
|
||||||
|
fwaas_plugin_v2.FirewallCallbacks)
|
||||||
|
else:
|
||||||
|
# FWaaS V1
|
||||||
|
self._init_fwaas_plugin(
|
||||||
|
'firewall',
|
||||||
|
fwaas_callbacks_v1.Nsxv3FwaasCallbacksV1,
|
||||||
|
fwaas_plugin_v1.FirewallCallbacks)
|
||||||
|
return
|
||||||
|
|
||||||
def _init_dhcp_metadata(self):
|
def _init_dhcp_metadata(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -29,6 +29,9 @@ from vmware_nsxlib.v3 import nsx_constants as consts
|
|||||||
FAKE_FW_ID = 'fake_fw_uuid'
|
FAKE_FW_ID = 'fake_fw_uuid'
|
||||||
FAKE_ROUTER_ID = 'fake_rtr_uuid'
|
FAKE_ROUTER_ID = 'fake_rtr_uuid'
|
||||||
MOCK_NSX_ID = 'nsx_router_id'
|
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_DEFAULT_RULE_ID = 'nsx_default_rule_id'
|
||||||
MOCK_SECTION_ID = 'sec_id'
|
MOCK_SECTION_ID = 'sec_id'
|
||||||
DEFAULT_RULE = {'is_default': True,
|
DEFAULT_RULE = {'is_default': True,
|
||||||
@ -177,6 +180,8 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin):
|
|||||||
"update") as update_fw, \
|
"update") as update_fw, \
|
||||||
mock.patch.object(self.plugin, '_get_router_interfaces',
|
mock.patch.object(self.plugin, '_get_router_interfaces',
|
||||||
return_value=[]), \
|
return_value=[]), \
|
||||||
|
mock.patch.object(self.plugin, 'get_ports',
|
||||||
|
return_value=[]), \
|
||||||
mock.patch.object(self.plugin, 'get_router',
|
mock.patch.object(self.plugin, 'get_router',
|
||||||
return_value=apply_list[0]), \
|
return_value=apply_list[0]), \
|
||||||
mock.patch.object(self.plugin.fwaas_callbacks,
|
mock.patch.object(self.plugin.fwaas_callbacks,
|
||||||
@ -199,6 +204,8 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin):
|
|||||||
"update") as update_fw,\
|
"update") as update_fw,\
|
||||||
mock.patch.object(self.plugin, '_get_router_interfaces',
|
mock.patch.object(self.plugin, '_get_router_interfaces',
|
||||||
return_value=[]), \
|
return_value=[]), \
|
||||||
|
mock.patch.object(self.plugin, 'get_ports',
|
||||||
|
return_value=[]), \
|
||||||
mock.patch.object(self.plugin, 'get_router',
|
mock.patch.object(self.plugin, 'get_router',
|
||||||
return_value=apply_list[0]), \
|
return_value=apply_list[0]), \
|
||||||
mock.patch.object(self.plugin.fwaas_callbacks,
|
mock.patch.object(self.plugin.fwaas_callbacks,
|
||||||
@ -269,6 +276,8 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin):
|
|||||||
"update") as update_fw, \
|
"update") as update_fw, \
|
||||||
mock.patch.object(self.plugin, '_get_router_interfaces',
|
mock.patch.object(self.plugin, '_get_router_interfaces',
|
||||||
return_value=[]), \
|
return_value=[]), \
|
||||||
|
mock.patch.object(self.plugin, 'get_ports',
|
||||||
|
return_value=[]), \
|
||||||
mock.patch.object(self.plugin, 'get_router',
|
mock.patch.object(self.plugin, 'get_router',
|
||||||
return_value=apply_list[0]), \
|
return_value=apply_list[0]), \
|
||||||
mock.patch.object(self.plugin.fwaas_callbacks,
|
mock.patch.object(self.plugin.fwaas_callbacks,
|
||||||
@ -281,3 +290,47 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin):
|
|||||||
update_fw.assert_called_once_with(
|
update_fw.assert_called_once_with(
|
||||||
MOCK_SECTION_ID,
|
MOCK_SECTION_ID,
|
||||||
rules=[self._default_rule()])
|
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)
|
||||||
|
@ -29,6 +29,7 @@ from vmware_nsxlib.v3 import nsx_constants as consts
|
|||||||
FAKE_FW_ID = 'fake_fw_uuid'
|
FAKE_FW_ID = 'fake_fw_uuid'
|
||||||
FAKE_ROUTER_ID = 'fake_rtr_uuid'
|
FAKE_ROUTER_ID = 'fake_rtr_uuid'
|
||||||
FAKE_PORT_ID = 'fake_port_uuid'
|
FAKE_PORT_ID = 'fake_port_uuid'
|
||||||
|
FAKE_NET_ID = 'fake_net_uuid'
|
||||||
FAKE_NSX_PORT_ID = 'fake_nsx_port_uuid'
|
FAKE_NSX_PORT_ID = 'fake_nsx_port_uuid'
|
||||||
MOCK_NSX_ID = 'nsx_nsx_router_id'
|
MOCK_NSX_ID = 'nsx_nsx_router_id'
|
||||||
MOCK_DEFAULT_RULE_ID = 'nsx_default_rule_id'
|
MOCK_DEFAULT_RULE_ID = 'nsx_default_rule_id'
|
||||||
@ -191,9 +192,11 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin):
|
|||||||
def test_create_firewall_no_rules(self):
|
def test_create_firewall_no_rules(self):
|
||||||
apply_list = self._fake_apply_list()
|
apply_list = self._fake_apply_list()
|
||||||
firewall = self._fake_empty_firewall_group()
|
firewall = self._fake_empty_firewall_group()
|
||||||
port = {'id': FAKE_PORT_ID}
|
port = {'id': FAKE_PORT_ID, 'network_id': FAKE_NET_ID}
|
||||||
with mock.patch.object(self.plugin, '_get_router_interfaces',
|
with mock.patch.object(self.plugin, '_get_router_interfaces',
|
||||||
return_value=[port]),\
|
return_value=[port]),\
|
||||||
|
mock.patch.object(self.plugin, 'get_port',
|
||||||
|
return_value=port),\
|
||||||
mock.patch.object(self.plugin.fwaas_callbacks, 'get_port_fwg',
|
mock.patch.object(self.plugin.fwaas_callbacks, 'get_port_fwg',
|
||||||
return_value=firewall),\
|
return_value=firewall),\
|
||||||
mock.patch("vmware_nsx.db.db.get_nsx_switch_and_port_id",
|
mock.patch("vmware_nsx.db.db.get_nsx_switch_and_port_id",
|
||||||
@ -224,9 +227,11 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin):
|
|||||||
apply_list = self._fake_apply_list()
|
apply_list = self._fake_apply_list()
|
||||||
rule_list = self._fake_rules_v4(is_ingress=is_ingress)
|
rule_list = self._fake_rules_v4(is_ingress=is_ingress)
|
||||||
firewall = self._fake_firewall_group(rule_list, is_ingress=is_ingress)
|
firewall = self._fake_firewall_group(rule_list, is_ingress=is_ingress)
|
||||||
port = {'id': FAKE_PORT_ID}
|
port = {'id': FAKE_PORT_ID, 'network_id': FAKE_NET_ID}
|
||||||
with mock.patch.object(self.plugin, '_get_router_interfaces',
|
with mock.patch.object(self.plugin, '_get_router_interfaces',
|
||||||
return_value=[port]),\
|
return_value=[port]),\
|
||||||
|
mock.patch.object(self.plugin, 'get_port',
|
||||||
|
return_value=port),\
|
||||||
mock.patch.object(self.plugin.fwaas_callbacks, 'get_port_fwg',
|
mock.patch.object(self.plugin.fwaas_callbacks, 'get_port_fwg',
|
||||||
return_value=firewall),\
|
return_value=firewall),\
|
||||||
mock.patch("vmware_nsx.db.db.get_nsx_switch_and_port_id",
|
mock.patch("vmware_nsx.db.db.get_nsx_switch_and_port_id",
|
||||||
@ -302,3 +307,57 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin):
|
|||||||
update_fw.assert_called_once_with(
|
update_fw.assert_called_once_with(
|
||||||
MOCK_SECTION_ID,
|
MOCK_SECTION_ID,
|
||||||
rules=[self._default_rule()])
|
rules=[self._default_rule()])
|
||||||
|
|
||||||
|
def test_create_firewall_with_dhcp_relay(self):
|
||||||
|
apply_list = self._fake_apply_list()
|
||||||
|
firewall = self._fake_empty_firewall_group()
|
||||||
|
port = {'id': FAKE_PORT_ID, 'network_id': FAKE_NET_ID}
|
||||||
|
relay_server = '1.1.1.1'
|
||||||
|
with mock.patch.object(self.plugin, '_get_router_interfaces',
|
||||||
|
return_value=[port]),\
|
||||||
|
mock.patch.object(self.plugin, 'get_port',
|
||||||
|
return_value=port),\
|
||||||
|
mock.patch.object(self.plugin, '_get_port_relay_servers',
|
||||||
|
return_value=[relay_server]),\
|
||||||
|
mock.patch.object(self.plugin.fwaas_callbacks, 'get_port_fwg',
|
||||||
|
return_value=firewall),\
|
||||||
|
mock.patch("vmware_nsx.db.db.get_nsx_switch_and_port_id",
|
||||||
|
return_value=(0, FAKE_NSX_PORT_ID)),\
|
||||||
|
mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection."
|
||||||
|
"update") as update_fw:
|
||||||
|
self.firewall.create_firewall_group('nsx', apply_list, firewall)
|
||||||
|
# expecting 2 allow rules for the relay servers,
|
||||||
|
# 2 block rules for the logical port (egress & ingress)
|
||||||
|
# and last default allow all rule
|
||||||
|
expected_rules = [
|
||||||
|
{'display_name': "DHCP Relay ingress traffic",
|
||||||
|
'action': consts.FW_ACTION_ALLOW,
|
||||||
|
'destinations': [{'target_type': 'LogicalPort',
|
||||||
|
'target_id': FAKE_NSX_PORT_ID}],
|
||||||
|
'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': [{'target_type': 'LogicalPort',
|
||||||
|
'target_id': FAKE_NSX_PORT_ID}],
|
||||||
|
'destinations': [{'target_id': relay_server,
|
||||||
|
'target_type': 'IPv4Address'}],
|
||||||
|
'services': self.plugin._get_port_relay_services(),
|
||||||
|
'direction': 'OUT'},
|
||||||
|
{'display_name': "Block port ingress",
|
||||||
|
'action': consts.FW_ACTION_DROP,
|
||||||
|
'destinations': [{'target_type': 'LogicalPort',
|
||||||
|
'target_id': FAKE_NSX_PORT_ID}],
|
||||||
|
'direction': 'IN'},
|
||||||
|
{'display_name': "Block port egress",
|
||||||
|
'action': consts.FW_ACTION_DROP,
|
||||||
|
'sources': [{'target_type': 'LogicalPort',
|
||||||
|
'target_id': FAKE_NSX_PORT_ID}],
|
||||||
|
'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