From 456251d6c62d5d493695f013ab43bb6d98ad2f15 Mon Sep 17 00:00:00 2001 From: asarfaty Date: Sun, 30 Aug 2020 10:16:39 +0200 Subject: [PATCH] MP2P Migration: create edge firewall section before END API Move the new policy EDGE firewall section creation to run before the END api, so that it will take affect before the default policy section is realized. Change-Id: I6d194df0d1533cbe0b86445bece699176ec2da79 --- .../plugins/nsxv3/resources/migration.py | 131 ++++++++---------- 1 file changed, 59 insertions(+), 72 deletions(-) diff --git a/vmware_nsx/shell/admin/plugins/nsxv3/resources/migration.py b/vmware_nsx/shell/admin/plugins/nsxv3/resources/migration.py index 3f303b601b..da291a4ca6 100644 --- a/vmware_nsx/shell/admin/plugins/nsxv3/resources/migration.py +++ b/vmware_nsx/shell/admin/plugins/nsxv3/resources/migration.py @@ -89,7 +89,7 @@ COMPONENT_STATUS_OK = 2 ROLLBACK_DATA = [] EDGE_FW_SEQ = 1 DFW_SEQ = 1 - +NSX_ROUTER_SECTIONS = [] SERVICE_UP_RETRIES = 30 @@ -373,6 +373,7 @@ def migrate_resource(nsxlib, resource_type, entries, LOG.info("Going to migrate %d %s objects in groups of max %s", len(entries), resource_type, limit) + start_time = time.time() if limit == MIGRATE_LIMIT_NO_LIMIT: migrate_objects(nsxlib, {'type': resource_type, @@ -415,6 +416,10 @@ def migrate_resource(nsxlib, resource_type, entries, 'resource_ids': entries[index:index + limit]}, use_admin=use_admin) + elapsed_time = time.time() - start_time + LOG.info("Migrating %d %s objects took %s seconds", + len(entries), resource_type, elapsed_time) + def get_configured_values(plugin, az_attribute): values = [] @@ -1044,6 +1049,56 @@ def migrate_dfw_sections(nsxlib, nsxpolicy, plugin): count_internals=True) +def migrate_edge_firewalls(nsxlib, nsxpolicy, plugin): + # -- Migrate edge firewall sections: + # The MP plugin uses the default MP edge firewall section, while the policy + # plugin uses a non default one, so regular migration cannot be used. + # Instead, create new edge firewall sections, and remove rules from the MP + # default sections + + # This is a hack to use the v3 plugin with the policy fwaas driver + class MigrationNsxpFwaasCallbacks(fwaas_callbacks_v2.NsxpFwaasCallbacksV2): + def __init__(self, with_rpc): + super(MigrationNsxpFwaasCallbacks, self).__init__(with_rpc) + # Make sure fwaas is considered as enabled + self.fwaas_enabled = True + + def _get_port_firewall_group_id(self, context, port_id): + # Override this api because directory.get_plugin does not work from + # admin utils context. + driver_db = firewall_db_v2.FirewallPluginDb() + return driver_db.get_fwg_attached_to_port(context, port_id) + + fwaas_callbacks = MigrationNsxpFwaasCallbacks(False) + plugin.nsxpolicy = nsxpolicy + ctx = context.get_admin_context() + routers = plugin.get_routers(ctx) + global NSX_ROUTER_SECTIONS + for rtr in routers: + nsx_router_id = db.get_nsx_router_id(ctx.session, rtr['id']) + nsx_rtr = nsxlib.logical_router.get(nsx_router_id) + for sec in nsx_rtr.get('firewall_sections', []): + section_id = sec['target_id'] + section = nsxlib.firewall_section.get(section_id) + if section['display_name'] != 'Default LR Layer3 Section': + continue + rules = nsxlib.firewall_section.get_rules(section_id)['results'] + if len(rules) <= 1: + continue + # Non default rules exist. need to migrate this section + router_db = plugin._get_router(ctx, rtr['id']) + ports = plugin._get_router_interfaces(ctx, rtr['id']) + fwaas_callbacks.update_router_firewall( + ctx, rtr['id'], router_db, ports) + LOG.debug("Created GW policy for router %s", rtr['id']) + + # delete rule from the default mp section at the end of the loop + # so the new section will have time to realize + NSX_ROUTER_SECTIONS.append({'id': section_id, + 'default_rule': rules[-1], + 'router_id': rtr['id']}) + + def migrate_dhcp_servers(nsxlib, nsxpolicy): # Each MP DHCP server will be migrated to a policy DHCP server config # which will be used by a segment later. It will get the neutron network id @@ -1191,6 +1246,7 @@ def migrate_t_resources_2_p(nsxlib, nsxpolicy, plugin): # Migrate firewall sections last as those take the longest to rollback # in case of error migrate_dfw_sections(nsxlib, nsxpolicy, plugin) + migrate_edge_firewalls(nsxlib, nsxpolicy, plugin) # Finalize the migration (cause policy realization) end_migration_process(nsxlib) @@ -1369,55 +1425,8 @@ def post_migration_actions(nsxlib, nsxpolicy, nsxpolicy_admin, plugin): LOG.debug("Updated gateway of network %s", net['id']) break - # -- Migrate edge firewall sections: - # The MP plugin uses the default MP edge firewall section, while the policy - # plugin uses a non default one, so regular migration cannot be used. - # Instead, create new edge firewall sections, and remove rules from the MP - # default sections - - # This is a hack to use the v3 plugin with the policy fwaas driver - class MigrationNsxpFwaasCallbacks(fwaas_callbacks_v2.NsxpFwaasCallbacksV2): - def __init__(self, with_rpc): - super(MigrationNsxpFwaasCallbacks, self).__init__(with_rpc) - # Make sure fwaas is considered as enabled - self.fwaas_enabled = True - - def _get_port_firewall_group_id(self, context, port_id): - # Override this api because directory.get_plugin does not work from - # admin utils context. - driver_db = firewall_db_v2.FirewallPluginDb() - return driver_db.get_fwg_attached_to_port(context, port_id) - - fwaas_callbacks = MigrationNsxpFwaasCallbacks(False) - plugin.nsxpolicy = nsxpolicy - routers = plugin.get_routers(ctx) - nsx_router_sections = [] - for rtr in routers: - nsx_router_id = db.get_nsx_router_id(ctx.session, rtr['id']) - nsx_rtr = nsxlib.logical_router.get(nsx_router_id) - for sec in nsx_rtr.get('firewall_sections', []): - section_id = sec['target_id'] - section = nsxlib.firewall_section.get(section_id) - if section['display_name'] != 'Default LR Layer3 Section': - continue - rules = nsxlib.firewall_section.get_rules(section_id)['results'] - if len(rules) <= 1: - continue - # Non default rules exist. need to migrate this section - router_db = plugin._get_router(ctx, rtr['id']) - ports = plugin._get_router_interfaces(ctx, rtr['id']) - fwaas_callbacks.update_router_firewall( - ctx, rtr['id'], router_db, ports) - LOG.debug("Created GW policy for router %s", rtr['id']) - - # delete rule from the default mp section at the end of the loop - # so the new section will have time to realize - nsx_router_sections.append({'id': section_id, - 'default_rule': rules[-1], - 'router_id': rtr['id']}) - - # Remove old rules from the default sections - for section in nsx_router_sections: + # -- Delete MP edge firewall rules + for section in NSX_ROUTER_SECTIONS: # make sure the policy section was already realized # with runtime_status=SUCESS nsxpolicy.gateway_policy.wait_until_state_sucessful( @@ -1430,13 +1439,6 @@ def post_migration_actions(nsxlib, nsxpolicy, nsxpolicy_admin, plugin): LOG.info("Post-migration actions done.") -def edge_firewall_migration_cond(resource): - return (resource.get('display_name') == 'Default LR Layer3 Section' and - resource.get('enforced_on') == 'LOGICALROUTER' and - resource.get('category') == 'Default' and - resource.get('section_type') == 'LAYER3') - - def pre_migration_checks(nsxlib, plugin): """Check for unsupported configuration that will fail the migration""" nsx_version = nsxlib.get_version() @@ -1471,21 +1473,6 @@ def pre_migration_checks(nsxlib, plugin): "neighbors or enable BGP and try again.", tier0) return False - # Firewall section with too many rules - fw_sections = nsxlib.firewall_section.list() - for section in fw_sections: - if (dfw_migration_cond(section) or - edge_firewall_migration_cond(section)): - n_rules = nsxlib.firewall_section.get_rules( - section['id'])['result_count'] - if n_rules >= MIGRATE_LIMIT_SECTION_AND_RULES: - LOG.error("Pre migration check failed: Firewall section %s " - "has %s rules and cannot be migrated. Please make " - "sure each section has less than %s rules and try " - "again.", section['id'], n_rules, - MIGRATE_LIMIT_SECTION_AND_RULES) - return False - # DHCP relay is unsupported if plugin._availability_zones_data.dhcp_relay_configured(): LOG.error("Pre migration check failed: DHCP relay configuration "