NSXV3: ensure all OS ports are added to default section

Enable different application to use the NSX and not have the
default section discard all traffic on ports not owned by OpenStack.

This ensures that all openstack ports are added to the default group.

A admin utility has been added to enabled the migration:
nsxadmin -r ports -o nsx-tag-default

Change-Id: I2572241ec1906ee396b61f520e8e860799367f5b
This commit is contained in:
Gary Kotton 2017-05-11 13:56:46 -07:00
parent 699c44ca39
commit 427cf1ff94
4 changed files with 92 additions and 3 deletions

View File

@ -257,6 +257,10 @@ Ports
nsxadmin -r ports -o migrate-exclude-ports
- Tag ports to be part of the default OS security group::
nsxadmin -r ports -o nsx-tag-default
Security Groups & NSX Security Groups
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -112,6 +112,8 @@ NSX_V3_NO_PSEC_PROFILE_NAME = 'nsx-default-spoof-guard-vif-profile'
NSX_V3_DHCP_PROFILE_NAME = 'neutron_port_dhcp_profile'
NSX_V3_MAC_LEARNING_PROFILE_NAME = 'neutron_port_mac_learning_profile'
NSX_V3_FW_DEFAULT_SECTION = 'OS Default Section for Neutron Security-Groups'
NSX_V3_FW_DEFAULT_NS_GROUP = 'os_default_section_ns_group'
NSX_V3_DEFAULT_SECTION = 'OS-Default-Section'
NSX_V3_EXCLUDED_PORT_NSGROUP_NAME = 'neutron_excluded_port_nsgroup'
@ -205,6 +207,15 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
self._translate_configured_names_to_uuids()
self._init_dhcp_metadata()
# Include default section NSGroup
LOG.debug("Initializing NSX v3 default section NSGroup")
self._default_section_nsgroup = None
self._default_section_nsgroup = self._init_default_section_nsgroup()
if not self._default_section_nsgroup:
msg = _("Unable to initialize NSX v3 default section NSGroup %s"
) % NSX_V3_FW_DEFAULT_NS_GROUP
raise nsx_exc.NsxPluginException(err_msg=msg)
self.default_section = self._init_default_section_rules()
self._process_security_group_logging()
self._routerlib = router.RouterLib(self.nsxlib.logical_router,
@ -313,6 +324,30 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
'nsx-logical-switch-id':
self._get_network_nsx_id(context, port_data['network_id'])}
@nsxlib_utils.retry_upon_exception(
Exception, max_attempts=cfg.CONF.nsx_v3.retries)
def _init_default_section_nsgroup(self):
with locking.LockManager.get_lock('nsxv3_init_default_nsgroup'):
nsgroup = self._get_default_section_nsgroup()
if not nsgroup:
# Create a new NSGroup for default section
membership_criteria = (
self.nsxlib.ns_group.get_port_tag_expression(
security.PORT_SG_SCOPE, NSX_V3_DEFAULT_SECTION))
nsgroup = self.nsxlib.ns_group.create(
NSX_V3_FW_DEFAULT_NS_GROUP,
'OS Default Section Port NSGroup',
tags=self.nsxlib.build_v3_api_version_tag(),
membership_criteria=membership_criteria)
return self._get_default_section_nsgroup()
def _get_default_section_nsgroup(self):
if self._default_section_nsgroup:
return self._default_section_nsgroup
nsgroups = self.nsxlib.ns_group.find_by_display_name(
NSX_V3_FW_DEFAULT_NS_GROUP)
return nsgroups[0] if nsgroups else None
@nsxlib_utils.retry_upon_exception(
Exception, max_attempts=cfg.CONF.nsx_v3.retries)
def _init_excluded_port_nsgroup(self):
@ -465,7 +500,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
section_description = ("This section is handled by OpenStack to "
"contain default rules on security-groups.")
section_id = self.nsxlib.firewall_section.init_default(
NSX_V3_FW_DEFAULT_SECTION, section_description, [],
NSX_V3_FW_DEFAULT_SECTION, section_description,
[self._default_section_nsgroup.get('id')],
cfg.CONF.nsx_v3.log_security_groups_blocked_traffic)
return section_id
@ -1541,14 +1577,18 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
'tag': nsxlib_consts.EXCLUDE_PORT})
else:
add_to_exclude_list = True
if utils.is_nsx_version_1_1_0(self._nsx_version):
elif utils.is_nsx_version_1_1_0(self._nsx_version):
# If port has no security-groups then we don't need to add any
# security criteria tag.
if port_data[ext_sg.SECURITYGROUPS]:
tags += self.nsxlib.ns_group.get_lport_tags(
port_data[ext_sg.SECURITYGROUPS] +
port_data[provider_sg.PROVIDER_SECURITYGROUPS])
# Add port to the default list
if (device_owner != l3_db.DEVICE_OWNER_ROUTER_INTF and
device_owner != const.DEVICE_OWNER_DHCP):
tags.append({'scope': security.PORT_SG_SCOPE,
'tag': NSX_V3_DEFAULT_SECTION})
parent_name, tag = self._get_data_from_binding_profile(
context, port_data)
@ -2322,6 +2362,10 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
tags_update += self.nsxlib.ns_group.get_lport_tags(
updated_port.get(ext_sg.SECURITYGROUPS, []) +
updated_port.get(provider_sg.PROVIDER_SECURITYGROUPS, []))
# Only set the default section tag if there is no port security
if not updated_excluded:
tags_update.append({'scope': security.PORT_SG_SCOPE,
'tag': NSX_V3_DEFAULT_SECTION})
else:
self._update_lport_with_security_groups(
context, lport_id,

View File

@ -35,6 +35,7 @@ from vmware_nsxlib.v3 import security
from neutron.db import allowedaddresspairs_db as addr_pair_db
from neutron.db import db_base_plugin_v2
from neutron.db import l3_db
from neutron.db import portsecurity_db
from neutron.extensions import allowedaddresspairs
from neutron_lib.callbacks import registry
@ -320,6 +321,39 @@ def migrate_exclude_ports(resource, event, trigger, **kwargs):
LOG.info("Port %s successfully updated", port_id)
def tag_default_ports(resource, event, trigger, **kwargs):
nsxlib = v3_utils.get_connected_nsxlib()
admin_cxt = neutron_context.get_admin_context()
# the plugin creation below will create the NS group and update the default
# OS section to have the correct applied to group
with v3_utils.NsxV3PluginWrapper() as _plugin:
neutron_ports = _plugin.get_ports(admin_cxt)
for port in neutron_ports:
neutron_id = port['id']
# get the network nsx id from the mapping table
nsx_id = get_port_nsx_id(admin_cxt.session, neutron_id)
if not nsx_id:
continue
device_owner = port['device_owner']
if (device_owner == l3_db.DEVICE_OWNER_ROUTER_INTF or
device_owner == const.DEVICE_OWNER_DHCP):
continue
ps = _plugin._get_port_security_binding(admin_cxt,
neutron_id)
if not ps:
continue
try:
nsx_port = nsxlib.logical_port.get(nsx_id)
except nsx_exc.ResourceNotFound:
continue
tags_update = nsx_port['tags']
tags_update += [{'scope': security.PORT_SG_SCOPE,
'tag': plugin.NSX_V3_DEFAULT_SECTION}]
nsxlib.logical_port.update(nsx_id, None,
tags_update=tags_update)
registry.subscribe(list_missing_ports,
constants.PORTS,
shell.Operations.LIST_MISMATCHES.value)
@ -331,3 +365,8 @@ registry.subscribe(migrate_compute_ports_vms,
registry.subscribe(migrate_exclude_ports,
constants.PORTS,
shell.Operations.NSX_MIGRATE_EXCLUDE_PORTS.value)
registry.subscribe(tag_default_ports,
constants.PORTS,
shell.Operations.NSX_TAG_DEFAULT.value)

View File

@ -48,6 +48,7 @@ class Operations(enum.Enum):
NSX_UPDATE_SECRET = 'nsx-update-secret'
NSX_RECREATE = 'nsx-recreate'
NSX_REORDER = 'nsx-reorder'
NSX_TAG_DEFAULT = 'nsx-tag-default'
MIGRATE_TO_DYNAMIC_CRITERIA = 'migrate-to-dynamic-criteria'
NSX_MIGRATE_V_V3 = 'nsx-migrate-v-v3'
MIGRATE_TO_POLICY = 'migrate-to-policy'
@ -84,6 +85,7 @@ nsxv3_resources = {
[Operations.LIST_MISMATCHES.value]),
constants.PORTS: Resource(constants.PORTS,
[Operations.LIST_MISMATCHES.value,
Operations.NSX_TAG_DEFAULT.value,
Operations.NSX_MIGRATE_V_V3.value,
Operations.NSX_MIGRATE_EXCLUDE_PORTS.value]),
constants.ROUTERS: Resource(constants.ROUTERS,