Exemple #1
0
def create_empty_fabric(data):

    logger.debug("creating empty fabric")
    fabric = Fabric()
    fabric.model_name = LEAF_SPINE
    fabric.is_fabric = True
    fabric.is_saved = False
    fabric.is_discovered = True
    fabric.save()

    fabric.defaults = dict()
    fabric.defaults[SWITCHES] = list()
    fabric.defaults[LINKS] = list()

    # add switch to discovery defaults
    logger.debug("Assigning defaults to dummy fabric")
    fabric.defaults[SWITCHES].append(get_default_discovery_switch(fabric.id, SPINE))
    fabric.defaults[SWITCHES].append(get_default_discovery_switch(fabric.id, LEAF))
    fabric.defaults[LINKS].append(get_default_discovery_link(fabric.id))
    logger.debug("Fabric created")
    return fabric.id
Exemple #2
0
def clone_fabric(fab_id, data, user=""):

    old_fabric = Topology.objects.get(pk=fab_id)

    # create new fabric
    new_fabric = Fabric()
    new_fabric.name = data[NAME]
    new_fabric.model_name = old_fabric.model_name
    new_fabric.is_fabric = True

    if old_fabric.config_profile:
        new_fabric.config_profile = old_fabric.config_profile
    if old_fabric.feature_profile:
        new_fabric.feature_profile = old_fabric.feature_profile

    new_fabric.updated_by = user
    new_fabric.save()

    # fabric defaults, switches & links objects
    new_fabric.defaults = dict()
    new_fabric.defaults[SWITCHES] = list()
    new_fabric.defaults[LINKS] = list()
    new_fabric.switches = list()
    new_fabric.links = list()

    switch_dict = dict()

    for switch in Switch.objects.filter(topology_id=old_fabric.id
                                        ).order_by(ID):
        # save id for later
        switch_id = switch.id

        switch.id = None
        switch.topology = new_fabric
        switch.serial_num = ""
        switch.boot_detail = None

        if not switch.dummy:
            # append fabric name to switch name
            if data[NAME_OPERATION] == REPLACE:
                name = switch.name.replace(old_fabric.name, new_fabric.name)
                if Switch.objects.filter(name=name):
                    raise IgniteException(ERR_CLONE_FABRIC)
                switch.name = name
            elif data[NAME_OPERATION] == PREPEND:
                name = new_fabric.name + "_" + switch.name
                if Switch.objects.filter(name=name):
                    raise IgniteException(ERR_CLONE_FABRIC)
                switch.name = name

        switch.save()

        # store fabric switch id to switch mapping
        switch_dict[switch_id] = switch

        if switch.dummy:
            new_fabric.defaults[SWITCHES].append(switch)
        else:
            new_fabric.switches.append(switch)

    for link in Link.objects.filter(topology_id=old_fabric.id):
        link.id = None
        link.topology = new_fabric

        if link.src_switch:
            link.src_switch = switch_dict[link.src_switch.id]
            link.dst_switch = switch_dict[link.dst_switch.id]
        else:
            link.src_switch = None
            link.dst_switch = None

        link.save()

        if not link.dummy:
            new_fabric.links.append(link)
        elif link.dummy and not link.src_switch:
            link.src_tier = link.src_ports
            link.dst_tier = link.dst_ports
            new_fabric.defaults[LINKS].append(link)
    new_fabric.save()

    return new_fabric
