def get_switch_workflow(switch): # if switch specific value set, then return if switch.workflow: return switch.workflow # else fetch tier default value default = Switch.objects.get(topology_id=switch.topology_id, tier=switch.tier, dummy=True) if default.workflow: return default.workflow return workflow.get_workflow(BOOTSTRAP_WORKFLOW_ID)
def update_switch(fab_id, switch_id, data, user): switch = Switch.objects.get(pk=switch_id) # check if switch is already booted if switch.boot_detail: if any([switch.name != data[NAME], switch.model.id != data[MODEL], switch.serial_num != data[SERIAL_NUM]]): raise IgniteException(ERR_NO_NAME_CHANGE) # check if switch already exists with new name # switch name is searched across all fabrics if (switch.name != data[NAME] and Switch.objects.filter(topology__is_fabric=True, dummy=False, name=data[NAME])): raise IgniteException(ERR_SW_NAME_IN_USE) switch.name = data[NAME] # check if switch already exists with new serial num # note: serial numbers are unique across fabrics if (data[SERIAL_NUM] and switch.serial_num != data[SERIAL_NUM] and Switch.objects.filter(dummy=False, serial_num=data[SERIAL_NUM])): raise IgniteException(ERR_SERIAL_NUM_IN_USE) # check if serial_num exists in discovery rules find_dup_serial_discovery([data[SERIAL_NUM]]) switch.serial_num = data[SERIAL_NUM] new_model = get_switch(data[MODEL]) # is there a change in model? change = True if new_model != switch.model else False logger.debug("%schange in switch model", "no " if not change else "") # save new values switch.model = new_model switch.image_profile = (image.get_profile(data[IMAGE_PROFILE]) if data[IMAGE_PROFILE] else None) switch.config_profile = (config.get_profile(data[CONFIG_PROFILE]) if data[CONFIG_PROFILE] else None) switch.feature_profile = (feature.get_profile(data[FEATURE_PROFILE]) if data[FEATURE_PROFILE] else None) switch.workflow = (workflow.get_workflow(data[WORKFLOW]) if data[WORKFLOW] else None) switch.save() if change: BaseTopology.get_object(fab_id, user).update_model(switch) else: Fabric.objects.filter(pk=fab_id).update(updated_by=user)
def update_profiles(fab_id, data, user): # setting global level config and feture profiles fabric = Fabric.objects.get(pk=fab_id) if data[CONFIG_PROFILE]: fabric.config_profile = config.get_profile(data[CONFIG_PROFILE]) else: fabric.config_profile = None if data[FEATURE_PROFILE]: fabric.feature_profile = feature.get_profile(data[FEATURE_PROFILE]) else: fabric.feature_profile = None fabric.save() cfg = dict() feat = dict() wf = dict() # store tier default config & feature profile for item in data[PROFILES]: # 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 # update profiles in fabric default switches for switch in Switch.objects.filter(topology_id=fab_id, dummy=True): switch.config_profile = cfg[switch.tier] switch.feature_profile = feat[switch.tier] switch.workflow = wf[switch.tier] switch.save() Fabric.objects.filter(pk=fab_id).update(updated_by=user)
def add_discoveryrule(data, username): config_obj = get_profile(data[CONFIG]) image = image_profile.get_profile(data[IMAGE]) rule_object = DiscoveryRule() if data[WORKFLOW]: wf = get_workflow(data[WORKFLOW]) rule_object.workflow = wf rule_object.name = data[NAME] rule_object.match = data[MATCH].lower() if str(data[MATCH]) == SERIAL_NUM: find_repeat_serial_num(data[SUBRULES]) find_duplicate(data[SUBRULES]) rule_object.priority = data[PRIORITY] rule_object.config = config_obj rule_object.image = image rule_object.subrules = data[SUBRULES] rule_object.updated_by = username rule_object.save() return rule_object
def ignite_request(request): if ACCESS_PROTOCOL not in ACCESS_PROTOCOLS: msg = ERR_PROTO_NOT_FOUND + "- " + ACCESS_PROTOCOL return _get_server_response(False, err_msg=msg) serial_number = request[SERIAL_NUM] model_type = request[MODEL_TYPE] switch, match_type = search_fabric(request) if switch: logger.info("config type - " + switch.config_type) cfg_file = None if switch.config_type == POAP_CONFIG: if (switch.topology.feature_profile or get_switch_feature_profile(switch)): logger.debug("Switch have feture profiles applied") build_config(switch.topology.id) else: # delete cfg file try: os.remove(os.path.join(REPO_PATH + str(switch.id) + '.cfg')) except OSError as e: pass # build new cfg build_switch_config(switch) cfg_file = str(switch.id) + CFG_FILE_EXT cfg_file = get_cfg_file_path(REPO_PATH, cfg_file, FILE_REPO_PATH) if not cfg_file: logger.error(ERR_CFG_NOT_FOUND) return _get_server_response(False, err_msg=ERR_CFG_NOT_FOUND) logger.info("config file found for " + switch.config_type) elif switch.config_type == RUNNING_CONFIG: running_config = get_latest_version(switch.id) cfg_file = get_cfg_file_path(SWITCH_CONFIG_PATH, running_config, FILE_SWITCH_PATH) if not cfg_file: logger.error(ERR_CFG_NOT_FOUND) return _get_server_response(False, err_msg=ERR_CFG_NOT_FOUND) logger.info("config file found for " + switch.config_type) # fetch switch workflow wf = get_switch_workflow(switch) # fetch switch image image = get_switch_image(switch) wf_file = str(switch.id) + YAML_FILE_EXT logger.debug("Build workflow") with open(os.path.join(REPO_PATH, wf_file), 'w') as output_fh: output_fh.write(yaml.safe_dump(build_workflow(wf, image, cfg_file, serial_number), default_flow_style=False)) update_boot_detail(switch, match_type=match_type, boot_status=BOOT_PROGRESS, boot_time=timezone.now(), model_type=model_type) #update switch serial number if switch.serial_num != serial_number: logger.debug("Received serial number % s\ configured serial number % s" % (serial_number, switch.serial_num)) try: discoveryrule.find_duplicate([serial_number]) except IgniteException: logger.debug(ERR_SERIAL_NUM_IN_USE) return _get_server_response(False, err_msg=ERR_SERIAL_NUM_IN_USE) switch.serial_num = serial_number switch.save() if ACCESS_PROTOCOL in [PROTO_SCP, PROTO_SFTP]: wf_file = os.path.join(REPO_PATH, wf_file) elif ACCESS_PROTOCOL == PROTO_HTTP: wf_file = os.path.join(DOWNLOAD_URL, YAML, wf_file) else: wf_file = os.path.join(FILE_REPO_PATH, wf_file) return _get_server_response(True, wf_file) logger.debug("No match found in fabric") rule = discoveryrule.match_discovery_rules(request) wf = None if rule: try: switch = Switch.objects.get(name=serial_number, topology__isnull=True) except Switch.DoesNotExist: switch = Switch() switch.name = serial_number switch.serial_num = serial_number switch.save() if rule.workflow: wf = rule.workflow else: wf = get_workflow(BOOTSTRAP_WORKFLOW_ID) logger.debug("Discovery rule match- workflow: %s, config: %s" % (wf.name, rule.config.name)) # delete cfg file try: os.remove(os.path.join(REPO_PATH + str(switch.id) + '.cfg')) except OSError as e: pass # build new cfg build_switch_config(switch, switch_cfg=rule.config) if rule.match == SERIAL_NUM: match_type = SERIAL_NUMBER else: match_type = NEIGHBOR update_boot_detail(switch, match_type=match_type, discovery_rule=rule, boot_time=timezone.now(), boot_status=BOOT_PROGRESS, model_type=model_type) cfg_file = str(switch.id) + CFG_FILE_EXT wf_file = str(switch.id) + YAML_FILE_EXT logger.debug("Build workflow") if ACCESS_PROTOCOL in [PROTO_SCP, PROTO_SFTP]: cfg_file = os.path.join(REPO_PATH, cfg_file) elif ACCESS_PROTOCOL == PROTO_HTTP: cfg_file = os.path.join(DOWNLOAD_URL, CONFIG, cfg_file) else: cfg_file = os.path.join(FILE_REPO_PATH, cfg_file) with open(os.path.join(REPO_PATH, wf_file), 'w') as output_fh: output_fh.write(yaml.safe_dump(build_workflow(wf, rule.image, cfg_file, serial_number), default_flow_style=False)) if ACCESS_PROTOCOL in [PROTO_SCP, PROTO_SFTP]: wf_file = os.path.join(REPO_PATH, wf_file) elif ACCESS_PROTOCOL == PROTO_HTTP: wf_file = os.path.join(DOWNLOAD_URL, YAML, wf_file) else: wf_file = os.path.join(FILE_REPO_PATH, wf_file) return _get_server_response(True, wf_file) return _get_server_response(False)
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
def update_switch(fab_id, switch_id, data, user): switch = Switch.objects.get(pk=switch_id) # check if switch is already booted if switch.boot_detail: if data[CONFIG_TYPE] == RUNNING_CONFIG: logger.debug("input config type- " + data[CONFIG_TYPE]) if SwitchConfig.objects.filter(switch_id=switch_id): switch.config_type = data[CONFIG_TYPE] else: logger.error(ERR_RUN_CONFIG_NOT_AVAL) raise IgniteException(ERR_RUN_CONFIG_NOT_AVAL) else: switch.config_type = data[CONFIG_TYPE] if any([ switch.name != data[NAME], switch.model.id != data[MODEL], switch.serial_num != data[SERIAL_NUM] ]): raise IgniteException(ERR_NO_NAME_CHANGE) # check if switch already exists with new name # switch name is searched across all fabrics if (switch.name != data[NAME] and Switch.objects.filter( topology__is_fabric=True, dummy=False, name=data[NAME])): raise IgniteException(ERR_SW_NAME_IN_USE) switch.name = data[NAME] # check if switch already exists with new serial num # note: serial numbers are unique across fabrics if (data[SERIAL_NUM] and switch.serial_num != data[SERIAL_NUM] and Switch.objects.filter(dummy=False, serial_num=data[SERIAL_NUM])): raise IgniteException(ERR_SERIAL_NUM_IN_USE) # check if serial_num exists in discovery rules find_dup_serial_discovery([data[SERIAL_NUM]]) switch.serial_num = data[SERIAL_NUM] new_model = get_switch(data[MODEL]) # is there a change in model? change = True if new_model != switch.model else False logger.debug("%schange in switch model", "no " if not change else "") if change: if data[MODEL] == 1: logger.debug("Unknown switch model can not be assigned") raise IgniteException(ERR_CAN_NOT_ASSIGN_UNKOWN_MODEL) # save new values switch.model = new_model switch.image_profile = (image.get_profile(data[IMAGE_PROFILE]) if data[IMAGE_PROFILE] else None) switch.config_profile = (config.get_profile(data[CONFIG_PROFILE]) if data[CONFIG_PROFILE] else None) switch.feature_profile = (feature.get_profile(data[FEATURE_PROFILE]) if data[FEATURE_PROFILE] else None) switch.workflow = (workflow.get_workflow(data[WORKFLOW]) if data[WORKFLOW] else None) switch.save() if change: BaseTopology.get_object(fab_id, user).update_model(switch) else: Fabric.objects.filter(pk=fab_id).update(updated_by=user)