Merge "NSX|V3 adminUtils: detect and clean orphaned section rules"
This commit is contained in:
commit
783a021b18
@ -429,11 +429,11 @@ Firewall Sections
|
|||||||
Orphaned 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
|
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
|
nsxadmin -r orphaned-firewall-sections -o nsx-clean
|
||||||
|
|
||||||
|
@ -127,8 +127,6 @@ NSX_V3_NON_VIF_ENS_PROFILE = \
|
|||||||
'nsx-default-switch-security-non-vif-profile-for-ens'
|
'nsx-default-switch-security-non-vif-profile-for-ens'
|
||||||
NSX_V3_SERVER_SSL_PROFILE = 'nsx-default-server-ssl-profile'
|
NSX_V3_SERVER_SSL_PROFILE = 'nsx-default-server-ssl-profile'
|
||||||
NSX_V3_CLIENT_SSL_PROFILE = 'nsx-default-client-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
|
@resource_extend.has_resource_extenders
|
||||||
@ -295,11 +293,11 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
|
|||||||
found_sg = False
|
found_sg = False
|
||||||
try:
|
try:
|
||||||
super(NsxV3Plugin, self).get_security_group(
|
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:
|
except ext_sg.SecurityGroupNotFound:
|
||||||
LOG.warning('Creating a global security group')
|
LOG.warning('Creating a global security group')
|
||||||
sec_group = {'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,
|
'tenant_id': nsx_constants.INTERNAL_V3_TENANT_ID,
|
||||||
'name': 'NSX Internal',
|
'name': 'NSX Internal',
|
||||||
'description': ''}}
|
'description': ''}}
|
||||||
@ -324,7 +322,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
|
|||||||
# check if the section and nsgroup are already in the DB. If not
|
# check if the section and nsgroup are already in the DB. If not
|
||||||
# it means another server is creating them right now.
|
# it means another server is creating them right now.
|
||||||
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
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:
|
if nsgroup_id is None or section_id is None:
|
||||||
LOG.info("Global security exists without NSX objects")
|
LOG.info("Global security exists without NSX objects")
|
||||||
# Wait a bit to let the other server finish
|
# Wait a bit to let the other server finish
|
||||||
@ -352,7 +350,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
|
|||||||
self._ensure_default_rules()
|
self._ensure_default_rules()
|
||||||
# Validate if there is a race between processes
|
# Validate if there is a race between processes
|
||||||
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
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)
|
LOG.debug("Default NSGroup - %s, Section %s", nsgroup_id, section_id)
|
||||||
default_ns_group_id = self._default_section_nsgroup.get('id')
|
default_ns_group_id = self._default_section_nsgroup.get('id')
|
||||||
duplicates = False
|
duplicates = False
|
||||||
@ -362,7 +360,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
|
|||||||
LOG.debug("Updating NSGroup - %s, Section %s",
|
LOG.debug("Updating NSGroup - %s, Section %s",
|
||||||
default_ns_group_id, self.default_section)
|
default_ns_group_id, self.default_section)
|
||||||
nsx_db.save_sg_mappings(ctx,
|
nsx_db.save_sg_mappings(ctx,
|
||||||
NSX_V3_OS_DFW_UUID,
|
v3_utils.NSX_V3_OS_DFW_UUID,
|
||||||
default_ns_group_id,
|
default_ns_group_id,
|
||||||
self.default_section)
|
self.default_section)
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -3262,7 +3260,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
|
|||||||
return secgroup_db
|
return secgroup_db
|
||||||
|
|
||||||
def _prevent_nsx_internal_sg_modification(self, sg_id):
|
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")
|
msg = _("Cannot modify NSX internal security group")
|
||||||
raise n_exc.InvalidInput(error_message=msg)
|
raise n_exc.InvalidInput(error_message=msg)
|
||||||
|
|
||||||
|
@ -50,6 +50,9 @@ PORT_ERROR_TYPE_MISSING = "Missing port"
|
|||||||
PORT_ERROR_TYPE_PROFILE = "Wrong switching profiles"
|
PORT_ERROR_TYPE_PROFILE = "Wrong switching profiles"
|
||||||
PORT_ERROR_TYPE_BINDINGS = "Wrong address binding"
|
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__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -362,6 +365,41 @@ def get_orphaned_firewall_sections(context, nsxlib):
|
|||||||
return orphaned_sections
|
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):
|
def get_dhcp_profile_id(nsxlib):
|
||||||
profiles = nsxlib.switching_profile.find_by_display_name(
|
profiles = nsxlib.switching_profile.find_by_display_name(
|
||||||
NSX_V3_DHCP_PROFILE_NAME)
|
NSX_V3_DHCP_PROFILE_NAME)
|
||||||
|
@ -298,11 +298,23 @@ def list_orphaned_sections(resource, event, trigger, **kwargs):
|
|||||||
attrs=['id', 'display_name'])
|
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):
|
def clean_orphaned_sections(resource, event, trigger, **kwargs):
|
||||||
"""Delete orphaned firewall sections from the NSX backend"""
|
"""Delete orphaned firewall sections from the NSX backend"""
|
||||||
nsxlib = v3_utils.get_connected_nsxlib()
|
nsxlib = v3_utils.get_connected_nsxlib()
|
||||||
orphaned_sections = plugin_utils.get_orphaned_firewall_sections(
|
orphaned_sections = plugin_utils.get_orphaned_firewall_sections(
|
||||||
neutron_sg.context, nsxlib)
|
neutron_sg.context, nsxlib)
|
||||||
|
if not orphaned_sections:
|
||||||
|
LOG.info("No orphaned nsx sections were found.")
|
||||||
for sec in orphaned_sections:
|
for sec in orphaned_sections:
|
||||||
try:
|
try:
|
||||||
nsxlib.firewall_section.delete(sec['id'])
|
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'])
|
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):
|
def update_security_groups_logging(resource, event, trigger, **kwargs):
|
||||||
"""Update allowed traffic logging for all neutron security group rules"""
|
"""Update allowed traffic logging for all neutron security group rules"""
|
||||||
errmsg = ("Need to specify log-allowed-traffic property. Add --property "
|
errmsg = ("Need to specify log-allowed-traffic property. Add --property "
|
||||||
@ -365,6 +397,14 @@ registry.subscribe(list_orphaned_sections,
|
|||||||
constants.ORPHANED_FIREWALL_SECTIONS,
|
constants.ORPHANED_FIREWALL_SECTIONS,
|
||||||
shell.Operations.NSX_LIST.value)
|
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,
|
registry.subscribe(clean_orphaned_sections,
|
||||||
constants.ORPHANED_FIREWALL_SECTIONS,
|
constants.ORPHANED_FIREWALL_SECTIONS,
|
||||||
shell.Operations.NSX_CLEAN.value)
|
shell.Operations.NSX_CLEAN.value)
|
||||||
|
|
||||||
|
registry.subscribe(clean_orphaned_section_rules,
|
||||||
|
constants.ORPHANED_FIREWALL_SECTIONS,
|
||||||
|
shell.Operations.NSX_CLEAN.value)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user