Exemple #3
0
def add_fabric(data, user):
    # get topology
    top = Topology.objects.get(pk=data[TOPOLOGY])

    logger.debug("fabric name = %s, topology name = %s, model = %s",
                 data[NAME], top.name, top.model_name)

    # create new fabric
    fabric = Fabric()
    fabric.name = data[NAME]
    fabric.model_name = top.model_name
    fabric.is_fabric = True

    if data[CONFIG_PROFILE]:
        fabric.config_profile = config.get_profile(data[CONFIG_PROFILE])
    if data[FEATURE_PROFILE]:
        fabric.feature_profile = feature.get_profile(data[FEATURE_PROFILE])
    fabric.updated_by = user
    fabric.save()

    cfg = dict()
    feat = dict()
    wf = dict()

    # store tier default config & feature profile
    for item in data[SWITCHES]:
        # if profile id is zero, then store null
        # it means - do not apply config/feature/workflow for this tier
        if item[CONFIG_PROFILE]:
            cfg[item[TIER]] = config.get_profile(item[CONFIG_PROFILE])
        else:
            cfg[item[TIER]] = None

        if item[FEATURE_PROFILE]:
            feat[item[TIER]] = feature.get_profile(item[FEATURE_PROFILE])
        else:
            feat[item[TIER]] = None

        if item[WORKFLOW]:
            wf[item[TIER]] = workflow.get_workflow(item[WORKFLOW])
        else:
            wf[item[TIER]] = None

    # fabric defaults, switches & links objects
    fabric.defaults = dict()
    fabric.defaults[SWITCHES] = list()
    fabric.defaults[LINKS] = list()
    fabric.switches = list()
    fabric.links = list()

    # map of topology switch id to fabric switch object
    # needed when creating fabric links
    switch_dict = dict()

    # duplicate all topology switches into fabric
    for switch in Switch.objects.filter(topology_id=top.id).order_by(ID):
        # save id for later
        switch_id = switch.id

        switch.id = None
        switch.topology = fabric

        if switch.dummy:
            # set config & feature profile for fabric default switch
            switch.config_profile = cfg[switch.tier]
            switch.feature_profile = feat[switch.tier]
            switch.workflow = wf[switch.tier]
        else:
            # append fabric name to switch name
            switch.name = fabric.name + "_" + switch.name

        switch.save()

        # store topology switch id to switch mapping
        switch_dict[switch_id] = switch

        if switch.dummy:
            fabric.defaults[SWITCHES].append(switch)
        else:
            fabric.switches.append(switch)

    # duplicate all topology links into fabric
    for link in Link.objects.filter(topology_id=top.id):
        link.id = None
        link.topology = fabric

        if link.src_switch:
            link.src_switch = switch_dict[link.src_switch.id]
            link.dst_switch = switch_dict[link.dst_switch.id]
        else:
            link.src_switch = None
            link.dst_switch = None

        link.save()

        if not link.dummy:
            fabric.links.append(link)
        elif link.dummy and not link.src_switch:
            link.src_tier = link.src_ports
            link.dst_tier = link.dst_ports
            fabric.defaults[LINKS].append(link)

    return fabric
Exemple #4
0
    def post(self, request, format=None):

        success = True
        resp = {}
        resp['Error'] = ' '
        serializer = FabricSerializer(data=request.data)
        topology = Topology.objects.get(id=request.data['topology_id'])
        topology_json = json.loads(topology.topology_json)
        me = RequestValidator(request.META)
        if serializer.is_valid():
            if request.data['instance'] < 1:
                logger.error("Fabric Instances cannot be less than 1")
            else:
                fabric_obj = Fabric()
                fabric_obj.name = request.data['name']
                fabric_obj.user_id = me.user_is_exist().user_id
                fabric_obj.topology = topology
                topology.used += 1
                topology.save()
                fabric_obj.instance = request.data['instance']
                fabric_obj.validate = request.data['validate']
                fabric_obj.locked = request.data['locked']
                fabric_obj.config_json = json.dumps(
                    request.data['config_json'])
                for config in request.data['config_json']:
                    config_obj = Configuration.objects.get(
                        id=config['configuration_id'])
                    config_obj.used += 1
                    config_obj.save()
                fabric_obj.submit = request.data['submit']
                try:
                    fabric_obj.system_id = json.dumps(
                        request.data['system_id'])
                except:
                    fabric_obj.system_id = []
                try:
                    fabric_obj.save()
                except:
                    logger.error("Failed to create Fabric: " + fabric_obj.name)
                    resp['Error'] = 'Failed to create Fabric'
                    return JsonResponse(resp,
                                        status=status.HTTP_400_BAD_REQUEST)

                # filling discovery rule with system_id
                try:
                    sys_id_obj = json.loads(fabric_obj.system_id)
                    config_obj = json.loads(fabric_obj.config_json)
                    regex = fabric_obj.name + "(_)([1-9][0-9]*)(_)([a-zA-Z]*-[1-9])"
                    for switch_systemId_info in sys_id_obj:
                        if not success:
                            break
                        switch_name = (re.search(
                            regex, switch_systemId_info['name'])).group(4)
                        replica_num = int(
                            (re.search(regex,
                                       switch_systemId_info['name'])).group(2))
                        system_id = switch_systemId_info['system_id']
                        for config in config_obj:
                            if switch_name == config['name']:
                                discoveryrule_name = 'serial_' + switch_systemId_info[
                                    'system_id']
                                old_dis_rule = DiscoveryRule.objects.filter(
                                    name=discoveryrule_name)
                                if old_dis_rule:
                                    obj = DiscoveryRule.objects.get(
                                        name=discoveryrule_name)
                                    logger.error("DIscovery Rule existed with system id: "+switch_systemId_info\
                                                 ['system_id']+" wiht switch_name: "+obj.switch_name)
                                    if obj.fabric_id == fabric_obj.id:
                                        resp['Error'] = 'Serial id: '+switch_systemId_info['system_id']+\
                                                        ' is repeated in this Fabric'
                                    else:
                                        resp['Error'] = "serial id: "+switch_systemId_info['system_id']+\
                                                        " is existed with switch: "+obj.switch_name
                                    logger.error(resp['Error'])
                                    success = False
                                    break

                                dis_rule_obj = DiscoveryRule()
                                dis_rule_obj.priority = 100
                                dis_rule_obj.name = discoveryrule_name
                                dis_rule_obj.config_id = config[
                                    'configuration_id']
                                dis_rule_obj.match = 'serial_id'
                                dis_rule_obj.subrules = [system_id]
                                dis_rule_obj.fabric_id = fabric_obj.id
                                dis_rule_obj.replica_num = replica_num
                                dis_rule_obj.switch_name = switch_systemId_info[
                                    'name']
                                dis_rule_obj.save()
                except:
                    success = False
                    logger.error('Failed to update discoveryRule DB with system_id rule for fabric_id: '+\
                                 str(fabric_obj.id))
                    resp['Error'] = 'Failed to update DiscoveryRule DB'

                if success:
                    if (generate_fabric_rules(request.data['name'],\
                    request.data['instance'], fabric_obj, request.data['config_json'],\
                    topology_json)):
                        serializer = FabricGetSerializer(fabric_obj)
                        logger.info("Successfully created Fabric id: " +
                                    str(fabric_obj.id))
                        return Response(serializer.data,
                                        status=status.HTTP_201_CREATED)
                    else:
                        success = False
                        logger.error("Failed to update FabricRuleDb: " +
                                     fabric_obj.name)
                        resp['Error'] = 'Failed to update FabricRule DB'

                if not success:
                    try:
                        DiscoveryRule.objects.filter(
                            fabric_id=fabric_obj.id).delete()
                    except:
                        pass
                    Fabric.objects.filter(id=fabric_obj.id).delete()
                    logger.error("Failed to create Fabric: " + fabric_obj.name)
                    return JsonResponse(resp,
                                        status=status.HTTP_400_BAD_REQUEST)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Exemple #5
