mirror of
https://github.com/lucky-sideburn/kubeinvaders.git
synced 2026-05-17 06:06:40 +00:00
ui improvements
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# kubeinvaders :space_invader: aka k-inv :joystick:
|
||||
# kubeinvaders (the original) :space_invader: aka k-inv :joystick:
|
||||
|
||||
**Gamified Chaos Engineering and Educational Tool for Kubernetes**
|
||||
|
||||
|
||||
@@ -220,3 +220,150 @@ body {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* ─── Sidebar enhancements ─────────────────────────────── */
|
||||
.sidebar-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 14px 15px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.12);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.sidebar a:hover {
|
||||
background-color: #771996;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* ─── Metrics table ─────────────────────────────────────── */
|
||||
.metrics-table-wrapper {
|
||||
max-width: 620px;
|
||||
margin: 14px auto 0;
|
||||
}
|
||||
|
||||
.metrics-table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
border: 1px solid #e3e3e3;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.metrics-table tbody tr:not(:last-child) td {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.metrics-table tbody tr:hover td {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.metrics-table td {
|
||||
padding: 10px 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.metrics-table-label {
|
||||
font-size: 11px;
|
||||
color: #6c757d;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.metrics-table-value {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.metrics-table-value--text {
|
||||
font-size: 14px;
|
||||
color: #6366f1;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.metrics-table-unit {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
/* Colored dot accent per row */
|
||||
.metric-dot {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.metric-dot--ns { background: #6366f1; }
|
||||
.metric-dot--deleted { background: #ef4444; }
|
||||
.metric-dot--jobs { background: #f97316; }
|
||||
.metric-dot--chaosp { background: #eab308; }
|
||||
.metric-dot--notrn { background: #f43f5e; }
|
||||
.metric-dot--delay { background: #14b8a6; }
|
||||
.metric-dot--ldelay { background: #a855f7; }
|
||||
|
||||
/* ─── Programming mode layout ───────────────────────────── */
|
||||
.prog-mode-toolbar {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 6px;
|
||||
padding: 8px 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.prog-mode-editor-panel,
|
||||
.prog-mode-flow-panel {
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.prog-mode-editor-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #282a36;
|
||||
color: #f8f8f2;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.prog-mode-editor-title {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.prog-mode-flow-title {
|
||||
background: #282a36;
|
||||
color: #f8f8f2;
|
||||
padding: 8px 12px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.prog-run-btn {
|
||||
background-color: #771996;
|
||||
border-color: #5a1270;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.prog-run-btn:hover,
|
||||
.prog-run-btn:focus {
|
||||
background-color: #5a1270;
|
||||
border-color: #440e56;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* CodeMirror fills the editor panel */
|
||||
.prog-mode-editor-panel .CodeMirror {
|
||||
border-radius: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
172
html/index.html
172
html/index.html
@@ -13,6 +13,9 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js "></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.1/dist/echarts.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/js-yaml@4.1.0/dist/js-yaml.min.js"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/codemirror@5.65.18/theme/dracula.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/codemirror@5.65.18/mode/yaml/yaml.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
@@ -180,10 +183,14 @@
|
||||
</div>
|
||||
|
||||
<div class="sidebar" id="sidebar">
|
||||
<a id="gameModeButton" onclick="saveK8sConnection(); startGameMode()">Enable Game Mode</a>
|
||||
<a id="programmingModeButton" onclick="saveK8sConnection(); startProgrammingMode()" style="font-weight: normal;">Programming Mode</a>
|
||||
<a href="#" onclick="saveK8sConnection(); showSetCurrentChaosContainer()" style="font-weight: normal;">Chaos Container Editor</a>
|
||||
<a href="#" onclick="saveK8sConnection(); showSpecialKeys()" style="font-weight: normal;">Controls and options</a>
|
||||
<div class="sidebar-brand">
|
||||
<img src="./images/kubeinvaders_spaceship.png" alt="KubeInvaders" style="width: 34px; height: auto; margin-right: 8px; image-rendering: pixelated;">
|
||||
<span style="font-size: 13px; font-weight: bold; color: #fff; letter-spacing: 0.04em;">KubeInvaders</span>
|
||||
</div>
|
||||
<a id="gameModeButton" onclick="saveK8sConnection(); startGameMode()"><i class="fas fa-gamepad me-2"></i>Enable Game Mode</a>
|
||||
<a id="programmingModeButton" onclick="saveK8sConnection(); startProgrammingMode()" style="font-weight: normal;"><i class="fas fa-code me-2"></i>Programming Mode</a>
|
||||
<a href="#" onclick="saveK8sConnection(); showSetCurrentChaosContainer()" style="font-weight: normal;"><i class="fas fa-cube me-2"></i>Chaos Container Editor</a>
|
||||
<a href="#" onclick="saveK8sConnection(); showSpecialKeys()" style="font-weight: normal;"><i class="fas fa-sliders me-2"></i>Controls and Options</a>
|
||||
</div>
|
||||
|
||||
<!-- Main content -->
|
||||
@@ -771,103 +778,67 @@ EOF</pre>
|
||||
<!-- END GAME MODE BUTTONS -->
|
||||
|
||||
<!-- START METRICS ROW -->
|
||||
<div class="row" align="center" id="metricsPresetsRow">
|
||||
<div style="margin-top: 1%;" class="text-justify" id="metricsGroup">
|
||||
<style>
|
||||
.status-label {
|
||||
color: #444242; /* Colore per le etichette */
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.status-value {
|
||||
color: #000000; /* Colore blu scuro per i valori */
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.status-unit {
|
||||
color: #6c757d; /* Colore per le unità */
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.status-container {
|
||||
margin-bottom: 8px; /* Spazio tra le righe */
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="status-container">
|
||||
<span class="status-label">Selected Namespace: </span>
|
||||
<span id="currentGameNamespace" class="status-value">NULL</span>
|
||||
<div class="row" id="metricsPresetsRow">
|
||||
<div style="margin-top: 1%; width: 100%; display: flex; flex-direction: column; align-items: center;" id="metricsGroup">
|
||||
<div class="metrics-table-wrapper">
|
||||
<table class="metrics-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="metrics-table-label"><span class="metric-dot metric-dot--ns"></span><i class="fas fa-layer-group me-2"></i>Selected Namespace</td>
|
||||
<td id="currentGameNamespace" class="metrics-table-value metrics-table-value--text">NULL</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="metrics-table-label"><span class="metric-dot metric-dot--deleted"></span><i class="fas fa-trash-can me-2"></i>Deleted Pods Total</td>
|
||||
<td id="deleted_pods_total" class="metrics-table-value">0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="metrics-table-label"><span class="metric-dot metric-dot--jobs"></span><i class="fas fa-terminal me-2"></i>Chaos Jobs Total</td>
|
||||
<td id="chaos_jobs_total" class="metrics-table-value">0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="metrics-table-label"><span class="metric-dot metric-dot--chaosp"></span><i class="fas fa-circle-dot me-2"></i>Current Chaos Pods</td>
|
||||
<td id="current_chaos_job_pod" class="metrics-table-value">0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="metrics-table-label"><span class="metric-dot metric-dot--notrn"></span><i class="fas fa-circle-xmark me-2"></i>Not Running Pods</td>
|
||||
<td id="pods_not_running_on" class="metrics-table-value">0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="metrics-table-label"><span class="metric-dot metric-dot--delay"></span><i class="fas fa-clock me-2"></i>Current Replicas Delay</td>
|
||||
<td class="metrics-table-value"><span id="fewer_replicas_seconds">0</span> <span class="metrics-table-unit">sec</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="metrics-table-label"><span class="metric-dot metric-dot--ldelay"></span><i class="fas fa-clock-rotate-left me-2"></i>Latest Replicas Delay</td>
|
||||
<td class="metrics-table-value"><span id="latest_fewer_replicas_seconds">0</span> <span class="metrics-table-unit">sec</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="status-container">
|
||||
<span class="status-label">Deleted Pods Total: </span>
|
||||
<span id="deleted_pods_total" class="status-value">0</span>
|
||||
</div>
|
||||
|
||||
<div class="status-container">
|
||||
<span class="status-label">Chaos Jobs Total: </span>
|
||||
<span id="chaos_jobs_total" class="status-value">0</span>
|
||||
</div>
|
||||
|
||||
<div class="status-container">
|
||||
<span class="status-label">Current Chaos Pods: </span>
|
||||
<span id="current_chaos_job_pod" class="status-value">0</span>
|
||||
</div>
|
||||
|
||||
<div class="status-container">
|
||||
<span class="status-label">Not Running Pods: </span>
|
||||
<span id="pods_not_running_on" class="status-value">0</span>
|
||||
</div>
|
||||
|
||||
<div class="status-container">
|
||||
<span class="status-label">Current Replicas State Delay: </span>
|
||||
<span id="fewer_replicas_seconds" class="status-value">0</span>
|
||||
<span class="status-unit">sec</span>
|
||||
</div>
|
||||
|
||||
<div class="status-container">
|
||||
<span class="status-label">Latest Replicas State Delay: </span>
|
||||
<span id="latest_fewer_replicas_seconds" class="status-value">0</span>
|
||||
<span class="status-unit">sec</span>
|
||||
</div>
|
||||
|
||||
<div id="mainChaosMetrics" style="width: 100%; height: 70%; margin-top: 16px;"></div>
|
||||
<div id="mainChaosMetrics" style="width: 100%; align-self: stretch; height: 300px; margin-top: 16px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END METRICS ROW -->
|
||||
|
||||
<!-- START CHAOS PROGRAMMING MODE SCREEN -->
|
||||
<div id="chaos-program-screen" style="display: none;">
|
||||
<div class="">
|
||||
<!-- <div class="row" style="margin-top: 2%;"> -->
|
||||
<!-- <font size="2" class="text-kinv" id="loadTestingPresetsText">Load Testing Presets & Chaos Programs</font>
|
||||
</div> -->
|
||||
<div class="row">
|
||||
<div class="btn-group" id="loadButtonGroup" role="group" aria-label="Basic example" style="overflow-x: scroll; width: 100%; padding-bottom: 2%; padding-top: 2%; scrollbar-color: dark;">
|
||||
</div>
|
||||
<div class="prog-mode-toolbar">
|
||||
<div class="btn-group" id="loadButtonGroup" role="group" aria-label="Preset buttons" style="overflow-x: auto; width: 100%; padding-bottom: 6px; padding-top: 6px; scrollbar-color: dark;">
|
||||
</div>
|
||||
<div class="btn-group" id="loadChaosProgramButtonGroup" role="group" aria-label="Saved programs" hidden style="overflow-x: auto; width: 100%; padding-bottom: 4px; padding-top: 4px; scrollbar-color: dark;">
|
||||
</div>
|
||||
<div class="row" hidden="true">
|
||||
<div class="btn-group" id="loadChaosProgramButtonGroup" role="group" aria-label="Basic example" style="overflow-x: scroll; width: 100%; padding-bottom: 2.0%; padding-top: 0.5%; scrollbar-color: dark;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 0,5%;">
|
||||
<div id="alert_placeholder_programming_mode" style="margin-top: 1%; margin-bottom: 1%;"></div>
|
||||
<div class="col">
|
||||
<div class="row" width="10px">
|
||||
<!-- <div class="col text-center">
|
||||
<button type="button" id="saveChaosProgramButton" class="btn btn-light" onclick="savePreset('save-chaos-program')">SAVE</button>
|
||||
</div> -->
|
||||
<div class="col text-center">
|
||||
<button type="button" id="runChaosProgramButton" class="btn btn-dark" onclick="runChaosProgram()">RUN</button>
|
||||
<div id="alert_placeholder_programming_mode" style="margin-top: 8px; margin-bottom: 8px;"></div>
|
||||
<div class="row g-3">
|
||||
<div class="col-lg-8">
|
||||
<div class="prog-mode-editor-panel">
|
||||
<div class="prog-mode-editor-toolbar">
|
||||
<span class="prog-mode-editor-title"><i class="fas fa-file-code me-2"></i>Chaos Program</span>
|
||||
<button type="button" id="runChaosProgramButton" class="btn btn-sm prog-run-btn" onclick="runChaosProgram()">
|
||||
<i class="fas fa-play me-1"></i>RUN
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<label for="chaosProgramTextArea"></label>
|
||||
<textarea class="form-control chaos-prog-area" id="chaosProgramTextArea" rows="50" style="min-width: 100%; font-weight: normal; font-size: small;">
|
||||
<form>
|
||||
<textarea class="form-control chaos-prog-area" id="chaosProgramTextArea" rows="50" style="min-width: 100%; font-weight: normal; font-size: small;">
|
||||
chaos-codename: CODENAME_PLACEHOLDER
|
||||
experiments:
|
||||
- name: cpu_attack_exp
|
||||
@@ -893,20 +864,23 @@ k8s_jobs:
|
||||
command: "stress-ng"
|
||||
args:
|
||||
- --version
|
||||
</textarea>
|
||||
</textarea>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col" style="margin-top: 4%; overflow-y: scroll; height:900px;">
|
||||
<div id="chaosProgramFlow">
|
||||
<div class="row"><div class="alert alert-light alert-kinv" id="exampleAlert1" role="alert" style="border-color: #000000; border-width: 1.5px;">test attack 1</div></div>
|
||||
<img src="images/down-arrow.png" width="30" height="30" style="margin-bottom: 2%;">
|
||||
<div class="row"><div class="alert alert-light alert-kinv" id="exampleAlert2" role="alert" style="border-color: #000000; border-width: 1.5px;">test attack 2</div></div>
|
||||
<div class="col-lg-4">
|
||||
<div class="prog-mode-flow-panel">
|
||||
<div class="prog-mode-flow-title"><i class="fas fa-sitemap me-2"></i>Experiment Flow</div>
|
||||
<div id="chaosProgramFlow" style="padding: 12px; overflow-y: auto; max-height: 840px;">
|
||||
<div class="row"><div class="alert alert-light alert-kinv" id="exampleAlert1" role="alert" style="border-color: #000000; border-width: 1.5px;">test attack 1</div></div>
|
||||
<img src="images/down-arrow.png" width="30" height="30" style="margin-bottom: 2%;">
|
||||
<div class="row"><div class="alert alert-light alert-kinv" id="exampleAlert2" role="alert" style="border-color: #000000; border-width: 1.5px;">test attack 2</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END CHAOS PROGRAMMING MODE SCREEN -->
|
||||
<!-- END CHAOS PROGRAMMING MODE SCREEN -->
|
||||
|
||||
<!-- START GAME MODE SCREEN -->
|
||||
<div id="game-screen" style="display: none;">
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
function startGameMode() {
|
||||
if (game_mode_switch) {
|
||||
game_mode_switch = false;
|
||||
$("#gameModeButton").text("Enable Game Mode");
|
||||
$("#gameModeButton").html('<i class="fas fa-gamepad me-2"></i>Enable Game Mode');
|
||||
} else {
|
||||
/* TO DO: DO BETTER :D */
|
||||
let checkbox = {
|
||||
@@ -32,8 +32,8 @@ function startGameMode() {
|
||||
document.getElementById("gameContainer").style.width = "100%";
|
||||
document.getElementById("gameContainer").style.height = "100%";
|
||||
//document.getElementById("loadButtonGroup").style.width = "650px";
|
||||
$("#gameModeButton").text("Disable Game Mode");
|
||||
$("#programmingModeButton").text("Enable Prog. Mode");
|
||||
$("#gameModeButton").html('<i class="fas fa-gamepad me-2"></i>Disable Game Mode');
|
||||
$("#programmingModeButton").html('<i class="fas fa-code me-2"></i>Programming Mode');
|
||||
programming_mode_switch = false;
|
||||
}
|
||||
if (game_buttons.style.display === "none") {
|
||||
@@ -90,10 +90,15 @@ function startProgrammingMode() {
|
||||
|
||||
if (editor == null) {
|
||||
editor = CodeMirror.fromTextArea(chaosProgramTextArea, {
|
||||
lineNumbers: true,
|
||||
lineNumbers: true,
|
||||
theme: "dracula",
|
||||
mode: "javascript"
|
||||
mode: "yaml",
|
||||
indentUnit: 2,
|
||||
tabSize: 2,
|
||||
indentWithTabs: false,
|
||||
lineWrapping: false,
|
||||
extraKeys: { "Tab": "indentMore", "Shift-Tab": "indentLess" }
|
||||
});
|
||||
editor.setSize("100%", "100%");
|
||||
editor.setSize("100%", "820px");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user