示例#1
0
def tag_default_ports(resource, event, trigger, **kwargs):
    nsxlib = v3_utils.get_connected_nsxlib()
    admin_cxt = neutron_context.get_admin_context()
    filters = v3_utils.get_plugin_filters(admin_cxt)

    # 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, filters=filters)
        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)
示例#2
0
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 "
              "log-allowed-traffic=true/false")
    if not kwargs.get('property'):
        LOG.error("%s", errmsg)
        return
    properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
    log_allowed_str = properties.get('log-allowed-traffic')
    if not log_allowed_str or log_allowed_str.lower() not in ['true', 'false']:
        LOG.error("%s", errmsg)
        return
    log_allowed = log_allowed_str.lower() == 'true'

    context = neutron_context.get_admin_context()
    nsxlib = v3_utils.get_connected_nsxlib()

    with v3_utils.NsxV3PluginWrapper() as plugin:
        secgroups = plugin.get_security_groups(
            context, fields=['id', sg_logging.LOGGING])
        LOG.info("Going to update logging of %s sections", len(secgroups))
        for sg in [
                sg for sg in secgroups if sg.get(sg_logging.LOGGING) is False
        ]:
            nsgroup_id, section_id = nsx_db.get_sg_mappings(
                context.session, sg['id'])
            if section_id:
                try:
                    nsxlib.firewall_section.set_rule_logging(
                        section_id, logging=log_allowed)
                except nsx_lib_exc.ManagerError:
                    LOG.error(
                        "Failed to update firewall rule logging "
                        "for rule in section %s", section_id)
示例#3
0
    def _init_mock_plugin(self):
        test_v3_plugin._mock_nsx_backend_calls()

        # mock resources
        for cls in (nsx_v3_resources.LogicalPort,
                    nsx_v3_resources.LogicalDhcpServer,
                    core_resources.NsxLibLogicalRouter,
                    core_resources.NsxLibSwitchingProfile):

            self._patch_object(cls, 'list', return_value={'results': []})
            self._patch_object(cls,
                               'get',
                               return_value={'id': uuidutils.generate_uuid()})
            self._patch_object(cls, 'update')

        self._patch_object(core_resources.NsxLibSwitchingProfile,
                           'find_by_display_name',
                           return_value=[{
                               'id': uuidutils.generate_uuid()
                           }])
        super(TestNsxv3AdminUtils, self)._init_mock_plugin()

        self._plugin = nsxv3_utils.NsxV3PluginWrapper()
        mock_nm_get_plugin = mock.patch(
            "neutron_lib.plugins.directory.get_plugin")
        self.mock_nm_get_plugin = mock_nm_get_plugin.start()
        self.mock_nm_get_plugin.return_value = self._plugin
示例#4
0
def nsx_update_metadata_proxy(resource, event, trigger, **kwargs):
    """Update Metadata proxy for NSXv3 CrossHairs."""

    nsx_version = utils.get_connected_nsxlib().get_version()
    if not nsx_utils.is_nsx_version_1_1_0(nsx_version):
        LOG.info(_LI("This utility is not available for NSX version %s"),
                 nsx_version)
        return

    metadata_proxy_uuid = None
    if kwargs.get('property'):
        properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
        metadata_proxy_uuid = properties.get('metadata_proxy_uuid')
    if not metadata_proxy_uuid:
        LOG.error(_LE("metadata_proxy_uuid is not defined"))
        return

    cfg.CONF.set_override('dhcp_agent_notification', False)
    cfg.CONF.set_override('native_dhcp_metadata', True, 'nsx_v3')
    cfg.CONF.set_override('metadata_proxy_uuid', metadata_proxy_uuid, 'nsx_v3')

    plugin = utils.NsxV3PluginWrapper()
    nsx_client = utils.get_nsxv3_client()
    port_resource = resources.LogicalPort(nsx_client)

    # For each Neutron network, check if it is an internal metadata network.
    # If yes, delete the network and associated router interface.
    # Otherwise, create a logical switch port with MD-Proxy attachment.
    for network in neutron_client.get_networks():
        if _is_metadata_network(network):
            # It is a metadata network, find the attached router,
            # remove the router interface and the network.
            filters = {'device_owner': const.ROUTER_INTERFACE_OWNERS,
                       'fixed_ips': {
                           'subnet_id': [network['subnets'][0]],
                           'ip_address': [nsx_rpc.METADATA_GATEWAY_IP]}}
            ports = neutron_client.get_ports(filters=filters)
            if not ports:
                continue
            router_id = ports[0]['device_id']
            interface = {'subnet_id': network['subnets'][0]}
            plugin.remove_router_interface(router_id, interface)
            LOG.info(_LI("Removed metadata interface on router %s"), router_id)
            plugin.delete_network(network['id'])
            LOG.info(_LI("Removed metadata network %s"), network['id'])
        else:
            lswitch_id = neutron_client.net_id_to_lswitch_id(network['id'])
            if not lswitch_id:
                continue
            tags = nsx_utils.build_v3_tags_payload(
                network, resource_type='os-neutron-net-id',
                project_name='admin')
            name = nsx_utils.get_name_and_uuid('%s-%s' % (
                'mdproxy', network['name'] or 'network'), network['id'])
            port_resource.create(
                lswitch_id, metadata_proxy_uuid, tags=tags, name=name,
                attachment_type=nsx_constants.ATTACHMENT_MDPROXY)
            LOG.info(_LI("Enabled native metadata proxy for network %s"),
                     network['id'])