0
 def post(self, request, format=None):
     
     success = True
     resp = {}
     resp['Error'] = ' '
     serializer = FabricSerializer(data=request.data)
     topology = Topology.objects.get(id=request.data['topology_id'])
     topology_json = json.loads(topology.topology_json)
     me = RequestValidator(request.META)
     if serializer.is_valid():
         if request.data['instance'] < 1:
             logger.error("Fabric Instances cannot be less than 1")
         else:
             fabric_obj = Fabric()
             find_dup_data = {'system_id':['system_id','name'], 'config_json':['name']}
             for key,val in find_dup_data.iteritems():
                 for value in val:
                     err_msg, isError = findDuplicate(request.data[key], value)
                     if isError:
                         resp['Error'] = err_msg
                         return Response(resp, status=status.HTTP_400_BAD_REQUEST)
             err = uniqueSystenmId(request.data['system_id'],fabric_obj.id)
             if err != "":
                 resp['Error'] = err
                 return Response(resp, status=status.HTTP_400_BAD_REQUEST)
             fabric_obj.name = request.data['name']
             fabric_obj.user_id = me.user_is_exist().user_id
             fabric_obj.topology = topology
             topology.used += 1
             topology.save()
             fabric_obj.instance = request.data['instance']
             fabric_obj.validate = request.data['validate']
             fabric_obj.locked = request.data['locked']
             fabric_obj.config_json = json.dumps(request.data['config_json'])
             for config in request.data['config_json']:
                 config_obj = Configuration.objects.get(id = config['configuration_id'])
                 config_obj.used += 1
                 config_obj.save()
             fabric_obj.submit = request.data['submit']
             try:
                 fabric_obj.system_id = json.dumps(request.data['system_id'])
             except:
                 fabric_obj.system_id = []
             """
             try:
                 fabric_obj.profiles = json.dumps(request.data['profiles'])
             except:
                 fabric_obj.profiles = json.dumps({})
             """    
             try:   # fill image details
                 fabric_obj.image_details = json.dumps(request.data['image_details'])
             except:
                 fabric_obj.image_details = json.dumps({})
             try:  # save object
                 fabric_obj.save()
             except:
                 logger.error("Failed to create Fabric: " + fabric_obj.name)
                 resp['Error'] = 'Failed to create Fabric' 
                 return JsonResponse(resp,status=status.HTTP_400_BAD_REQUEST)
                             
             # filling discovery rule with system_id
             success, resp, dis_bulk_obj = add_dis_rule(request.data,success,resp,fabric_obj.id)
             
             if success:   
                 if (generate_fabric_rules(request.data['name'],\
                 request.data['instance'], fabric_obj, request.data['config_json'],\
                 topology_json)):
                     serializer = FabricGetSerializer(fabric_obj)
                     logger.info("Successfully created Fabric id: " + str(fabric_obj.id))
                     try:
                         for obj in dis_bulk_obj:
                             obj.save()
                     except:
                         logger.error('failed to save dis_rule_obj')
                         resp['Error']='Failed to save DiscoveryRules'
                         return JsonResponse(resp,status=status.HTTP_400_BAD_REQUEST)
                     return Response(serializer.data, status=status.HTTP_201_CREATED)
                 else:
                     success = False
                     logger.error("Failed to update FabricRuleDb: " + fabric_obj.name)
                     resp['Error'] = 'Failed to update FabricRule DB'
                     
                 
             if not success:
                 try:
                     DiscoveryRule.objects.filter(fabric_id = fabric_obj.id).delete()
                 except:
                     pass
                 Fabric.objects.filter(id = fabric_obj.id).delete()
                 logger.error("Failed to create Fabric: " + fabric_obj.name)
                 return JsonResponse(resp,status=status.HTTP_400_BAD_REQUEST)
                     
     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Exemple #6
