commit
fa4d417bf7
7 changed files with 190 additions and 0 deletions
@ -0,0 +1,3 @@
|
||||
# Recycled Cloud Status Page |
||||
|
||||
Simple status page for the Recycled Cloud Infrastructure. |
File diff suppressed because one or more lines are too long
@ -0,0 +1,8 @@
|
||||
/*! |
||||
* Bootstrap Reboot v4.5.3 (https://getbootstrap.com/) |
||||
* Copyright 2011-2020 The Bootstrap Authors |
||||
* Copyright 2011-2020 Twitter, Inc. |
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) |
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) |
||||
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} |
||||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */ |
@ -0,0 +1,39 @@
|
||||
body { |
||||
width: 400px; |
||||
margin: auto !important; |
||||
} |
||||
|
||||
#header { |
||||
text-align: center; |
||||
margin-top: 20px; |
||||
} |
||||
|
||||
#header #logo { |
||||
width: 150px; |
||||
margin: 5px; |
||||
} |
||||
|
||||
.location { |
||||
text-align: center; |
||||
} |
||||
|
||||
.location h3 { |
||||
font-size: 1em; |
||||
} |
||||
|
||||
.location ul { |
||||
list-style: none; |
||||
padding: 0; |
||||
} |
||||
|
||||
.up { |
||||
color: green; |
||||
} |
||||
|
||||
.down { |
||||
color: red; |
||||
} |
||||
|
||||
.unknown { |
||||
color: orange; |
||||
} |
@ -0,0 +1,131 @@
|
||||
#!/bin/sh |
||||
|
||||
TITLE="Recycled Cloud Status" |
||||
LOCATIONS="lnth.ch lsne.ch fvil.ch" |
||||
EXTERNAL_PROMETHEUS_ADDR=http://localhost:9090 |
||||
|
||||
query () { |
||||
endpoint="$1/api/v1/query" |
||||
query=$2 |
||||
|
||||
curl "$endpoint" --data-urlencode "query=$query" | jq --raw-output .data.result[].value[1] |
||||
} |
||||
|
||||
get_state () { |
||||
case "$1" in |
||||
0) |
||||
echo "down" |
||||
;; |
||||
1) |
||||
echo "up" |
||||
;; |
||||
*) |
||||
echo "unknown" |
||||
;; |
||||
esac |
||||
} |
||||
|
||||
get_canary_state () { |
||||
location=$1 |
||||
inet=$2 |
||||
|
||||
instance="canary.$location.recycled.cloud" |
||||
job="blackbox-external-v$inet" |
||||
result=$(query $EXTERNAL_PROMETHEUS_ADDR \ |
||||
"probe_success{instance=\"$instance\", job=\"$job\"}") |
||||
|
||||
get_state "$result" |
||||
} |
||||
|
||||
get_edge_state () { |
||||
location=$1 |
||||
edge=$2 |
||||
|
||||
instance="edge$edge-$(echo "$location" | cut -d. -f1).transfer.recycled.cloud" |
||||
result=$(query $EXTERNAL_PROMETHEUS_ADDR \ |
||||
"probe_success{instance=\"$instance\"}") |
||||
|
||||
get_state "$result" |
||||
} |
||||
|
||||
cat << EOF |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="utf-8"/> |
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> |
||||
<title>${TITLE:?}</title> |
||||
<link rel="stylesheet" href="assets/main.css"> |
||||
<link rel="stylesheet" href="assets/bootstrap-reboot.min.css"> |
||||
<link rel="stylesheet" href="assets/bootstrap-grid.min.css"> |
||||
</head> |
||||
<body> |
||||
<div id="header"> |
||||
<img src="assets/cloud.svg" id="logo" /> |
||||
<h1>${TITLE:?}</h1> |
||||
<p>This page reports the status of the <a |
||||
href="https://recycled.cloud">Recycled Cloud</a> infrastructure, |
||||
regenerated every minute. |
||||
</p> |
||||
<p> |
||||
States: |
||||
<span class="up">up</span> |
||||
<span class="down">down</span> |
||||
<span class="unknown">unknown</span> |
||||
</p> |
||||
<p> |
||||
Last refresh on <b>$(date)</b>. |
||||
</p> |
||||
</div> |
||||
EOF |
||||
|
||||
for location in $LOCATIONS; do |
||||
canary_v6=$(get_canary_state "$location" 6) |
||||
canary_v4=$(get_canary_state "$location" 4) |
||||
|
||||
edge1_transfer=$(get_edge_state "$location" 1) |
||||
edge2_transfer=$(get_edge_state "$location" 2) |
||||
|
||||
cat <<- EOF |
||||
<div class="location"> |
||||
<hr /> |
||||
<h2>$location</h2> |
||||
|
||||
<div class="row"> |
||||
<div class="col-6"> |
||||
<h3>Routers</h3> |
||||
<ul> |
||||
<li>edge1 <span class="$edge1_transfer">$edge1_transfer</span></li> |
||||
<li>edge2 <span class="$edge2_transfer">$edge2_transfer</span></li> |
||||
</ul> |
||||
</div> |
||||
<div class="col-6"> |
||||
<h3>Canary VM</h3> |
||||
<ul> |
||||
<li>IPv6 <span class="$canary_v6">$canary_v6</span></li> |
||||
<li>IPv4 <span class="$canary_v4">$canary_v4</span></li> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- not implemented yet |
||||
<h3>Capacity</h3> |
||||
|
||||
<div class="row"> |
||||
<div class="col-6"> |
||||
<p>Used RAM: X / XX GB</p> |
||||
</div> |
||||
<div class="col-6"> |
||||
<p>Used Storage: X / XX GB</p> |
||||
</div> |
||||
</div> |
||||
--> |
||||
</div> |
||||
EOF |
||||
done |
||||
|
||||
cat << EOF |
||||
</body> |
||||
</html> |
||||
EOF |
Loading…
Reference in new issue