Merge "NSX|V3 adminUtils: detect and clean orphaned section rules"

This commit is contained in:
Zuul 2019-04-21 05:18:30 +00:00 committed by Gerrit Code Review
commit 783a021b18
4 changed files with 86 additions and 10 deletions

View File

@ -429,11 +429,11 @@ Firewall Sections
Orphaned Firewall Sections
~~~~~~~~~~~~~~~~~~~~~~~~~~
- List orphaned firewall sections (exist on NSXv3 backend but don't have a corresponding binding in Neutron DB)::
- List orphaned firewall sections & rules (exist on NSXv3 backend but don't have a corresponding binding in Neutron DB)::
nsxadmin -r orphaned-firewall-sections -o nsx-list
- Delete orphaned firewall sections (exist on NSXv3 backend but don't have a corresponding binding in Neutron DB)::
- Delete orphaned firewall sections & rules (exist on NSXv3 backend but don't have a corresponding binding in Neutron DB)::
nsxadmin -r orphaned-firewall-sections -o nsx-clean

View File

@ -127,8 +127,6 @@ NSX_V3_NON_VIF_ENS_PROFILE = \
'nsx-default-switch-security-non-vif-profile-for-ens'
NSX_V3_SERVER_SSL_PROFILE = 'nsx-default-server-ssl-profile'
NSX_V3_CLIENT_SSL_PROFILE = 'nsx-default-client-ssl-profile'
# Default UUID for the global OS rule
NSX_V3_OS_DFW_UUID = '00000000-def0-0000-0fed-000000000000'
@resource_extend.has_resource_extenders
@ -295,11 +293,11 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
found_sg = False
try:
super(NsxV3Plugin, self).get_security_group(
context, NSX_V3_OS_DFW_UUID, fields=['id'])
context, v3_utils.NSX_V3_OS_DFW_UUID, fields=['id'])
except ext_sg.SecurityGroupNotFound:
LOG.warning('Creating a global security group')
sec_group = {'security_group':
{'id': NSX_V3_OS_DFW_UUID,
{'id': v3_utils.NSX_V3_OS_DFW_UUID,
'tenant_id': nsx_constants.INTERNAL_V3_TENANT_ID,
'name': 'NSX Internal',
'description': ''}}
@ -324,7 +322,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
# check if the section and nsgroup are already in the DB. If not
# it means another server is creating them right now.
nsgroup_id, section_id = nsx_db.get_sg_mappings(
context.session, NSX_V3_OS_DFW_UUID)
context.session, v3_utils.NSX_V3_OS_DFW_UUID)
if nsgroup_id is None or section_id is None:
LOG.info("Global security exists without NSX objects")
# Wait a bit to let the other server finish
@ -352,7 +350,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
self._ensure_default_rules()
# Validate if there is a race between processes
nsgroup_id, section_id = nsx_db.get_sg_mappings(
ctx.session, NSX_V3_OS_DFW_UUID)
ctx.session, v3_utils.NSX_V3_OS_DFW_UUID)
LOG.debug("Default NSGroup - %s, Section %s", nsgroup_id, section_id)
default_ns_group_id = self._default_section_nsgroup.get('id')
duplicates = False
@ -362,7 +360,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
LOG.debug("Updating NSGroup - %s, Section %s",
default_ns_group_id, self.default_section)
nsx_db.save_sg_mappings(ctx,
NSX_V3_OS_DFW_UUID,
v3_utils.NSX_V3_OS_DFW_UUID,
default_ns_group_id,
self.default_section)
except Exception:
@ -3262,7 +3260,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
return secgroup_db
def _prevent_nsx_internal_sg_modification(self, sg_id):
if sg_id == NSX_V3_OS_DFW_UUID:
if sg_id == v3_utils.NSX_V3_OS_DFW_UUID:
msg = _("Cannot modify NSX internal security group")
raise n_exc.InvalidInput(error_message=msg)

View File

@ -50,6 +50,9 @@ PORT_ERROR_TYPE_MISSING = "Missing port"
PORT_ERROR_TYPE_PROFILE = "Wrong switching profiles"
PORT_ERROR_TYPE_BINDINGS = "Wrong address binding"
# Default UUID for the global OS rule
NSX_V3_OS_DFW_UUID = '00000000-def0-0000-0fed-000000000000'
LOG = logging.getLogger(__name__)
@ -362,6 +365,41 @@ def get_orphaned_firewall_sections(context, nsxlib):
return orphaned_sections
def get_security_group_rules_mappings(context):
q = context.session.query(
securitygroup.SecurityGroupRule.id,
nsx_models.NeutronNsxRuleMapping.nsx_id).join(
nsx_models.NeutronNsxRuleMapping).all()
sg_mappings = [{'rule_id': mapp[0],
'nsx_rule_id': mapp[1]}
for mapp in q]
return sg_mappings
def get_orphaned_firewall_section_rules(context, nsxlib):
fw_sections = nsxlib.firewall_section.list()
sg_mappings = get_security_groups_mappings(context)
rules_mappings = get_security_group_rules_mappings(context)
orphaned_rules = []
nsx_rules_in_mappings = [r['nsx_rule_id'] for r in rules_mappings]
for fw_section in fw_sections:
for sg_db in sg_mappings:
if (fw_section['id'] == sg_db['section-id'] and
sg_db['id'] != NSX_V3_OS_DFW_UUID):
# found the right neutron SG
section_rules = nsxlib.firewall_section.get_rules(
fw_section['id'])['results']
for nsx_rule in section_rules:
if nsx_rule['id'] not in nsx_rules_in_mappings:
# orphaned rule
orphaned_rules.append(
{'security-group-name': sg_db['name'],
'security-group-id': sg_db['id'],
'section-id': fw_section['id'],
'rule-id': nsx_rule['id']})
return orphaned_rules
def get_dhcp_profile_id(nsxlib):
profiles = nsxlib.switching_profile.find_by_display_name(
NSX_V3_DHCP_PROFILE_NAME)

View File

@ -298,11 +298,23 @@ def list_orphaned_sections(resource, event, trigger, **kwargs):
attrs=['id', 'display_name'])
def list_orphaned_section_rules(resource, event, trigger, **kwargs):
"""List orphaned firewall section rules"""
nsxlib = v3_utils.get_connected_nsxlib()
orphaned_rules = plugin_utils.get_orphaned_firewall_section_rules(
neutron_sg.context, nsxlib)
_log_info("orphaned-firewall-section-rules", orphaned_rules,
attrs=['security-group-name', 'security-group-id',
'section-id', 'rule-id'])
def clean_orphaned_sections(resource, event, trigger, **kwargs):
"""Delete orphaned firewall sections from the NSX backend"""
nsxlib = v3_utils.get_connected_nsxlib()
orphaned_sections = plugin_utils.get_orphaned_firewall_sections(
neutron_sg.context, nsxlib)
if not orphaned_sections:
LOG.info("No orphaned nsx sections were found.")
for sec in orphaned_sections:
try:
nsxlib.firewall_section.delete(sec['id'])
@ -313,6 +325,26 @@ def clean_orphaned_sections(resource, event, trigger, **kwargs):
LOG.info("Backend firewall section %s was deleted.", sec['id'])
def clean_orphaned_section_rules(resource, event, trigger, **kwargs):
"""Delete orphaned firewall section rules from the NSX backend"""
nsxlib = v3_utils.get_connected_nsxlib()
orphaned_rules = plugin_utils.get_orphaned_firewall_section_rules(
neutron_sg.context, nsxlib)
if not orphaned_rules:
LOG.info("No orphaned nsx rules were found.")
for rule in orphaned_rules:
try:
nsxlib.firewall_section.delete_rule(
rule['section-id'], rule['rule-id'])
except Exception as e:
LOG.error("Failed to delete backend firewall section %(sect)s "
"rule %(rule)s: %(e)s.", {'sect': rule['section-id'],
'rule': rule['rule-id'],
'e': e})
else:
LOG.info("Backend firewall rule %s was deleted.", rule['rule-id'])
def update_security_groups_logging(resource, event, trigger, **kwargs):
"""Update allowed traffic logging for all neutron security group rules"""
errmsg = ("Need to specify log-allowed-traffic property. Add --property "
@ -365,6 +397,14 @@ registry.subscribe(list_orphaned_sections,
constants.ORPHANED_FIREWALL_SECTIONS,
shell.Operations.NSX_LIST.value)
registry.subscribe(list_orphaned_section_rules,
constants.ORPHANED_FIREWALL_SECTIONS,
shell.Operations.NSX_LIST.value)
registry.subscribe(clean_orphaned_sections,
constants.ORPHANED_FIREWALL_SECTIONS,
shell.Operations.NSX_CLEAN.value)
registry.subscribe(clean_orphaned_section_rules,
constants.ORPHANED_FIREWALL_SECTIONS,
shell.Operations.NSX_CLEAN.value)