示例#5
0
def fix_security_groups(resource, event, trigger, **kwargs):
    """Fix mismatch security groups by recreating missing sections & NS groups
    on the NSX backend
    """
    context_ = neutron_context.get_admin_context()
    inconsistent_secgroups = _find_missing_sections()
    inconsistent_secgroups.update(_find_missing_security_groups())

    nsxlib = v3_utils.get_connected_nsxlib()
    with v3_utils.NsxV3PluginWrapper() as plugin:
        for sg_id, sg in inconsistent_secgroups.items():
            secgroup = plugin.get_security_group(context_, sg_id)

            try:
                # FIXME(roeyc): try..except clause should be removed once the
                # api will return 404 response code instead 400 for trying to
                # delete a non-existing firewall section.
                nsxlib.firewall_section.delete(sg['section-id'])
            except Exception:
                pass
            nsxlib.ns_group.delete(sg['nsx-securitygroup-id'])
            neutron_sg.delete_security_group_section_mapping(sg_id)
            neutron_sg.delete_security_group_backend_mapping(sg_id)
            nsgroup, fw_section = (
                plugin._create_security_group_backend_resources(secgroup))
            nsx_db.save_sg_mappings(context_, sg_id, nsgroup['id'],
                                    fw_section['id'])
            # If version > 1.1 then we use dynamic criteria tags, and the port
            # should already have them.
            if not nsxlib.feature_supported(consts.FEATURE_DYNAMIC_CRITERIA):
                members = []
                for port_id in neutron_sg.get_ports_in_security_group(sg_id):
                    lport_id = neutron_sg.get_logical_port_id(port_id)
                    members.append(lport_id)
                nsxlib.ns_group.add_members(nsgroup['id'],
                                            consts.TARGET_TYPE_LOGICAL_PORT,
                                            members)

            for rule in secgroup['security_group_rules']:
                rule_mapping = (context_.session.query(
                    nsx_models.NeutronNsxRuleMapping).filter_by(
                        neutron_id=rule['id']).one())
                with context_.session.begin(subtransactions=True):
                    context_.session.delete(rule_mapping)
            action = (consts.FW_ACTION_DROP if secgroup.get(
                provider_sg.PROVIDER) else consts.FW_ACTION_ALLOW)
            rules = plugin._create_firewall_rules(
                context_, fw_section['id'], nsgroup['id'],
                secgroup.get(sg_logging.LOGGING, False), action,
                secgroup['security_group_rules'])
            plugin.save_security_group_rule_mappings(context_, rules['rules'])
