mirror of
https://github.com/FairwindsOps/polaris.git
synced 2026-05-21 08:33:55 +00:00
Merge pull request #58 from reactiveops/rs/dashboard-cleanup
Dashboard cleanup
This commit is contained in:
@@ -1,3 +1,17 @@
|
||||
// Copyright 2019 ReactiveOps
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package dashboard
|
||||
|
||||
import (
|
||||
@@ -44,22 +58,13 @@ func MainHandler(w http.ResponseWriter, r *http.Request, c conf.Configuration, k
|
||||
JSON: template.JS(jsonData),
|
||||
}
|
||||
tmpl, err := template.New(TemplateName).Funcs(template.FuncMap{
|
||||
"getWarningWidth": func(rs validator.ResultSummary, fullWidth int) uint {
|
||||
return uint(float64(rs.Successes+rs.Warnings) / float64(rs.Successes+rs.Warnings+rs.Errors) * float64(fullWidth))
|
||||
},
|
||||
"getSuccessWidth": func(rs validator.ResultSummary, fullWidth int) uint {
|
||||
return uint(float64(rs.Successes) / float64(rs.Successes+rs.Warnings+rs.Errors) * float64(fullWidth))
|
||||
},
|
||||
"getIcon": func(rm validator.ResultMessage) string {
|
||||
switch rm.Type {
|
||||
case "success":
|
||||
return "fas fa-check"
|
||||
case "warning":
|
||||
return "fas fa-exclamation"
|
||||
default:
|
||||
return "fas fa-times"
|
||||
}
|
||||
},
|
||||
"getWarningWidth": getWarningWidth,
|
||||
"getSuccessWidth": getSuccessWidth,
|
||||
"getWeatherIcon": getWeatherIcon,
|
||||
"getWeatherText": getWeatherText,
|
||||
"getGrade": getGrade,
|
||||
"getScore": getScore,
|
||||
"getIcon": getIcon,
|
||||
}).ParseFiles(TemplateFile)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
|
||||
104
pkg/dashboard/helpers.go
Normal file
104
pkg/dashboard/helpers.go
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright 2019 ReactiveOps
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package dashboard
|
||||
|
||||
import (
|
||||
"github.com/reactiveops/fairwinds/pkg/validator"
|
||||
)
|
||||
|
||||
func getWarningWidth(rs validator.ResultSummary, fullWidth int) uint {
|
||||
return uint(float64(rs.Successes+rs.Warnings) / float64(rs.Successes+rs.Warnings+rs.Errors) * float64(fullWidth))
|
||||
}
|
||||
|
||||
func getSuccessWidth(rs validator.ResultSummary, fullWidth int) uint {
|
||||
return uint(float64(rs.Successes) / float64(rs.Successes+rs.Warnings+rs.Errors) * float64(fullWidth))
|
||||
}
|
||||
|
||||
func getGrade(rs validator.ResultSummary) string {
|
||||
score := getScore(rs)
|
||||
if score >= 97 {
|
||||
return "A+"
|
||||
} else if score >= 93 {
|
||||
return "A"
|
||||
} else if score >= 90 {
|
||||
return "A-"
|
||||
} else if score >= 87 {
|
||||
return "B+"
|
||||
} else if score >= 83 {
|
||||
return "B"
|
||||
} else if score >= 80 {
|
||||
return "B-"
|
||||
} else if score >= 77 {
|
||||
return "C+"
|
||||
} else if score >= 73 {
|
||||
return "C"
|
||||
} else if score >= 70 {
|
||||
return "C-"
|
||||
} else if score >= 67 {
|
||||
return "D+"
|
||||
} else if score >= 63 {
|
||||
return "D"
|
||||
} else if score >= 60 {
|
||||
return "D-"
|
||||
} else {
|
||||
return "F"
|
||||
}
|
||||
}
|
||||
|
||||
func getScore(rs validator.ResultSummary) uint {
|
||||
total := (rs.Successes * 2) + rs.Warnings + (rs.Errors * 2)
|
||||
return uint((float64(rs.Successes*2) / float64(total)) * 100)
|
||||
}
|
||||
|
||||
func getWeatherIcon(rs validator.ResultSummary) string {
|
||||
score := getScore(rs)
|
||||
if score >= 90 {
|
||||
return "fa-sun"
|
||||
} else if score >= 80 {
|
||||
return "fa-cloud-sun"
|
||||
} else if score >= 70 {
|
||||
return "fa-cloud"
|
||||
} else if score >= 60 {
|
||||
return "fa-cloud-rain"
|
||||
} else {
|
||||
return "fa-cloud-showers-heavy"
|
||||
}
|
||||
}
|
||||
|
||||
func getWeatherText(rs validator.ResultSummary) string {
|
||||
score := getScore(rs)
|
||||
if score >= 90 {
|
||||
return "Smooth sailing"
|
||||
} else if score >= 80 {
|
||||
return "Mostly smooth sailing"
|
||||
} else if score >= 70 {
|
||||
return "Smooth sailing within sight"
|
||||
} else if score >= 60 {
|
||||
return "A little stormy"
|
||||
} else {
|
||||
return "Storms ahead, be careful"
|
||||
}
|
||||
}
|
||||
|
||||
func getIcon(rm validator.ResultMessage) string {
|
||||
switch rm.Type {
|
||||
case "success":
|
||||
return "fas fa-check"
|
||||
case "warning":
|
||||
return "fas fa-exclamation"
|
||||
default:
|
||||
return "fas fa-times"
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="https://fonts.googleapis.com/css?family=Lobster" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css?family=Muli:300,400,700" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/static/css/normalize.css">
|
||||
<link rel="stylesheet" href="/static/css/main.css">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
|
||||
@@ -27,8 +27,8 @@
|
||||
<div class="header-content">
|
||||
<img class="logo" src="/static/images/logo.png" alt="Fairwinds" />
|
||||
<div class="header-right">
|
||||
<a href="https://reactiveops.com?source=fairwinds">
|
||||
<span class="by-text">by</span>
|
||||
<a href="https://reactiveops.com?source=fairwinds" target="_blank">
|
||||
<span class="oss-text">Open Source Project By</span>
|
||||
<img class="ro-logo" src="/static/images/ro-logo.png" alt="ReactiveOps" />
|
||||
</a>
|
||||
</div>
|
||||
@@ -36,16 +36,22 @@
|
||||
</div>
|
||||
|
||||
<div class="dashboard-content">
|
||||
<div class="charts">
|
||||
<div class="cluster-score chart-section">
|
||||
<h3>Overall Score:</h3>
|
||||
<div style="width:510px; height: 400px; left: -100px; position: relative;">
|
||||
<canvas id="clusterScoreChart"></canvas>
|
||||
<div class="namespace">
|
||||
<h3>Cluster Overview</h3>
|
||||
<div class="cluster-overview">
|
||||
<div class="cluster-score">
|
||||
<div class="weather"><i class="fas {{ getWeatherIcon .AuditData.ClusterSummary }}"></i></div>
|
||||
<div class="sailing">{{ getWeatherText .AuditData.ClusterSummary }}</div>
|
||||
<div class="scores">Grade: <strong>{{ getGrade .AuditData.ClusterSummary }}</strong> | Score: <strong>{{ getScore .AuditData.ClusterSummary }}%</strong></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="namespace-score chart-section">
|
||||
<h3>Scores By Namespace:</h3>
|
||||
<canvas id="namespaceScoreChart"></canvas>
|
||||
<div class="result-messages">
|
||||
<ul>
|
||||
<li class="success"><i class="fas fa-check"></i> {{ .AuditData.ClusterSummary.Successes }} checks passed</li>
|
||||
<li class="warning"><i class="fas fa-exclamation"></i> {{ .AuditData.ClusterSummary.Warnings }} checks had warnings</li>
|
||||
<li class="error"><i class="fas fa-times"></i> {{ .AuditData.ClusterSummary.Errors }} checks had errors</li>
|
||||
</ul>
|
||||
</div>
|
||||
<canvas id="clusterScoreChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -59,7 +65,7 @@
|
||||
<div class="name"><span class="caret-expander"></span>{{ .Type }}: <strong>{{ .Name }}</strong></div>
|
||||
|
||||
{{ range .PodResults}}
|
||||
<div class="extra">
|
||||
<div class="result-messages">
|
||||
<h4>Pod Spec:</h4>
|
||||
<ul>
|
||||
{{ range $message := .Messages}}
|
||||
@@ -68,7 +74,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
{{ range .ContainerResults}}
|
||||
<div class="extra">
|
||||
<div class="result-messages">
|
||||
<h4>Container: {{ .Name }}</h4>
|
||||
<ul>
|
||||
{{ range $message := .Messages}}
|
||||
@@ -96,7 +102,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
© 2019, <a href="https://reactiveops.com?source=fairwinds">ReactiveOps Inc.</a>
|
||||
<a href="https://reactiveops.com?source=fairwinds" target="_blank">©2019 ReactiveOps Inc.</a>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/charts.js">
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
|
||||
background: #eee;
|
||||
font-family: 'Muli', 'Helvetica', 'Arial', sans-serif;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: #fff;
|
||||
padding: 10px 20px;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
|
||||
padding: 20px 20px 0;
|
||||
}
|
||||
|
||||
.header .header-content {
|
||||
@@ -23,12 +21,11 @@ body {
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
.header span.by-text {
|
||||
font-family: 'Lobster', sans-serif;
|
||||
.header span.oss-text {
|
||||
color: #23103A;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
margin-top: 4px;
|
||||
display: block;
|
||||
font-size: 11px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.header a {
|
||||
@@ -36,7 +33,7 @@ body {
|
||||
}
|
||||
|
||||
.header .ro-logo {
|
||||
height: 64px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.dashboard-content {
|
||||
@@ -45,70 +42,79 @@ body {
|
||||
}
|
||||
|
||||
.charts {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.chart-section {
|
||||
float: left;
|
||||
margin: 20px;
|
||||
padding: 30px;
|
||||
width: 300px;
|
||||
height: 320px;
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.chart-section.namespace-score {
|
||||
margin-left: 0px;
|
||||
width: 480px;
|
||||
}
|
||||
|
||||
.chart-section h3 {
|
||||
margin: 0 0 15px;
|
||||
padding: 0 0 15px;
|
||||
font-weight: 300;
|
||||
font-size: 30px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#clusterScoreChart {
|
||||
width: 260px;
|
||||
height: 260px;
|
||||
}
|
||||
|
||||
#namespaceScoreChart {
|
||||
width: 520px;
|
||||
height: 260px;
|
||||
height: 405px;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
margin: 20px;
|
||||
margin: 25px 20px;
|
||||
padding: 10px 20px;
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.namespace h3 {
|
||||
margin: 0;
|
||||
font-weight: 300;
|
||||
font-size: 30px;
|
||||
padding: 20px;
|
||||
font-size: 28px;
|
||||
padding: 15px 20px 20px;
|
||||
}
|
||||
|
||||
.namespace h3 strong {
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.cluster-score .status {
|
||||
width: 400px;
|
||||
height: 30px;
|
||||
margin: 30px auto;
|
||||
.namespace .cluster-overview {
|
||||
height: 240px;
|
||||
}
|
||||
|
||||
.namespace .cluster-overview .cluster-score {
|
||||
width: 200px;
|
||||
display: inline-block;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.namespace .cluster-overview .cluster-score .weather {
|
||||
font-size: 110px;
|
||||
font-weight: bold;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.namespace .cluster-overview .cluster-score .sailing-message {
|
||||
font-size: 16px;
|
||||
line-height: 28px;
|
||||
margin-left: 7px;
|
||||
font-weight: 300;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.namespace .cluster-overview .cluster-score .scores {
|
||||
font-size: 16px;
|
||||
margin-top: 10px;}
|
||||
|
||||
#clusterScoreChart {
|
||||
width: 550px;
|
||||
position: relative;
|
||||
top: -254px;
|
||||
left: 120px;
|
||||
}
|
||||
|
||||
.namespace .cluster-overview .result-messages {
|
||||
margin: 0 20px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
left: -100px;
|
||||
top: -52px;
|
||||
}
|
||||
|
||||
.namespace .cluster-overview .result-messages ul {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
left: 400px;
|
||||
font-size: 20px;
|
||||
line-height: 35px;
|
||||
}
|
||||
|
||||
.namespace-content {
|
||||
@@ -128,11 +134,11 @@ body {
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
.namespace-content .resource-info .name {
|
||||
.namespace .resource-info .name {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.namespace-content .resource-info .caret-expander {
|
||||
.namespace .resource-info .caret-expander {
|
||||
display: inline-block;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
@@ -143,27 +149,27 @@ body {
|
||||
background-position: 2px center;
|
||||
}
|
||||
|
||||
.namespace-content .resource-info.expanded .caret-expander {
|
||||
.namespace .resource-info.expanded .caret-expander {
|
||||
background-image: url('../images/caret-bottom.svg');
|
||||
background-position: center 2px;
|
||||
}
|
||||
|
||||
.namespace-content .resource-info .extra {
|
||||
.namespace .resource-info .result-messages {
|
||||
display: none;
|
||||
color: #6a6a6a;
|
||||
}
|
||||
|
||||
.namespace-content .resource-info.expanded .extra {
|
||||
.namespace .resource-info.expanded .result-messages {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.namespace-content .extra h4 {
|
||||
.namespace .result-messages h4 {
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
margin: 15px 25px 6px;
|
||||
}
|
||||
|
||||
.namespace-content .extra ul {
|
||||
.namespace .result-messages ul {
|
||||
list-style-type: none;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
@@ -172,11 +178,11 @@ body {
|
||||
color: #6a6a6a;
|
||||
}
|
||||
|
||||
.namespace-content .extra ul li {
|
||||
.namespace .result-messages ul li {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.namespace-content .extra i {
|
||||
.namespace .result-messages i {
|
||||
display: inline-block;
|
||||
margin-right: 7px;
|
||||
text-align: center;
|
||||
@@ -187,60 +193,65 @@ body {
|
||||
bottom: -3px;
|
||||
}
|
||||
|
||||
.namespace-content .extra .success i {
|
||||
.namespace .result-messages .success i {
|
||||
color: #8BD2DC;
|
||||
}
|
||||
|
||||
.namespace-content .extra .warning i {
|
||||
.namespace .result-messages .warning i {
|
||||
color: #f26c21;
|
||||
}
|
||||
|
||||
.namespace-content .extra .error i {
|
||||
.namespace .result-messages .error i {
|
||||
color: #a11f4c;
|
||||
}
|
||||
|
||||
.namespace-content td.status-bar {
|
||||
.namespace td.status-bar {
|
||||
vertical-align: top;
|
||||
padding-top: 18px;
|
||||
}
|
||||
|
||||
.namespace-content .status {
|
||||
.namespace .status {
|
||||
float: right;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.namespace-content .status div {
|
||||
.namespace .status div {
|
||||
height: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.namespace-content .status .passing {
|
||||
.namespace .status .passing {
|
||||
background-color: #8BD2DC;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.namespace-content .status .warning {
|
||||
.namespace .status .warning {
|
||||
background-color: #f26c21;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.namespace .status .failing {
|
||||
background-color: #a11f4c;
|
||||
width: 200px;
|
||||
animation: fadeIn 2s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
0% {opacity: 0;}
|
||||
100% {opacity: 1;}
|
||||
}
|
||||
|
||||
.namespace-content .status .failing {
|
||||
background-color: #a11f4c;
|
||||
width: 200px;
|
||||
animation: fadeIn 2s;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
.footer, .footer a {
|
||||
.footer a {
|
||||
color: #999;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.footer a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
|
||||
<path d="M4 0c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm2 1.78l.72.72-3.22 3.22-1.72-1.72.72-.72 1 1 2.5-2.5z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 213 B |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
|
||||
<path d="M4 0c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm-1.5 1.78l1.5 1.5 1.5-1.5.72.72-1.5 1.5 1.5 1.5-.72.72-1.5-1.5-1.5 1.5-.72-.72 1.5-1.5-1.5-1.5.72-.72z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 262 B |
Binary file not shown.
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 15 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
|
||||
<path d="M3.09 0c-.06 0-.1.04-.13.09l-2.94 6.81c-.02.05-.03.13-.03.19v.81c0 .05.04.09.09.09h6.81c.05 0 .09-.04.09-.09v-.81c0-.05-.01-.14-.03-.19l-2.94-6.81c-.02-.05-.07-.09-.13-.09h-.81zm-.09 3h1v2h-1v-2zm0 3h1v1h-1v-1z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 312 B |
@@ -1,195 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Fairwinds</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="https://fonts.googleapis.com/css?family=Lobster" rel="stylesheet">
|
||||
<link rel="stylesheet" href="css/normalize.css">
|
||||
<link rel="stylesheet" href="css/main.css">
|
||||
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>
|
||||
<img class="logo" src="images/logo.png" alt="Fairwinds" />
|
||||
<span class="alt-logo">Fairwinds</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-content">
|
||||
<div class="charts">
|
||||
<div class="cluster-score chart-section">
|
||||
<h3>Overall Score:</h3>
|
||||
<div style="width:510px; height: 400px; left: -100px; position: relative;">
|
||||
<canvas id="clusterScoreChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="namespace-score chart-section">
|
||||
<h3>Scores By Namespace:</h3>
|
||||
<canvas id="namespaceScoreChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="namespace">
|
||||
<h3>Namespace: <strong>kube-system</strong></h3>
|
||||
|
||||
<table class="namespace-content" cellspacing="0">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="name"><span class="caret-expander"></span>DaemonSet: <strong>datadog-agent</strong></div>
|
||||
</td>
|
||||
<td class="status-bar">
|
||||
<div class="status">
|
||||
<div class="failing">
|
||||
<div class="warning" style="width: 124px;">
|
||||
<div class="passing" style="width: 82px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="name"><span class="caret-expander expanded"></span>Deployment: <strong>tiller-deployment</strong></div>
|
||||
<ul class="extra">
|
||||
<li class="success"><span>☑</span> Image Tag Specified</li>
|
||||
<li class="success"><span>☑</span> Resource Limits</li>
|
||||
<li class="success"><span>☑</span> Resource Requests</li>
|
||||
<li class="warning"><span>⚠</span> Run As Non Root User</li>
|
||||
<li class="failure"><span>☒</span> Liveness Probe</li>
|
||||
<li class="failure"><span>☒</span> Readiness Probe</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="status-bar">
|
||||
<div class="status">
|
||||
<div class="failing">
|
||||
<div class="warning" style="width: 150px;">
|
||||
<div class="passing" style="width: 106px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.onload = function renderCharts() {
|
||||
Chart.pluginService.register({
|
||||
beforeDraw: function (chart) {
|
||||
if (chart.config.options.elements.center) {
|
||||
//Get ctx from string
|
||||
var ctx = chart.chart.ctx;
|
||||
|
||||
//Get options from the center object in options
|
||||
var centerConfig = chart.config.options.elements.center;
|
||||
var fontStyle = centerConfig.fontStyle || 'Arial';
|
||||
var txt = centerConfig.text;
|
||||
var color = centerConfig.color || '#000';
|
||||
var sidePadding = centerConfig.sidePadding || 20;
|
||||
var sidePaddingCalculated = (sidePadding / 100) * (chart.innerRadius * 2)
|
||||
//Start with a base font of 30px
|
||||
ctx.font = "30px " + fontStyle;
|
||||
|
||||
//Get the width of the string and also the width of the element minus 10 to give it 5px side padding
|
||||
var stringWidth = ctx.measureText(txt).width;
|
||||
var elementWidth = (chart.innerRadius * 2) - sidePaddingCalculated;
|
||||
|
||||
// Find out how much the font can grow in width.
|
||||
var widthRatio = elementWidth / stringWidth;
|
||||
var newFontSize = Math.floor(30 * widthRatio);
|
||||
var elementHeight = (chart.innerRadius * 2);
|
||||
|
||||
// Pick a new font size so it will not be larger than the height of label.
|
||||
var fontSizeToUse = Math.min(newFontSize, elementHeight);
|
||||
|
||||
//Set font settings to draw it correctly.
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
var centerX = ((chart.chartArea.left + chart.chartArea.right) / 2);
|
||||
var centerY = ((chart.chartArea.top + chart.chartArea.bottom) / 2);
|
||||
ctx.font = "bold " + fontSizeToUse + "px " + fontStyle;
|
||||
ctx.fillStyle = color;
|
||||
|
||||
//Draw text in center
|
||||
ctx.fillText(txt, centerX, centerY);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
var namespaceChart = new Chart("namespaceScoreChart", {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: ["kube-system", "development", "staging", "infra", "default"],
|
||||
datasets: [{
|
||||
label: 'Passing',
|
||||
data: [118, 78, 65, 56, 43],
|
||||
backgroundColor: '#230f39',
|
||||
}, {
|
||||
label: 'Warning',
|
||||
data: [85, 54, 28, 23, 21],
|
||||
backgroundColor: '#f26c21',
|
||||
}, {
|
||||
label: 'Failing',
|
||||
data: [38, 24, 18, 15, 12],
|
||||
backgroundColor: '#a11f4c',
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{
|
||||
stacked: true,
|
||||
}],
|
||||
yAxes: [{
|
||||
stacked: true,
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var clusterChart = new Chart("clusterScoreChart", {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: ["Passing", "Warning", "Failing"],
|
||||
datasets: [{
|
||||
data: [118, 34, 28],
|
||||
backgroundColor: ['#230f39', '#f26c21', '#a11f4c'],
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
// responsive: false,
|
||||
cutoutPercentage: 75,
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
elements: {
|
||||
center: {
|
||||
text: '64%',
|
||||
color: '#333', //Default black
|
||||
fontStyle: 'Helvetica', //Default Arial
|
||||
sidePadding: 30 //Default 20 (as a percentage)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,57 +1,4 @@
|
||||
if (!Object.values) {
|
||||
Object.values = function(obj) {
|
||||
return Object.keys(obj).map(function(key) {
|
||||
return obj[key];
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$(function () {
|
||||
var namespaceChart = new Chart("namespaceScoreChart", {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: Object.keys(fairwindsAuditData.NamespacedResults),
|
||||
datasets: [{
|
||||
label: 'Passing',
|
||||
data: Object.values(fairwindsAuditData.NamespacedResults)
|
||||
.map(function(r) { return r.Summary.Successes}),
|
||||
backgroundColor: '#8BD2DC',
|
||||
},{
|
||||
label: 'Warning',
|
||||
data: Object.values(fairwindsAuditData.NamespacedResults)
|
||||
.map(function(r) { return r.Summary.Warnings}),
|
||||
backgroundColor: '#f26c21',
|
||||
},{
|
||||
label: 'Failing',
|
||||
data: Object.values(fairwindsAuditData.NamespacedResults)
|
||||
.map(function(r) { return r.Summary.Errors}),
|
||||
backgroundColor: '#a11f4c',
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{
|
||||
stacked: true,
|
||||
}],
|
||||
yAxes: [{
|
||||
stacked: true,
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var score = fairwindsAuditData.ClusterSummary.Successes / (
|
||||
fairwindsAuditData.ClusterSummary.Successes +
|
||||
fairwindsAuditData.ClusterSummary.Warnings +
|
||||
fairwindsAuditData.ClusterSummary.Errors);
|
||||
score = Math.round(score * 100);
|
||||
|
||||
var clusterChart = new Chart("clusterScoreChart", {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
@@ -62,24 +9,14 @@ $(function () {
|
||||
fairwindsAuditData.ClusterSummary.Warnings,
|
||||
fairwindsAuditData.ClusterSummary.Errors,
|
||||
],
|
||||
backgroundColor: ['#8BD2DC','#f26c21','#a11f4c'],
|
||||
backgroundColor: ['#8BD2DC', '#f26c21', '#a11f4c'],
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
// responsive: false,
|
||||
cutoutPercentage: 75,
|
||||
responsive: false,
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
elements: {
|
||||
center: {
|
||||
text: score + '%',
|
||||
color: '#333', //Default black
|
||||
fontStyle: 'Helvetica', //Default Arial
|
||||
sidePadding: 30 //Default 20 (as a percentage)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,46 +1,14 @@
|
||||
if (!Object.values) {
|
||||
Object.values = function (obj) {
|
||||
return Object.keys(obj).map(function (key) {
|
||||
return obj[key];
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$(function () {
|
||||
// Chart.js plugin for rendering text inside of donut chart
|
||||
// Credit: https://stackoverflow.com/a/43026361/8870697
|
||||
Chart.pluginService.register({
|
||||
beforeDraw: function (chart) {
|
||||
if (chart.config.options.elements.center) {
|
||||
var ctx = chart.chart.ctx;
|
||||
var centerConfig = chart.config.options.elements.center;
|
||||
var fontStyle = centerConfig.fontStyle || 'Arial';
|
||||
var txt = centerConfig.text;
|
||||
var color = centerConfig.color || '#000';
|
||||
var sidePadding = centerConfig.sidePadding || 20;
|
||||
var sidePaddingCalculated = (sidePadding/100) * (chart.innerRadius * 2)
|
||||
// Start with a base font of 30px
|
||||
ctx.font = "30px " + fontStyle;
|
||||
|
||||
// Get the width of the string and also the width of the element minus 10 to give it 5px side padding
|
||||
var stringWidth = ctx.measureText(txt).width;
|
||||
var elementWidth = (chart.innerRadius * 2) - sidePaddingCalculated;
|
||||
|
||||
// Find out how much the font can grow in width.
|
||||
var widthRatio = elementWidth / stringWidth;
|
||||
var newFontSize = Math.floor(30 * widthRatio);
|
||||
var elementHeight = (chart.innerRadius * 2);
|
||||
|
||||
// Pick a new font size so it will not be larger than the height of label.
|
||||
var fontSizeToUse = Math.min(newFontSize, elementHeight);
|
||||
|
||||
// Set font settings to draw it correctly.
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
var centerX = ((chart.chartArea.left + chart.chartArea.right) / 2);
|
||||
var centerY = ((chart.chartArea.top + chart.chartArea.bottom) / 2);
|
||||
ctx.font = "bold "+fontSizeToUse+"px " + fontStyle;
|
||||
ctx.fillStyle = color;
|
||||
|
||||
// Draw text in center
|
||||
ctx.fillText(txt, centerX, centerY);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.namespace .resource-info .name').on('click', function(e) {
|
||||
$('.namespace .resource-info .name').on('click', function (e) {
|
||||
console.log('clicked', arguments)
|
||||
console.log('parent', $(e.srcElement).parent('.resource-info'));
|
||||
$(e.srcElement).parents('.resource-info').toggleClass('expanded');
|
||||
|
||||
Reference in New Issue
Block a user