def render_loadgens(request, file_id, duration=10): try: process_loadgens = rpyc.timed(globals.core_conn.root.process_loadgens, duration * 2) results = process_loadgens(file_id) results.wait() results = results.value if results is not None: output, total_bits, error, total_retransmits, total_byte, \ custom_attr, to_plot = results output = P4STA_utils.flt(output) custom_attr = P4STA_utils.flt(custom_attr) else: error = True output = [ "Sorry an error occured!", "The core returned NONE from loadgens which is a result" " of an internal error in the loadgen module." ] total_bits = total_retransmits = total_byte = 0 custom_attr = {"l4_type": "", "name_list": [], "elems": {}} cfg = P4STA_utils.read_result_cfg(file_id) return render( request, "middlebox/output_loadgen.html", { "cfg": cfg, "output": output, "total_gbits": analytics.find_unit_bit_byte(total_bits, "bit"), "cachebuster": str(time.time()).replace(".", ""), "total_retransmits": total_retransmits, "total_gbyte": analytics.find_unit_bit_byte(total_byte, "byte"), "error": error, "custom_attr": custom_attr, "filename": file_id, "time": time.strftime("%H:%M:%S %d.%m.%Y", time.localtime( int(file_id))) }) except Exception as e: print(e) return render(request, "middlebox/timeout.html", { "inside_ajax": True, "error": ("render loadgen error: " + str(e)) })
def get_stamper_startup_log(request): try: log = globals.core_conn.root.get_stamper_startup_log() log = P4STA_utils.flt(log) return render(request, "middlebox/stamper_startup_log.html", {"log": log}) except Exception as e: return render(request, "middlebox/timeout.html", { "inside_ajax": True, "error": ("stamper Log: " + str(e)) })
def ping(request): if request.is_ajax(): try: output = globals.core_conn.root.ping() output = P4STA_utils.flt(output) return render(request, "middlebox/output_ping.html", {"output": output}) except Exception as e: return render(request, "middlebox/timeout.html", { "inside_ajax": True, "error": ("ping error: " + str(e)) })
def stamper_status_wrapper(request, html_file): stamper_status = rpyc.timed(globals.core_conn.root.stamper_status, 40) stamper_status_job = stamper_status() try: stamper_status_job.wait() result = stamper_status_job.value cfg, lines_pm, running, dev_status = result cfg = P4STA_utils.flt(cfg) # cfg contains host status information lines_pm = P4STA_utils.flt(lines_pm) return render( request, html_file, { "dev_status": dev_status, "dev_is_running": running, "pm": lines_pm, "cfg": cfg }) except Exception as e: print(e) return render(request, "middlebox/timeout.html", { "inside_ajax": True, "error": ("stamper status error " + str(e)) })
def status_overview(request): try: status_overview = rpyc.timed(globals.core_conn.root.status_overview, 60)() status_overview.wait() cfg = status_overview.value cfg = P4STA_utils.flt(cfg) return render(request, "middlebox/output_status_overview.html", cfg) except Exception as e: print(e) return render(request, "middlebox/timeout.html", { "inside_ajax": True, "error": ("stamper status error: " + str(e)) })
def stamper_results(request): if request.is_ajax(): try: sw = globals.core_conn.root.stamper_results( globals.selected_run_id) sw = P4STA_utils.flt(sw) if "error" in sw: raise Exception(sw["error"]) return render(request, "middlebox/output_stamper_results.html", sw) except Exception as e: print(e) return render( request, "middlebox/timeout.html", { "inside_ajax": True, "error": ("render stamper results error: " + str(e)) })
def setup_devices(request): if request.method == "POST": print(request.POST) setup_devices_cfg = {} if request.POST.get("enable_stamper") == "on": setup_devices_cfg["stamper_user"] = request.POST["stamper_user"] setup_devices_cfg["stamper_ssh_ip"] = request.POST["stamper_ip"] setup_devices_cfg["selected_stamper"] = request.POST[ "selected_stamper"] target_cfg = globals.core_conn.root.get_target_cfg( setup_devices_cfg["selected_stamper"]) setup_devices_cfg["target_specific_dict"] = {} if "config" in target_cfg \ and "stamper_specific" in target_cfg["config"]: for cfg in target_cfg["config"]["stamper_specific"]: if cfg["target_key"] in request.POST: setup_devices_cfg["target_specific_dict"][ cfg["target_key"]] = request.POST[ cfg["target_key"]] if request.POST.get( "enable_ext_host") == "on" and "ext_host_user" in request.POST: setup_devices_cfg["ext_host_user"] = request.POST["ext_host_user"] setup_devices_cfg["ext_host_ssh_ip"] = request.POST["ext_host_ip"] setup_devices_cfg["selected_extHost"] = request.POST[ "selected_extHost"] setup_devices_cfg["selected_loadgen"] = request.POST[ "selected_loadgen"] setup_devices_cfg["loadgens"] = [] for i in range(1, 99): if ("loadgen_user_" + str(i)) in request.POST: loadgen = {"loadgen_user": request.POST[ "loadgen_user_" + str(i)], "loadgen_ssh_ip": request.POST[ "loadgen_ip_" + str(i)]} setup_devices_cfg["loadgens"].append(loadgen) print("===================================================") print("=== Setup Device Config from management UI: ======") print("===================================================") print(setup_devices_cfg) # only create install script if button is clicked if "create_setup_script_button" in request.POST: globals.core_conn.root.write_install_script(setup_devices_cfg) # now write config.json with new data if request.POST.get("enable_stamper") == "on": path = globals.core_conn.root.get_template_cfg_path( request.POST["selected_stamper"]) cfg = globals.core_conn.root.open_cfg_file(path) cfg["stamper_ssh"] = request.POST["stamper_ip"] cfg["stamper_user"] = request.POST["stamper_user"] if request.POST.get( "enable_ext_host") == "on" \ and "ext_host_user" in request.POST: cfg["ext_host_user"] = request.POST["ext_host_user"] cfg["ext_host_ssh"] = request.POST["ext_host_ip"] cfg["selected_extHost"] = request.POST["selected_extHost"] cfg["selected_loadgen"] = request.POST["selected_loadgen"] # add all loadgens to loadgen group 1 and 2 cfg["loadgen_groups"] = [ {"group": 1, "loadgens": [], "use_group": "checked"}, {"group": 2, "loadgens": [], "use_group": "checked"}] grp1 = setup_devices_cfg["loadgens"][ len(setup_devices_cfg["loadgens"]) // 2:] grp2 = setup_devices_cfg["loadgens"][ :len(setup_devices_cfg["loadgens"]) // 2] id_c = 1 for loadgen in grp1: cfg["loadgen_groups"][0]["loadgens"].append( {"id": id_c, "loadgen_iface": "", "loadgen_ip": "", "loadgen_mac": "", "real_port": "", "p4_port": "", "ssh_ip": loadgen["loadgen_ssh_ip"], "ssh_user": loadgen["loadgen_user"]}) id_c = id_c + 1 id_c = 1 for loadgen in grp2: cfg["loadgen_groups"][1]["loadgens"].append( {"id": id_c, "loadgen_iface": "", "loadgen_ip": "", "loadgen_mac": "", "real_port": "", "p4_port": "", "ssh_ip": loadgen["loadgen_ssh_ip"], "ssh_user": loadgen["loadgen_user"]}) id_c = id_c + 1 if globals.core_conn.root.check_first_run(): P4STA_utils.write_config(cfg) globals.core_conn.root.first_run_finished() return HttpResponseRedirect("/run_setup_script/") # cancel case globals.core_conn.root.first_run_finished() return HttpResponseRedirect("/") else: # request the page print("### Setup Devices #####") params = {} params["stampers"] = P4STA_utils.flt( globals.core_conn.root.get_all_targets()) params["stampers"].sort(key=lambda y: y.lower()) params["extHosts"] = P4STA_utils.flt( globals.core_conn.root.get_all_extHost()) params["extHosts"].sort(key=lambda y: y.lower()) # bring python on position 1 if "PythonExtHost" in params["extHosts"]: params["extHosts"].insert(0, params["extHosts"].pop( params["extHosts"].index("PythonExtHost"))) params["loadgens"] = P4STA_utils.flt( globals.core_conn.root.get_all_loadGenerators()) params["loadgens"].sort(key=lambda y: y.lower()) params["isFirstRun"] = globals.core_conn.root.check_first_run() all_target_cfg = {} for stamper in params["stampers"]: # directly converting to json style because True # would be uppercase otherwise => JS needs "true" all_target_cfg[stamper] = P4STA_utils.flt( globals.core_conn.root.get_stamper_target_obj( target_name=stamper).target_cfg) params["all_target_cfg"] = json.dumps(all_target_cfg) return render(request, "middlebox/setup_page.html", {**params})
def updateCfg(request): print(request.POST) cfg = P4STA_utils.read_current_cfg() target_cfg = globals.core_conn.root.get_target_cfg() ports = globals.core_conn.root.get_ports() real_ports = ports["real_ports"] logical_ports = ports["logical_ports"] try: # if target has changed first request all port config again if cfg["selected_target"] is not request.POST["target"]: cfg["selected_target"] = request.POST["target"] cfg = P4STA_utils.flt(cfg) P4STA_utils.write_config(cfg) target_cfg = globals.core_conn.root.get_target_cfg() ports = globals.core_conn.root.get_ports() real_ports = ports["real_ports"] logical_ports = ports["logical_ports"] cfg["selected_loadgen"] = request.POST["selected_loadgen"] cfg["selected_extHost"] = request.POST["selected_extHost"] # rebuild loadgen_groups list based on user choice if len(cfg["loadgen_groups"]) != int( request.POST["num_loadgen_groups"]): cfg["loadgen_groups"] = [] for i in range(1, int(request.POST["num_loadgen_groups"]) + 1): cfg["loadgen_groups"].append({"group": i, "loadgens": []}) for loadgen_grp in cfg["loadgen_groups"]: # num_servers = int(request.POST["num_grp_" + str(loadgen_grp["group"])]) servers = [] i = 1 for j in range(1, num_servers + 1): s = {"id": j} _grp = str(loadgen_grp["group"]) _key = "s" + _grp + "_" + str(i) + "_real_port" while _key not in request.POST: i += 1 if i == 99: break s["real_port"] = str(request.POST["s" + _grp + "_" + str(i) + "_real_port"]) try: s["p4_port"] = logical_ports[real_ports.index( s["real_port"])].strip("\n") except Exception as e: print("FAILED: Finding: " + str(e)) s["p4_port"] = s["real_port"] s["ssh_ip"] = str(request.POST["s" + _grp + "_" + str(i) + "_ssh_ip"]) s["ssh_user"] = str(request.POST["s" + _grp + "_" + str(i) + "_ssh_user"]) s["loadgen_iface"] = str( request.POST["s" + _grp + "_" + str(i) + "_loadgen_iface"]) s["loadgen_mac"] = str( request.POST["s" + str(loadgen_grp["group"]) + "_" + str(i) + "_loadgen_mac"]) s["loadgen_ip"] = str( request.POST["s" + _grp + "_" + str(i) + "_loadgen_ip"]).split(" ")[0].split("/")[0] if "s" + _grp + "_" + str(i) + "_namespace" in request.POST: s["namespace_id"] = str( request.POST["s" + str(loadgen_grp["group"]) + "_" + str(i) + "_namespace"]) # read target specific config from webinterface for t_inp in target_cfg["inputs"]["input_table"]: try: if "s" + _grp + "_" + str(i) + "_" + \ t_inp["target_key"] in request.POST: s[t_inp["target_key"]] = str( request.POST["s" + str(loadgen_grp["group"]) + "_" + str(i) + "_" + t_inp["target_key"]]) elif "restrict" not in t_inp \ or t_inp["restrict"] == "loadgen": s[t_inp["target_key"]] = "" except Exception as e: print(traceback.format_exc()) print("\n#\nError parsing special target " "config parameters:" + str(e)) servers.append(s) i += 1 if str(request.POST["add_to_grp_" + _grp]) == "1": s = {} s["id"] = num_servers + 1 s["real_port"] = "" s["p4_port"] = "" s["loadgen_ip"] = "" s["ssh_ip"] = "" s["ssh_user"] = "" s["loadgen_iface"] = "" # add default values to target specific inputs for t_inp in target_cfg["inputs"]["input_table"]: if "default_value" in t_inp: s[t_inp["target_key"]] = t_inp["default_value"] else: s[t_inp["target_key"]] = "" servers.append(s) # set target specific default values for s in servers: for t_inp in target_cfg["inputs"]["input_table"]: if "default_value" in t_inp and t_inp["target_key"] in s \ and s[t_inp["target_key"]] == "": s[t_inp["target_key"]] = t_inp["default_value"] loadgen_grp["loadgens"] = servers cfg["dut_ports"] = [] for loadgen_grp in cfg["loadgen_groups"]: cfg["dut_ports"].append({"id": loadgen_grp["group"]}) try: # read target specific config from webinterface for t_inp in target_cfg["inputs"]["input_individual"]: if t_inp["target_key"] in request.POST: cfg[t_inp["target_key"]] = str( request.POST[t_inp["target_key"]]) else: cfg[t_inp["target_key"]] = "" for t_inp in target_cfg["inputs"]["input_table"]: for dut in cfg["dut_ports"]: if "dut" + str(dut["id"]) + "_" + t_inp["target_key"] \ in request.POST: dut[t_inp["target_key"]] = str( request.POST["dut" + str(dut["id"]) + "_" + t_inp["target_key"]]) elif "restrict" not in t_inp or t_inp["restrict"] == "dut": dut[t_inp["target_key"]] = "" if "default_value" in t_inp \ and dut[t_inp["target_key"]] == "": dut[t_inp["target_key"]] = t_inp["default_value"] if "ext_host_" + t_inp["target_key"] in request.POST: cfg["ext_host_" + t_inp["target_key"]] = str( request.POST["ext_host_" + t_inp["target_key"]]) elif "restrict" not in t_inp \ or t_inp["restrict"] == "ext_host": cfg["ext_host_" + t_inp["target_key"]] = "" if "default_value" in t_inp \ and ("ext_host_" + t_inp["target_key"]) in cfg \ and cfg["ext_host_" + t_inp["target_key"]] == "": cfg["ext_host_" + t_inp["target_key"]] = \ t_inp["default_value"] except Exception as e: print("EXCEPTION: " + str(e)) print(traceback.format_exc()) cfg["ext_host_real"] = str(request.POST["ext_host_real"]) try: cfg["ext_host"] = logical_ports[real_ports.index( cfg["ext_host_real"])].strip("\n") except Exception as e: print("FAILED: Finding Ext-Host Real Port: " + str(e)) # check if second,third, ... dut port should be used or not for dut in cfg["dut_ports"]: if int(dut["id"]) == 1: dut["use_port"] = "checked" else: try: if "dut_" + str(dut["id"]) + "_use_port" in request.POST: dut["use_port"] = request.POST["dut_" + str(dut["id"]) + "_use_port"] else: dut["use_port"] = "checked" except Exception: dut["use_port"] = "checked" for loadgen_grp in cfg["loadgen_groups"]: if loadgen_grp["group"] == dut["id"]: loadgen_grp["use_group"] = dut["use_port"] try: if "dut_" + str(dut["id"]) + "_outgoing_stamp" in request.POST: dut["stamp_outgoing"] = str( request.POST["dut_" + str(dut["id"]) + "_outgoing_stamp"]) else: dut["stamp_outgoing"] = "unchecked" except Exception: print(traceback.format_exc()) dut["stamp_outgoing"] = "checked" if "dut" + str(dut["id"]) + "_real" in request.POST: dut["real_port"] = str(request.POST["dut" + str(dut["id"]) + "_real"]) try: dut["p4_port"] = logical_ports[real_ports.index( dut["real_port"])].strip("\n") except Exception: dut["p4_port"] = "" else: dut["real_port"] = "" dut["p4_port"] = "" cfg["multicast"] = str(request.POST["multicast"]) cfg["stamper_ssh"] = str(request.POST["stamper_ssh"]) cfg["ext_host_ssh"] = str(request.POST["ext_host_ssh"]) cfg["ext_host_user"] = str(request.POST["ext_host_user"]) cfg["stamper_user"] = str(request.POST["stamper_user"]) cfg["ext_host_if"] = str(request.POST["ext_host_if"]) cfg["program"] = str(request.POST["program"]) cfg["forwarding_mode"] = str(request.POST["forwarding_mode"]) if "stamp_tcp" in request.POST: cfg["stamp_tcp"] = "checked" else: cfg["stamp_tcp"] = "unchecked" if "stamp_udp" in request.POST: cfg["stamp_udp"] = "checked" else: cfg["stamp_udp"] = "unchecked" # save config to file "database" print("write config") cfg = P4STA_utils.flt(cfg) P4STA_utils.write_config(cfg) print("finished config write") return True, cfg except Exception as e: print("EXCEPTION: " + str(e)) print(traceback.format_exc()) return False, cfg
def configure_page(request): if globals.core_conn.root.check_first_run(): print("FIRST RUN! Redirect to /setup_devices") return HttpResponseRedirect("/setup_devices") saved = "" target_cfg = P4STA_utils.flt(globals.core_conn.root.get_target_cfg()) if type(target_cfg) == dict and "error" in target_cfg: return render(request, "middlebox/timeout.html", { **target_cfg, **{ "inside_ajax": False } }) if request.method == "POST": saved, cfg = updateCfg(request) target_cfg = P4STA_utils.flt(globals.core_conn.root.get_target_cfg()) else: cfg = P4STA_utils.read_current_cfg() cfg["target_cfg"] = target_cfg # The following config updates are only for UI representation targets_without_selected = [] all_targets = get_all_targets() for target in all_targets: if cfg["selected_target"] != target: targets_without_selected.append(target) cfg["targets_without_selected"] = targets_without_selected cfg["all_available_targets"] = all_targets available_cfg_files = P4STA_utils.flt( globals.core_conn.root.get_available_cfg_files()) final_sorted_by_target = [] for target in sorted(all_targets): found = False final_sorted_by_target.append("###" + target) for elem in available_cfg_files: if elem.find(target) > -1: final_sorted_by_target.append(elem) found = True if not found: del final_sorted_by_target[-1] cfg["available_configs"] = final_sorted_by_target cfg["saved"] = saved loadgens_without_selected = globals.core_conn.root.get_all_loadGenerators() if cfg["selected_loadgen"] in loadgens_without_selected: loadgens_without_selected.remove(cfg["selected_loadgen"]) cfg["loadgens_without_selected"] = P4STA_utils.flt( loadgens_without_selected) exthosts_without_selected = globals.core_conn.root.get_all_extHost() if cfg["selected_extHost"] in exthosts_without_selected: exthosts_without_selected.remove(cfg["selected_extHost"]) cfg["exthosts_without_selected"] = P4STA_utils.flt( exthosts_without_selected) # if field "p4_ports" in target config, # target uses separate hardware ports & p4 ports (e.g. tofino) # now only hw (front) ports are left but relabeled as # "ports" and p4-ports are ignored # ports_list in abstract_target creates mapping 1->1 cfg["port_mapping"] = "p4_ports" in target_cfg cfg["cfg"] = cfg # needed for dynamic target input_individual return render(request, "middlebox/page_config.html", cfg)
def get_all_targets(): targets = P4STA_utils.flt(globals.core_conn.root.get_all_targets()) return targets