0
    def post(self, request, format=None):

        success = True
        resp = {}
        resp['Error'] = ' '
        serializer = FabricSerializer(data=request.data)
        topology = Topology.objects.get(id=request.data['topology_id'])
        topology_json = json.loads(topology.topology_json)
        me = RequestValidator(request.META)
        if serializer.is_valid():
            if request.data['instance'] < 1:
                logger.error("Fabric Instances cannot be less than 1")
            else:
                fabric_obj = Fabric()
                find_dup_data = {
                    'system_id': ['system_id', 'name'],
                    'config_json': ['name']
                }
                for key, val in find_dup_data.iteritems():
                    for value in val:
                        err_msg, isError = findDuplicate(
                            request.data[key], value)
                        if isError:
                            resp['Error'] = err_msg
                            return Response(resp,
                                            status=status.HTTP_400_BAD_REQUEST)
                err = uniqueSystenmId(request.data['system_id'], fabric_obj.id)
                if err != "":
                    resp['Error'] = err
                    return Response(resp, status=status.HTTP_400_BAD_REQUEST)
                fabric_obj.name = request.data['name']
                fabric_obj.user_id = me.user_is_exist().user_id
                fabric_obj.topology = topology
                topology.used += 1
                topology.save()
                fabric_obj.instance = request.data['instance']
                fabric_obj.validate = request.data['validate']
                fabric_obj.locked = request.data['locked']
                fabric_obj.config_json = json.dumps(
                    request.data['config_json'])
                for config in request.data['config_json']:
                    config_obj = Configuration.objects.get(
                        id=config['configuration_id'])
                    config_obj.used += 1
                    config_obj.save()
                fabric_obj.submit = request.data['submit']
                try:
                    fabric_obj.system_id = json.dumps(
                        request.data['system_id'])
                except:
                    fabric_obj.system_id = []
                """
                try:
                    fabric_obj.profiles = json.dumps(request.data['profiles'])
                except:
                    fabric_obj.profiles = json.dumps({})
                """
                try:  # fill image details
                    fabric_obj.image_details = json.dumps(
                        request.data['image_details'])
                except:
                    fabric_obj.image_details = json.dumps({})
                try:  # save object
                    fabric_obj.save()
                except:
                    logger.error("Failed to create Fabric: " + fabric_obj.name)
                    resp['Error'] = 'Failed to create Fabric'
                    return JsonResponse(resp,
                                        status=status.HTTP_400_BAD_REQUEST)

                # filling discovery rule with system_id
                success, resp, dis_bulk_obj = add_dis_rule(
                    request.data, success, resp, fabric_obj.id)

                if success:
                    if (generate_fabric_rules(request.data['name'],\
                    request.data['instance'], fabric_obj, request.data['config_json'],\
                    topology_json)):
                        serializer = FabricGetSerializer(fabric_obj)
                        logger.info("Successfully created Fabric id: " +
                                    str(fabric_obj.id))
                        try:
                            for obj in dis_bulk_obj:
                                obj.save()
                        except:
                            logger.error('failed to save dis_rule_obj')
                            resp['Error'] = 'Failed to save DiscoveryRules'
                            return JsonResponse(
                                resp, status=status.HTTP_400_BAD_REQUEST)
                        return Response(serializer.data,
                                        status=status.HTTP_201_CREATED)
                    else:
                        success = False
                        logger.error("Failed to update FabricRuleDb: " +
                                     fabric_obj.name)
                        resp['Error'] = 'Failed to update FabricRule DB'

                if not success:
                    try:
                        DiscoveryRule.objects.filter(
                            fabric_id=fabric_obj.id).delete()
                    except:
                        pass
                    Fabric.objects.filter(id=fabric_obj.id).delete()
                    logger.error("Failed to create Fabric: " + fabric_obj.name)
                    return JsonResponse(resp,
                                        status=status.HTTP_400_BAD_REQUEST)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Exemple #7