示例#6
0
def update_dhcp_relay(resource, event, trigger, **kwargs):
    """Update all routers dhcp relay service by the current configuration"""
    nsxlib = utils.get_connected_nsxlib()
    if not nsxlib.feature_supported(nsx_constants.FEATURE_DHCP_RELAY):
        version = nsxlib.get_version()
        LOG.error("DHCP relay is not supported by NSX version %s", version)
        return

    admin_cxt = neutron_context.get_admin_context()
    filters = utils.get_plugin_filters(admin_cxt)
    with utils.NsxV3PluginWrapper() as plugin:
        # Make sure FWaaS was initialized
        plugin.init_fwaas_for_admin_utils()

        # get all neutron routers and  interfaces ports
        routers = plugin.get_routers(admin_cxt, filters=filters)
        for router in routers:
            LOG.info("Updating router %s", router['id'])
            port_filters = {
                'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF],
                'device_id': [router['id']]
            }
            ports = plugin.get_ports(admin_cxt, filters=port_filters)
            for port in ports:
                # get the backend router port by the tag
                nsx_port_id = nsxlib.get_id_by_resource_and_tag(
                    'LogicalRouterDownLinkPort', 'os-neutron-rport-id',
                    port['id'])
                if not nsx_port_id:
                    LOG.warning(
                        "Couldn't find nsx router port for interface "
                        "%s", port['id'])
                    continue
                # get the network of this port
                network_id = port['network_id']
                # check the relay service on the az of the network
                az = plugin.get_network_az_by_net_id(admin_cxt, network_id)
                nsxlib.logical_router_port.update(
                    nsx_port_id, relay_service_uuid=az.dhcp_relay_service)

            # if FWaaS is enables, also update the firewall rules
            try:
                plugin.update_router_firewall(admin_cxt, router['id'])
            except Exception as e:
                LOG.warning(
                    "Updating router firewall was skipped because of "
                    "an error %s", e)

    LOG.info("Done.")
示例#7
0
def nsx_update_router_lb_advertisement(resource, event, trigger, **kwargs):
    """The implementation of the VIP advertisement changed.

    This utility will update existing LB/routers
    """
    nsxlib = utils.get_connected_nsxlib()
    if not nsxlib.feature_supported(consts.FEATURE_LOAD_BALANCER):
        LOG.error("This utility is not available for NSX version %s",
                  nsxlib.get_version())
        return

    # Get the list of neutron routers used by LB
    lb_services = nsxlib.load_balancer.service.list()['results']
    lb_routers = []
    for lb_srv in lb_services:
        for tag in lb_srv.get('tags', []):
            if tag['scope'] == 'os-neutron-router-id':
                lb_routers.append(tag['tag'])
    lb_routers = set(lb_routers)
    LOG.info(
        "Going to update LB advertisement on %(num)s router(s): "
        "%(routers)s", {
            'num': len(lb_routers),
            'routers': lb_routers
        })

    context = neutron_context.get_admin_context()
    with utils.NsxV3PluginWrapper() as plugin:
        for rtr_id in lb_routers:
            nsx_router_id = nsx_db.get_nsx_router_id(context.session, rtr_id)
            if not nsx_router_id:
                LOG.error("Router %s NSX Id was not found.", rtr_id)
                continue
            try:
                # disable the global vip advertisement flag
                plugin.nsxlib.logical_router.update_advertisement(
                    nsx_router_id, advertise_lb_vip=False)
                # Add an advertisement rule for the external network
                router = plugin.get_router(context, rtr_id)
                lb_utils.update_router_lb_vip_advertisement(
                    context, plugin, router, nsx_router_id)
            except Exception as e:
                LOG.error("Failed updating router %(id)s: %(e)s", {
                    'id': rtr_id,
                    'e': e
                })

    LOG.info("Done.")
示例#8
0
def nsx_recreate_dhcp_server(resource, event, trigger, **kwargs):
    """Recreate DHCP server & binding for a neutron network"""
    if not cfg.CONF.nsx_v3.native_dhcp_metadata:
        LOG.error("Native DHCP is disabled.")
        return

    errmsg = ("Need to specify net-id property. Add --property net-id=<id>")
    if not kwargs.get('property'):
        LOG.error("%s", errmsg)
        return
    properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
    net_id = properties.get('net-id')
    if not net_id:
        LOG.error("%s", errmsg)
        return

    context = neutron_context.get_admin_context()
    with utils.NsxV3PluginWrapper() as plugin:
        # verify that this is an existing network with dhcp enabled
        try:
            network = plugin._get_network(context, net_id)
        except exceptions.NetworkNotFound:
            LOG.error("Network %s was not found", net_id)
            return
        if plugin._has_no_dhcp_enabled_subnet(context, network):
            LOG.error("Network %s has no DHCP enabled subnet", net_id)
            return
        dhcp_relay = plugin.get_network_az_by_net_id(
            context, net_id).dhcp_relay_service
        if dhcp_relay:
            LOG.error("Native DHCP should not be enabled with dhcp relay")
            return

        # find the dhcp subnet of this network
        subnet_id = None
        for subnet in network.subnets:
            if subnet.enable_dhcp:
                subnet_id = subnet.id
                break
        if not subnet_id:
            LOG.error("Network %s has no DHCP enabled subnet", net_id)
            return
        dhcp_subnet = plugin.get_subnet(context, subnet_id)
        # disable and re-enable the dhcp
        plugin._enable_native_dhcp(context, network, dhcp_subnet)
    LOG.info("Done.")
