function replaceDivWithContent(divId, content) { document.getElementById(divId).innerHTML = content; } function getChaosProgTextAreaValue() { return editor.getValue(); } /* Programming Mode Functions */ function IsJsonString(str) { try { JSON.parse(str); } catch (e) { return false; } return true; } /* TODO: this is very bad... change asap :D */ loadPresetsCodeJson = `{ "SSH": "aW1wb3J0IHBhcmFtaWtvCgojIERlZmluZSBzZXJ2ZXJzIGFycmF5CnNlcnZlcnMgPSBbJ3NlcnZlcjEnLCAnc2VydmVyMicsICdzZXJ2ZXIzJ10KCmZvciBzZXJ2ZXIgaW4gc2VydmVyczoKICAgIHB1YmxpY19rZXkgPSBwYXJhbWlrby5SU0FLZXkoZGF0YT1iJ3lvdXItcHVibGljLWtleS1zdHJpbmcnKQogICAgc3NoID0gcGFyYW1pa28uU1NIQ2xpZW50KCkKICAgIHNzaC5zZXRfbWlzc2luZ19ob3N0X2tleV9wb2xpY3kocGFyYW1pa28uQXV0b0FkZFBvbGljeSgpKQogICAgc3NoLmNvbm5lY3QoaG9zdG5hbWU9J3lvdXItc2VydmVyLW5hbWUnLCB1c2VybmFtZT0neW91ci11c2VybmFtZScsIHBrZXk9cHVibGljX2tleSkKICAgIHN0ZGluLCBzdGRvdXQsIHN0ZGVyciA9IHNzaC5leGVjX2NvbW1hbmQoJ3lvdXItY29tbWFuZCcpCiAgICBwcmludChzdGRvdXQucmVhZCgpKQogICAgc3NoLmNsb3NlKCkK" }`; function loadPreset(tool, lang) { let decodedStringAtoB = ""; console.log("[GET-PRESETS] Loaded preset for " + tool + " with lang " + lang); latest_preset_name = tool; latest_preset_lang = lang; console.log("[GET-PRESETS] |" + lang + "|"); if (lang == "k-inv") { loadSavedPreset(tool, lang, $('#chaosProgramTextArea').text()); if (tool.toLowerCase() == "default") { document.getElementById("resetToDefaultButton").style.display = "none"; document.getElementById("deleteChaosProgramButton").style.display = "none"; } else { document.getElementById("resetToDefaultButton").style.display = "none"; document.getElementById("deleteChaosProgramButton").style.display = "block"; } } else { console.log("[GET-PRESETS] foo Loaded preset for " + tool + " with lang " + lang); console.log("[GET-PRESET] loadPresetsCodeJson " +loadPresetsCodeJson); loadPresetsCodeParsed = JSON.parse(loadPresetsCodeJson); decodedStringAtoB = atob(loadPresetsCodeParsed[tool]); loadSavedPreset(tool, lang, decodedStringAtoB); document.getElementById("resetToDefaultButton").style.display = "block"; document.getElementById("deleteChaosProgramButton").style.display = "none"; } $("#presetLang").val(lang); $("#presetName").val(tool); $('#setLoadTestModal').modal('show'); modal_opened = true; log_tail_switch = false; log_tail_div.style.display = "none"; log_tail_screen.style.display = "none" $("#logConsoleButton").text("Start Logs Tail"); if (programming_mode_switch == false) { startProgrammingMode(); } } function runChaosProgram() { chaosProgram = getChaosProgTextAreaValue(); const regex = /^chaos-codename:\s+(.*)$/m; const match = chaosProgram.match(regex); if (match) { codename = match[1]; console.log(codename); } else { console.log("Valore chaos-codename non trovato"); } var oReq = new XMLHttpRequest(); oReq.open("POST", k8s_url + "/kube/chaos/programming_mode?id=" + random_code, true); oReq.onreadystatechange = function () { if (this.readyState === XMLHttpRequest.DONE && this.status == 200) { //console.log("[PROGRAMMING_MODE] Chaos program loaded... HTTP Status code: " + this.status); now = new Date().toLocaleString().replace(',','') if (this.responseText.includes("Invalid")) { replaceDivWithContent('alert_placeholder_programming_mode', alert_div + this.responseText + ' '); chaos_program_valid = false; } else { // console.log("[PROGRAMMING_MODE] Write new status update of the latest loaded chaos program"); replaceDivWithContent('alert_placeholder_programming_mode', alert_div + '[PROGRAMMING_MODE] Chaos program ' + codename + ' loaded at ' + now + ' '); chaos_program_valid = true; } } else if (this.readyState === XMLHttpRequest.DONE && this.status != 200) { replaceDivWithContent('alert_placeholder_programming_mode', alert_div + "[PROGRAMMING_MODE] Invalid chaos program code, please check yaml syntax or kubeinvaders logs"); // console.log("[PROGRAMMING_MODE] Error. HTTP return code: " + this.status); } };; oReq.setRequestHeader("Content-Type", "application/json"); console.log("Sending this program: " + getChaosProgTextAreaValue()); oReq.send(getChaosProgTextAreaValue()); } function savePreset(action) { console.log("[SAVE-PRESET-CHAOSPROGRAM] Saving item..."); var presetName = ""; presetBody = $("#currentLoadTest").val(); console.log("[SAVE-PRESET-CHAOSPROGRAM] Saving " + presetBody); if (action == "save-chaos-program") { presetLang = "k-inv"; presetName = codename + "-" + rand_id(); latest_preset_lang = "k-inv"; console.log("[SAVE-PRESET-CHAOSPROGRAM] lang: " + presetLang + " name:" + presetName); presetBody = $('#chaosProgramTextArea').text(); document.getElementById("resetToDefaultButton").style.display = "none"; document.getElementById("deleteChaosProgramButton").style.display = "block"; } else if (latest_preset_lang == "k-inv") { presetLang = "k-inv"; presetName = codename; latest_preset_lang = "k-inv"; console.log("[SAVE-PRESET-CHAOSPROGRAM] lang: " + presetLang + " name:" + codename); presetBody = $('#currentLoadTest').val(); document.getElementById("resetToDefaultButton").style.display = "none"; document.getElementById("deleteChaosProgramButton").style.display = "block"; } else { presetLang = latest_preset_lang; presetName = latest_preset_name; document.getElementById("resetToDefaultButton").style.display = "block"; document.getElementById("deleteChaosProgramButton").style.display = "none"; } //console.log("Saving preset. name:" + presetName + ", lang:" + presetName + ", body: " + presetBody); var oReq = new XMLHttpRequest(); oReq.open("POST", k8s_url + "/chaos/loadpreset/save?name=" + presetName + "&lang=" + presetLang, true); oReq.onreadystatechange = function () { if (this.readyState === XMLHttpRequest.DONE && this.status === 200 && (action == "apply" || action == "save-chaos-program")) { if (latest_preset_lang == "k-inv") { if ($('#currentLoadTest').val() != "") { presetBody = $('#currentLoadTest').val(); } //document.getElementById("chaosProgramTextArea").text = presetBody; } else { presetBody = $('#chaosProgramTextArea').text(`chaos-codename: ${codename} jobs: ${presetName}-job: additional-labels: chaos-controller: kubeinvaders chaos-lang: ${presetLang} chaos-type: loadtest chaos-codename: ${codename} image: docker.io/luckysideburn/chaos-exec:v1.0.4 command: bash args: - start.sh - ${presetLang} - code=${btoa(presetBody).trim()} experiments: - name: ${presetName}-exp job: ${presetName}-job loop: 5`); } } };; oReq.setRequestHeader("Content-Type", "application/json"); oReq.send(presetBody); closeSetLoadTestModal(); if (action != "save-chaos-program") { let presetNameCapitalized = presetName.charAt(0).toUpperCase() + presetName.slice(1); var buttonId = "load" + presetNameCapitalized.trim(); // document.getElementById(buttonId).classList.remove('btn-light'); // document.getElementById(buttonId).classList.add('btn-light-saved'); } else { console.log("[SAVE-PRESET-CHAOSPROGRAM] Creating new button for lang: " + presetLang + " name:" + presetName); createChaosProgramButton(presetName, 'k-inv'); } getSavedPresets(); if (action == "apply" && programming_mode_switch == false){ startProgrammingMode(); } } function drawChaosProgramFlow() { //var chaosProgram = ""; chaosProgram = getChaosProgTextAreaValue(); var oReq = new XMLHttpRequest(); oReq.open("POST", k8s_url + "/chaos/programs/json-flow", true); oReq.onreadystatechange = function () { if (this.readyState === XMLHttpRequest.DONE && this.status === 200) { if (IsJsonString(this.responseText)){ if (this.responseText.includes("Invalid")) { $('#alert_placeholder_programming_mode').replaceWith(alert_div + this.responseText + ' '); chaos_program_valid = false; return; } var flow = JSON.parse(this.responseText); // console.log("[DRAW-PROGRAM-FLOW] Drawing flow for " + codename); // console.log("[DRAW-PROGRAM-FLOW] Drawing: " + JSON.stringify(flow)); var flow_html = ""; let i = 0; var times = ""; $('#chaosProgramFlow').html(""); while (i < flow["experiments"].length) { if (flow["experiments"][i]["loop"] == 1){ times = "once"; } else if (flow["experiments"][i]["loop"] == 2) { times = "twice" } else { times = flow["experiments"][i]["loop"] + " times" } if (current_color_mode == "light") { flow_html = flow_html + '