diff --git a/pkg/dashboard/dashboard.go b/pkg/dashboard/dashboard.go index e53161eea..b0d03a0bc 100644 --- a/pkg/dashboard/dashboard.go +++ b/pkg/dashboard/dashboard.go @@ -28,8 +28,16 @@ import ( ) const ( - // TemplateName references the dashboard template to use - TemplateName = "dashboard.gohtml" + // MainTemplateName is the main template + MainTemplateName = "main.gohtml" + // HeaderTemplateName contains the navbar + HeaderTemplateName = "header.gohtml" + // PreambleTemplateName contains an empty preamble that can be overridden + PreambleTemplateName = "preamble.gohtml" + // DashboardTemplateName contains the content of the dashboard + DashboardTemplateName = "dashboard.gohtml" + // FooterTemplateName contains the footer + FooterTemplateName = "footer.gohtml" ) var ( @@ -59,6 +67,40 @@ type TemplateData struct { JSON template.JS } +// GetBaseTemplate puts together the dashboard template. Individual pieces can be overridden before rendering. +func GetBaseTemplate(name string) (*template.Template, error) { + tmpl := template.New(name).Funcs(template.FuncMap{ + "getWarningWidth": getWarningWidth, + "getSuccessWidth": getSuccessWidth, + "getWeatherIcon": getWeatherIcon, + "getWeatherText": getWeatherText, + "getGrade": getGrade, + "getScore": getScore, + "getIcon": getIcon, + }) + + templateBox := GetTemplateBox() + templateFileNames := []string{ + DashboardTemplateName, + HeaderTemplateName, + PreambleTemplateName, + FooterTemplateName, + MainTemplateName, + } + for _, fname := range templateFileNames { + templateFile, err := templateBox.Find(fname) + if err != nil { + return nil, err + } + + tmpl, err = tmpl.Parse(string(templateFile)) + if err != nil { + return nil, err + } + } + return tmpl, nil +} + // MainHandler gets template data and renders the dashboard with it. func MainHandler(w http.ResponseWriter, r *http.Request, auditData validator.AuditData) { jsonData, err := json.Marshal(auditData) @@ -72,33 +114,15 @@ func MainHandler(w http.ResponseWriter, r *http.Request, auditData validator.Aud AuditData: auditData, JSON: template.JS(jsonData), } - - templateBox := GetTemplateBox() - templateFile, err := templateBox.Find(TemplateName) - + tmpl, err := GetBaseTemplate("main") if err != nil { logrus.Printf("Error getting template data %v", err) http.Error(w, "Error getting template data", 500) return } - tmpl, err := template.New(TemplateName).Funcs(template.FuncMap{ - "getWarningWidth": getWarningWidth, - "getSuccessWidth": getSuccessWidth, - "getWeatherIcon": getWeatherIcon, - "getWeatherText": getWeatherText, - "getGrade": getGrade, - "getScore": getScore, - "getIcon": getIcon, - }).Parse(string(templateFile)) - - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - buf := &bytes.Buffer{} - err = template.Must(tmpl.Clone()).Execute(buf, templateData) + err = tmpl.ExecuteTemplate(buf, "main", templateData) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/pkg/dashboard/templates/dashboard.gohtml b/pkg/dashboard/templates/dashboard.gohtml index 0fd0dadf8..42d831657 100644 --- a/pkg/dashboard/templates/dashboard.gohtml +++ b/pkg/dashboard/templates/dashboard.gohtml @@ -1,163 +1,117 @@ - - - - - - - Fairwinds - - - - - - - - - - - - - - - - - -
-
- -
- - Open Source Project By - - +{{define "dashboard"}} +
+

Cluster Overview

+
+
+
+
{{ getWeatherText .AuditData.ClusterSummary.Results }}
+
Grade: {{ getGrade .AuditData.ClusterSummary.Results }} | Score: {{ getScore .AuditData.ClusterSummary.Results }}%
-
-
- -
-
-

Cluster Overview

-
-
-
-
{{ getWeatherText .AuditData.ClusterSummary.Results }}
-
Grade: {{ getGrade .AuditData.ClusterSummary.Results }} | Score: {{ getScore .AuditData.ClusterSummary.Results }}%
-
-
-
    -
  • {{ .AuditData.ClusterSummary.Results.Totals.Successes }} checks passed
  • -
  • {{ .AuditData.ClusterSummary.Results.Totals.Warnings }} checks had warnings
  • -
  • {{ .AuditData.ClusterSummary.Results.Totals.Errors }} checks had errors
  • -
-
- +
+
    +
  • {{ .AuditData.ClusterSummary.Results.Totals.Successes }} checks passed
  • +
  • {{ .AuditData.ClusterSummary.Results.Totals.Warnings }} checks had warnings
  • +
  • {{ .AuditData.ClusterSummary.Results.Totals.Errors }} checks had errors
  • +
- - - + +
-
Cluster details
-
-
    -
  • - Kubernetes Version: - {{ .AuditData.ClusterSummary.Version }} -
  • -
  • - Nodes: - {{ .AuditData.ClusterSummary.Nodes }} -
  • -
  • - Pods: - {{ .AuditData.ClusterSummary.Pods }} -
  • + +
+ + + + + + - - - - -
+
Cluster details
+
+
    +
  • + Kubernetes Version: + {{ .AuditData.ClusterSummary.Version }} +
  • +
  • + Nodes: + {{ .AuditData.ClusterSummary.Nodes }} +
  • +
  • + Pods: + {{ .AuditData.ClusterSummary.Pods }} +
  • +
  • + Namespaces: + {{ .AuditData.ClusterSummary.Namespaces }} +
  • +
+
+
+
Health summary
+
+
    + {{ range $category, $summary := .AuditData.ClusterSummary.Results.ByCategory }}
  • - Namespaces: - {{ .AuditData.ClusterSummary.Namespaces }} -
  • -
-
-
-
Health summary
-
-
    - {{ range $category, $summary := .AuditData.ClusterSummary.Results.ByCategory }} -
  • - {{ $category }} - {{ $summary.Errors }} errors, {{ $summary.Warnings }} warnings -
    -
    -
    -
    -
    -
    + {{ $category }} + {{ $summary.Errors }} errors, {{ $summary.Warnings }} warnings +
    +
    +
    +
    +
    -
  • - {{ end }} -
-
-
+ + + {{ end }} + + +
-
+
- {{ range $namespace, $nsResult := .AuditData.NamespacedResults }} -
-

Namespace: {{ $namespace }}

- - {{ range .DeploymentResults }} - - + + {{ end }} {{/* end range .DeploymentResults */}} +
-
Deployment: {{ .Name }}
+ {{ range $namespace, $nsResult := .AuditData.NamespacedResults }} +
+

Namespace: {{ $namespace }}

+ + {{ range .DeploymentResults }} + + - + - - {{ end }} {{/* end range .DeploymentResults */}} -
+
Deployment: {{ .Name }}
+
+

Pod Spec:

+
    + {{ range $message := .PodResult.Messages}} +
  • {{ .Message }}
  • + {{ end }} +
+
+ {{ range .PodResult.ContainerResults}}
-

Pod Spec:

+

Container: {{ .Name }}

    - {{ range $message := .PodResult.Messages}} + {{ range $message := .Messages}}
  • {{ .Message }}
  • {{ end }}
- {{ range .PodResult.ContainerResults}} -
-

Container: {{ .Name }}

-
    - {{ range $message := .Messages}} -
  • {{ .Message }}
  • - {{ end }} -
-
- {{ end }} {{/* end range .PodResult.ContainerResults */}} - -
-
-
-
-
-
+ {{ end }} {{/* end range .PodResult.ContainerResults */}} +
+
+
+
+
+
-
-
- {{ end }} {{/* end range .AuditData.NamespacedResults */}} - - - - + +
+
+ {{ end }} {{/* end range .AuditData.NamespacedResults */}} - - - +{{end}} diff --git a/pkg/dashboard/templates/footer.gohtml b/pkg/dashboard/templates/footer.gohtml new file mode 100644 index 000000000..756986e45 --- /dev/null +++ b/pkg/dashboard/templates/footer.gohtml @@ -0,0 +1,5 @@ +{{define "footer"}} + +{{end}} diff --git a/pkg/dashboard/templates/header.gohtml b/pkg/dashboard/templates/header.gohtml new file mode 100644 index 000000000..1144b12cb --- /dev/null +++ b/pkg/dashboard/templates/header.gohtml @@ -0,0 +1,13 @@ +{{define "header"}} + +{{end}} diff --git a/pkg/dashboard/templates/main.gohtml b/pkg/dashboard/templates/main.gohtml new file mode 100644 index 000000000..086868b0b --- /dev/null +++ b/pkg/dashboard/templates/main.gohtml @@ -0,0 +1,34 @@ + + + + + + + Fairwinds + + + + + + + + + + + + + + + + + + {{ template "header" . }} +
+ {{ template "preamble" . }} + {{ template "dashboard" . }} +
+ {{ template "footer" . }} + + diff --git a/pkg/dashboard/templates/preamble.gohtml b/pkg/dashboard/templates/preamble.gohtml new file mode 100644 index 000000000..08d8b7176 --- /dev/null +++ b/pkg/dashboard/templates/preamble.gohtml @@ -0,0 +1,2 @@ +{{ define "preamble" }} +{{ end }}