示例#9
0
def list_missing_ports(resource, event, trigger, **kwargs):
    """List neutron ports that are missing the NSX backend port
    And ports with wrong switch profiles or bindings
    """
    admin_cxt = neutron_context.get_admin_context()
    filters = v3_utils.get_plugin_filters(admin_cxt)
    nsxlib = v3_utils.get_connected_nsxlib()
    with v3_utils.NsxV3PluginWrapper() as plugin:
        problems = plugin_utils.get_mismatch_logical_ports(
            admin_cxt, nsxlib, plugin, filters)

    if len(problems) > 0:
        title = ("Found internal ports misconfiguration on the "
                 "NSX manager:")
        LOG.info(
            formatters.output_formatter(title, problems,
                                        ['neutron_id', 'nsx_id', 'error']))
    else:
        LOG.info("All internal ports verified on the NSX manager")
示例#10
0
def fix_security_groups(resource, event, trigger, **kwargs):
    context_ = neutron_context.get_admin_context()
    plugin = v3_utils.NsxV3PluginWrapper()
    inconsistent_secgroups = _find_missing_sections()
    inconsistent_secgroups.update(_find_missing_security_groups())

    for sg_id, sg in inconsistent_secgroups.items():
        secgroup = plugin.get_security_group(context_, sg_id)
        nsxlib.delete_section(sg['section-id'])
        nsxlib.delete_nsgroup(sg['nsx-securitygroup-id'])
        neutron_sg.delete_security_group_section_mapping(sg_id)
        neutron_sg.delete_security_group_backend_mapping(sg_id)
        nsgroup, fw_section = (
            plugin._create_security_group_backend_resources(secgroup))
        nsx_db.save_sg_mappings(context_.session, sg_id, nsgroup['id'],
                                fw_section['id'])
        # If version > 1.1 then we use dynamic criteria tags, and the port
        # should already have them.
        if not utils.is_nsx_version_1_1_0(plugin._nsx_version):
            members = []
            for port_id in neutron_db.get_ports_in_security_group(sg_id):
                lport_id = neutron_db.get_logical_port_id(port_id)
                members.append(lport_id)
            nsxlib.add_nsgroup_members(nsgroup['id'], firewall.LOGICAL_PORT,
                                       members)

        for rule in secgroup['security_group_rules']:
            rule_mapping = (context_.session.query(
                nsx_models.NeutronNsxRuleMapping).filter_by(
                    neutron_id=rule['id']).one())
            with context_.session.begin(subtransactions=True):
                context_.session.delete(rule_mapping)
        action = (firewall.DROP
                  if secgroup.get(provider_sg.PROVIDER) else firewall.ALLOW)
        rules = nsxlib.create_firewall_rules(
            context_, fw_section['id'], nsgroup['id'],
            secgroup.get(sg_logging.LOGGING, False), action,
            secgroup['security_group_rules'])
        nsxlib.save_sg_rule_mappings(context_.session, rules['rules'])
        # Add nsgroup to a nested group
        plugin.nsgroup_manager.add_nsgroup(nsgroup['id'])