0
    def post(self, request, format=None):

        serializer = FabricSerializer(data=request.data)
        topology = Topology.objects.get(id=request.data['topology_id'])
        topology_json = json.loads(topology.topology_json)
        me = RequestValidator(request.META)
        if serializer.is_valid():
            if request.data['instance'] < 1:
                logger.error("Fabric Instances cannot be less than 1")
            else:
                fabric_obj = Fabric()
                fabric_obj.name = request.data['name']
                fabric_obj.user_id = me.user_is_exist().user_id
                fabric_obj.topology = topology
                topology.used += 1
                topology.save()
                fabric_obj.instance = request.data['instance']
                fabric_obj.validate = request.data['validate']
                fabric_obj.locked = request.data['locked']
                fabric_obj.config_json = json.dumps(request.data['config_json'])
                fabric_obj.submit = request.data['submit']
                fabric_obj.save()
                if (generate_fabric_rules(request.data['name'],\
                request.data['instance'], fabric_obj, request.data['config_json'],\
                topology_json)):
                    serializer = FabricGetSerializer(fabric_obj)
                    logger.info("Successfully created Fabric id: " + str(id))
                    return Response(serializer.data, status=status.HTTP_201_CREATED)
                else:
                    Fabric.objects.filter(id = fabric_obj.id).delete()
                    logger.error("Failed to create Fabric: " + fabric_obj.name)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Exemple #8
0
def create_empty_fabric(data):

    logger.debug("creating empty fabric")
    fabric = Fabric()
    fabric.model_name = LEAF_SPINE
    fabric.is_fabric = True
    fabric.is_saved = False
    fabric.is_discovered = True
    fabric.save()

    fabric.defaults = dict()
    fabric.defaults[SWITCHES] = list()
    fabric.defaults[LINKS] = list()

    # add switch to discovery defaults
    logger.debug("Assigning defaults to dummy fabric")
    fabric.defaults[SWITCHES].append(
        get_default_discovery_switch(fabric.id, SPINE))
    fabric.defaults[SWITCHES].append(
        get_default_discovery_switch(fabric.id, LEAF))
    fabric.defaults[LINKS].append(get_default_discovery_link(fabric.id))
    logger.debug("Fabric created")
    return fabric.id
