From 427cf1ff948c1823342e759215b69cdb4a3e2f5a Mon Sep 17 00:00:00 2001 From: Gary Kotton Date: Thu, 11 May 2017 13:56:46 -0700 Subject: [PATCH] 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 --- doc/source/admin_util.rst | 4 ++ vmware_nsx/plugins/nsx_v3/plugin.py | 50 +++++++++++++++++-- .../admin/plugins/nsxv3/resources/ports.py | 39 +++++++++++++++ vmware_nsx/shell/resources.py | 2 + 4 files changed, 92 insertions(+), 3 deletions(-) diff --git a/doc/source/admin_util.rst b/doc/source/admin_util.rst index 02299079a6..97e0a86793 100644 --- a/doc/source/admin_util.rst +++ b/doc/source/admin_util.rst @@ -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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index 1d5a33b13b..946886cbe2 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -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, diff --git a/vmware_nsx/shell/admin/plugins/nsxv3/resources/ports.py b/vmware_nsx/shell/admin/plugins/nsxv3/resources/ports.py index b42459bf33..8d1c5239b8 100644 --- a/vmware_nsx/shell/admin/plugins/nsxv3/resources/ports.py +++ b/vmware_nsx/shell/admin/plugins/nsxv3/resources/ports.py @@ -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) diff --git a/vmware_nsx/shell/resources.py b/vmware_nsx/shell/resources.py index a5346bf4d7..f3a239af38 100644 --- a/vmware_nsx/shell/resources.py +++ b/vmware_nsx/shell/resources.py @@ -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,