示例#11
0
def migrate_v_project_to_t(resource, event, trigger, **kwargs):
    """Migrate 1 project from v to t with all its resources"""

    # filter out the plugins INFO logging
    # TODO(asarfaty): Consider this for all admin utils
    LOG.logger.setLevel(logging.INFO)
    logging.getLogger(None).logger.setLevel(logging.WARN)

    # get the configuration: tenant + public network + from file flag
    usage = ("Usage: nsxadmin -r projects -o %s --property project-id=<> "
             "--property external-net=<NSX-T external network to be used> "
             "<--property from-file=True>" %
             shell.Operations.NSX_MIGRATE_V_V3.value)
    if not kwargs.get('property'):
        LOG.error("Missing parameters: %s", usage)
        return
    properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
    project = properties.get('project-id')
    ext_net_id = properties.get('external-net')
    from_file = properties.get('from-file', 'false').lower() == "true"
    # TODO(asarfaty): get files path
    if not project:
        LOG.error("Missing project-id parameter: %s", usage)
        return
    if not ext_net_id:
        LOG.error("Missing external-net parameter: %s", usage)
        return

    # check if files exist in the current directory
    try:
        filename = get_resource_file_name(project, 'network')
        file = open(filename, 'r')
        if file.read():
            if not from_file:
                from_file = admin_utils.query_yes_no(
                    "Use existing resources files for this project?",
                    default="yes")
        file.close()
    except Exception:
        sys.exc_clear()
        if from_file:
            LOG.error("Cannot run from file: files not found")
            return

    # validate tenant id and public network
    ctx = n_context.get_admin_context()
    mapping = db.get_project_plugin_mapping(ctx.session, project)
    current_plugin = mapping.plugin
    if not mapping:
        LOG.error("Project %s is unknown", project)
        return
    if not from_file and current_plugin != projectpluginmap.NsxPlugins.NSX_V:
        LOG.error("Project %s belongs to plugin %s.", project, mapping.plugin)
        return

    with v3_utils.NsxV3PluginWrapper() as plugin:
        try:
            plugin.get_network(ctx, ext_net_id)
        except exceptions.NetworkNotFound:
            LOG.error("Network %s was not found", ext_net_id)
            return
        if not plugin._network_is_external(ctx, ext_net_id):
            LOG.error("Network %s is not external", ext_net_id)
            return

    if from_file:
        # read resources from files
        objects = read_v_resources_from_files(project)
    else:
        # read all V resources and dump to a file
        objects = read_v_resources_to_files(ctx, project)

    # delete all the V resources (reading it from the files)
    if current_plugin == projectpluginmap.NsxPlugins.NSX_V:
        delete_v_resources(ctx, objects)

    # change the mapping of this tenant to T
    db.update_project_plugin_mapping(ctx.session, project,
                                     projectpluginmap.NsxPlugins.NSX_T)

    # use api replay flag to allow keeping the IDs
    cfg.CONF.set_override('api_replay_mode', True)

    # add resources 1 by one after adapting them to T (api-replay code)
    create_t_resources(ctx, objects, ext_net_id)

    # reset api replay flag to allow keeping the IDs
    cfg.CONF.set_override('api_replay_mode', False)