Exemple #9
0
def clone_fabric(fab_id, data, user=""):

    old_fabric = Topology.objects.get(pk=fab_id)

    # create new fabric
    new_fabric = Fabric()
    new_fabric.name = data[NAME]
    new_fabric.model_name = old_fabric.model_name
    new_fabric.is_fabric = True

    if old_fabric.config_profile:
        new_fabric.config_profile = old_fabric.config_profile
    if old_fabric.feature_profile:
        new_fabric.feature_profile = old_fabric.feature_profile

    new_fabric.updated_by = user
    new_fabric.save()

    # fabric defaults, switches & links objects
    new_fabric.defaults = dict()
    new_fabric.defaults[SWITCHES] = list()
    new_fabric.defaults[LINKS] = list()
    new_fabric.switches = list()
    new_fabric.links = list()

    switch_dict = dict()

    for switch in Switch.objects.filter(
            topology_id=old_fabric.id).order_by(ID):
        # save id for later
        switch_id = switch.id

        switch.id = None
        switch.topology = new_fabric
        switch.serial_num = ""
        switch.boot_detail = None

        if not switch.dummy:
            # append fabric name to switch name
            if data[NAME_OPERATION] == REPLACE:
                name = switch.name.replace(old_fabric.name, new_fabric.name)
                if Switch.objects.filter(name=name):
                    raise IgniteException(ERR_CLONE_FABRIC)
                switch.name = name
            elif data[NAME_OPERATION] == PREPEND:
                name = new_fabric.name + "_" + switch.name
                if Switch.objects.filter(name=name):
                    raise IgniteException(ERR_CLONE_FABRIC)
                switch.name = name

        switch.save()

        # store fabric switch id to switch mapping
        switch_dict[switch_id] = switch

        if switch.dummy:
            new_fabric.defaults[SWITCHES].append(switch)
        else:
            new_fabric.switches.append(switch)

    for link in Link.objects.filter(topology_id=old_fabric.id):
        link.id = None
        link.topology = new_fabric

        if link.src_switch:
            link.src_switch = switch_dict[link.src_switch.id]
            link.dst_switch = switch_dict[link.dst_switch.id]
        else:
            link.src_switch = None
            link.dst_switch = None

        link.save()

        if not link.dummy:
            new_fabric.links.append(link)
        elif link.dummy and not link.src_switch:
            link.src_tier = link.src_ports
            link.dst_tier = link.dst_ports
            new_fabric.defaults[LINKS].append(link)
    new_fabric.save()

    return new_fabric
Exemple #10
0
def add_fabric(data, user):
    # get topology
    top = Topology.objects.get(pk=data[TOPOLOGY])

    logger.debug("fabric name = %s, topology name = %s, model = %s",
                 data[NAME], top.name, top.model_name)

    # create new fabric
    fabric = Fabric()
    fabric.name = data[NAME]
    fabric.model_name = top.model_name
    fabric.is_fabric = True

    if data[CONFIG_PROFILE]:
        fabric.config_profile = config.get_profile(data[CONFIG_PROFILE])
    if data[FEATURE_PROFILE]:
        fabric.feature_profile = feature.get_profile(data[FEATURE_PROFILE])
    fabric.updated_by = user
    fabric.save()

    cfg = dict()
    feat = dict()
    wf = dict()

    # store tier default config & feature profile
    for item in data[SWITCHES]:
        # if profile id is zero, then store null
        # it means - do not apply config/feature/workflow for this tier
        if item[CONFIG_PROFILE]:
            cfg[item[TIER]] = config.get_profile(item[CONFIG_PROFILE])
        else:
            cfg[item[TIER]] = None

        if item[FEATURE_PROFILE]:
            feat[item[TIER]] = feature.get_profile(item[FEATURE_PROFILE])
        else:
            feat[item[TIER]] = None

        if item[WORKFLOW]:
            wf[item[TIER]] = workflow.get_workflow(item[WORKFLOW])
        else:
            wf[item[TIER]] = None

    # fabric defaults, switches & links objects
    fabric.defaults = dict()
    fabric.defaults[SWITCHES] = list()
    fabric.defaults[LINKS] = list()
    fabric.switches = list()
    fabric.links = list()

    # map of topology switch id to fabric switch object
    # needed when creating fabric links
    switch_dict = dict()

    # duplicate all topology switches into fabric
    for switch in Switch.objects.filter(topology_id=top.id).order_by(ID):
        # save id for later
        switch_id = switch.id

        switch.id = None
        switch.topology = fabric

        if switch.dummy:
            # set config & feature profile for fabric default switch
            switch.config_profile = cfg[switch.tier]
            switch.feature_profile = feat[switch.tier]
            switch.workflow = wf[switch.tier]
        else:
            # append fabric name to switch name
            switch.name = fabric.name + "_" + switch.name

        switch.save()

        # store topology switch id to switch mapping
        switch_dict[switch_id] = switch
        if switch.dummy:
            fabric.defaults[SWITCHES].append(switch)
        else:
            fabric.switches.append(switch)

    # duplicate all topology links into fabric
    for link in Link.objects.filter(topology_id=top.id):
        link.id = None
        link.topology = fabric

        if link.src_switch:
            link.src_switch = switch_dict[link.src_switch.id]
            link.dst_switch = switch_dict[link.dst_switch.id]
        else:
            link.src_switch = None
            link.dst_switch = None

        link.save()

        if not link.dummy:
            fabric.links.append(link)
        elif link.dummy and not link.src_switch:
            link.src_tier = link.src_ports
            link.dst_tier = link.dst_ports
            fabric.defaults[LINKS].append(link)

    return fabric