示例#12
0
def create_t_resources(context, objects, ext_net):
    """Create a list of objects in the T plugin"""
    LOG.info(">>>>Creating all the objects of the project in NSX-T.")
    prepare = replay_utils.PrepareObjectForMigration()
    with v3_utils.NsxV3PluginWrapper() as plugin:
        # create the resource in the order opposite to the deletion
        # (but start with routers)
        ordered_resources = migrated_resources[::-1]
        ordered_resources.remove('router')
        ordered_resources = ['router'] + ordered_resources
        dhcp_subnets = []
        for resource in ordered_resources:
            total_num = len(objects[resource])
            LOG.info(">>>Creating %s %s%s.", total_num,
                     resource, 's' if total_num > 1 else '')
            get_object = getattr(plugin, "get_%s" % resource)
            create_object = getattr(plugin, "create_%s" % resource)
            # go over the objects of this resource
            for count, obj in enumerate(objects[resource], 1):
                # check if this object already exists
                try:
                    get_object(context, obj['id'])
                except exceptions.NotFound:
                    # prevent logger from logging this exception
                    sys.exc_clear()
                else:
                    # already exists (this will happen if we rerun from files,
                    # or if the deletion failed)
                    LOG.info(">>Skipping %(resource)s %(name)s %(count)s/"
                             "%(total)s as it was already created.",
                             {'resource': resource,
                              'name': obj.get('name') or obj['id'],
                              'count': count,
                              'total': total_num})
                    continue

                # fix object before creation using the api replay code
                orig_id = obj['id']
                prepare_object = getattr(prepare, "prepare_%s" % resource)
                obj_data = prepare_object(obj, direct_call=True)
                enable_dhcp = False
                # special cases for different objects before create:
                if resource == 'subnet':
                    if obj_data['enable_dhcp']:
                        enable_dhcp = True
                        # disable dhcp for now, to avoid ip collisions
                        obj_data['enable_dhcp'] = False
                elif resource == 'security_group':
                    # security group rules should be added separately
                    sg_rules = obj_data.pop('security_group_rules')
                elif resource == 'floatingip':
                    # Create the floating IP on the T external network
                    obj_data['floating_network_id'] = ext_net
                    del obj_data['floating_ip_address']
                elif resource == 'port':
                    # remove the old subnet id field from ports fixed_ips dict
                    # since the subnet ids are changed
                    for fixed_ips in obj_data['fixed_ips']:
                        del fixed_ips['subnet_id']

                    if obj_data['device_owner'] == 'network:dhcp':
                        continue
                    if obj_data['device_owner'] == 'network:floatingip':
                        continue
                    if obj_data['device_owner'] == 'network:router_gateway':
                        # add a gateway on the new ext network for this router
                        router_id = obj_data['device_id']
                        # keep the original enable-snat value
                        router_data = get_router_by_id(objects, router_id)
                        enable_snat = router_data['external_gateway_info'].get(
                                'enable_snat', True)
                        rtr_body = {
                            "external_gateway_info":
                                {"network_id": ext_net,
                                 "enable_snat": enable_snat}}
                        try:
                            plugin.update_router(
                                context, router_id, {'router': rtr_body})
                            LOG.info(">>Uplinked router %(rtr)s to new "
                                     "external network %(net)s",
                                     {'rtr': router_id,
                                      'net': ext_net})

                        except Exception as e:
                            LOG.error(">>Failed to add router %(rtr)s "
                                      "gateway: %(e)s",
                                      {'rtr': router_id, 'e': e})
                            continue
                    if obj_data['device_owner'] == 'network:router_interface':
                        try:
                            # uplink router_interface ports by creating the
                            # port, and attaching it to the router
                            router_id = obj_data['device_id']
                            obj_data['device_owner'] = ""
                            obj_data['device_id'] = ""
                            created_port = plugin.create_port(
                                context,
                                {'port': obj_data})
                            LOG.info(">>Created interface port %(port)s, ip "
                                     "%(ip)s, mac %(mac)s)",
                                     {'port': created_port['id'],
                                      'ip': created_port['fixed_ips'][0][
                                            'ip_address'],
                                      'mac': created_port['mac_address']})
                            plugin.add_router_interface(
                                context,
                                router_id,
                                {'port_id': created_port['id']})
                            LOG.info(">>Uplinked router %(rtr)s to network "
                                     "%(net)s",
                                     {'rtr': router_id,
                                      'net': obj_data['network_id']})
                        except Exception as e:
                            LOG.error(">>Failed to add router %(rtr)s "
                                      "interface port: %(e)s",
                                      {'rtr': router_id, 'e': e})
                        continue

                # create the object on the NSX-T plugin
                try:
                    created_obj = create_object(context, {resource: obj_data})
                    LOG.info(">>Created %(resource)s %(name)s %(count)s/"
                             "%(total)s",
                             {'resource': resource, 'count': count,
                              'name': obj_data.get('name') or orig_id,
                              'total': total_num})
                except Exception as e:
                    # TODO(asarfaty): subnets ids are changed, so recreating a
                    # subnet will fail on overlapping ips.
                    LOG.error(">>Failed to create %(resource)s %(name)s: "
                              "%(e)s",
                              {'resource': resource, 'e': e,
                               'name': obj_data.get('name') or orig_id})
                    continue

                # special cases for different objects after create:
                if resource == 'security_group':
                    sg_id = obj_data.get('name') or obj_data['id']
                    for rule in sg_rules:
                        rule_data = prepare.prepare_security_group_rule(rule)
                        try:
                            plugin.create_security_group_rule(
                                context, {'security_group_rule': rule_data})
                        except ext_sg.SecurityGroupRuleExists:
                            # default rules were already created.
                            # prevent logger from logging this exception
                            sys.exc_clear()
                        except Exception as e:
                            LOG.error(
                                ">>Failed to create security group %(name)s "
                                "rules: %(e)s",
                                {'name': sg_id, 'e': e})
                elif resource == 'subnet':
                    if enable_dhcp:
                        dhcp_subnets.append(created_obj['id'])

        # Enable dhcp on all the relevant subnets (after creating all ports,
        # to maintain original IPs):
        if dhcp_subnets:
            for subnet_id in dhcp_subnets:
                try:
                    plugin.update_subnet(
                        context, subnet_id,
                        {'subnet': {'enable_dhcp': True}})

                except Exception as e:
                    LOG.error("Failed to enable DHCP on subnet %(subnet)s:"
                              " %(e)s",
                              {'subnet': subnet_id, 'e': e})

        # Add static routes (after all router interfaces and gateways are set)
        for obj_data in objects['router']:
            if 'routes' in obj_data:
                try:
                    plugin.update_router(
                        context, obj_data['id'],
                        {'router': {'routes': obj_data['routes']}})
                except Exception as e:
                    LOG.error("Failed to add routes to router %(rtr)s: "
                              "%(e)s",
                              {'rtr': obj_data['id'], 'e': e})

    LOG.info(">>>Done Creating all objects in NSX-T.")