Skip to content

Commit

Permalink
Start rewriting dashboards using new Grafonnet
Browse files Browse the repository at this point in the history
Signed-off-by: Matus Jenca <[email protected]>
  • Loading branch information
MatusJenca2 committed Dec 19, 2024
1 parent ede2b3c commit 20cdefc
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 8 deletions.
16 changes: 8 additions & 8 deletions helpers/ci_cd_image/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
FROM golang:1.15.2-alpine3.12 AS builder

RUN apk update && apk upgrade && \
apk add --no-cache bash git
FROM golang:1.18.10-bullseye AS builder

RUN apt update -y && apt upgrade -y
RUN git clone https://github.com/google/go-jsonnet.git && \
cd go-jsonnet && \
git reset --hard 31d71aaccda6d98135ecc02acae823ef6e78270c && \
# git reset --hard 31d71aaccda6d98135ecc02acae823ef6e78270c && \
git checkout tags/v0.20.0 && \
go build ./cmd/jsonnet && \
go build ./cmd/jsonnetfmt && \
go build ./cmd/jsonnet-lint

RUN wget https://github.com/mikefarah/yq/releases/download/3.4.1/yq_linux_amd64 -O /go/yq && \
chmod +x /go/yq

RUN go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb && \
RUN go install -a github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@latest && \
jb init && \
jb install https://github.com/grafana/grafonnet-lib/grafonnet@daad85cf3fad3580e58029414630e29956aefe21 && \
jb install https://github.com/thelastpickle/grafonnet-polystat-panel@275a48de57afdac0d72219d82863d8ab8bd0e682
jb install https://github.com/thelastpickle/grafonnet-polystat-panel@275a48de57afdac0d72219d82863d8ab8bd0e682 && \
jb install https://github.com/grafana/grafonnet/gen/grafonnet-latest@main

FROM alpine:3.12

LABEL Version="1.0.3"
LABEL Vendor="dNation"
LABEL Description="CI/CD jsonnet docker image"

LABEL JsonnetVersion="fe2809577220c8c06810e842c074f0f0820e9169"
LABEL JsonnetVersion="v0.20.0"
LABEL YqVersion="3.4.1"
LABEL GrafonnetVersion="daad85cf3fad3580e58029414630e29956aefe21"
LABEL GrafonnetPolystatPanelVersion="275a48de57afdac0d72219d82863d8ab8bd0e682"
Expand Down
238 changes: 238 additions & 0 deletions jsonnet/dashboards/apps/ssl-exporter-new.libsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
/*
Copyright 2024 The dNation Kubernetes Monitoring Authors. All Rights Reserved.
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.
*/

/* SSL exporter dashboard */
local g = import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet';

local prometheus = g.query.prometheus;
local stat = g.panel.stat;
local table = g.panel.table;
local timeSeries = g.panel.timeSeries;
local var = g.dashboard.variable;
local row = g.panel.row;
{

local statPanel(title,query,color="gray", colorMode="fixed") = stat.new (title)
+ stat.options.withGraphMode('none')
+ stat.standardOptions.color.withMode(colorMode)
+ stat.standardOptions.color.withFixedColor('gray')
+ stat.queryOptions.withTargets([
prometheus.new('$datasource',query)
+ prometheus.withInstant(true),
]),
local statPanelThreshold(title,query,steps) = stat.new (title)
+ stat.options.withGraphMode('none')
+ stat.standardOptions.thresholds.withSteps(steps)
+ stat.standardOptions.thresholds.withMode("absolute")
+ stat.queryOptions.withTargets([
prometheus.new('$datasource',query)
+ prometheus.withInstant(true),
]),
local failedSSLConnectTable = table.new('Failed SSL Connect')
+ table.standardOptions.thresholds.withSteps([
table.standardOptions.threshold.step.withValue(null)
+ table.standardOptions.threshold.step.withColor("red"),
],)
+ table.fieldConfig.defaults.custom.cellOptions.TableColoredBackgroundCellOptions.withMode("basic")
+ table.fieldConfig.defaults.custom.cellOptions.TableColoredBackgroundCellOptions.withType()
+ table.standardOptions.withUnit('short')
+ table.standardOptions.withOverrides([
table.standardOptions.override.byRegexp.new('(Time|__name__)')
+ table.standardOptions.override.byRegexp.withPropertiesFromOptions(table.fieldConfig.defaults.custom.withHidden()),
table.standardOptions.override.byName.new('Value')
+ table.standardOptions.override.byName.withPropertiesFromOptions(
table.standardOptions.withUnit('short')
+ table.standardOptions.withDecimals(0)
),
])
+ table.queryOptions.withTargets([
prometheus.new('$datasource','ssl_probe_success{cluster="$cluster"}==0' )
+ prometheus.withInstant(true)
+ prometheus.withFormat('table'),
]),
local sslExporterTable(title,query) = table.new(title)
+ table.standardOptions.thresholds.withMode("absoute")
+ table.standardOptions.thresholds.withSteps([
table.standardOptions.threshold.step.withValue(null)
+ table.standardOptions.threshold.step.withColor("transparent"),
],)
+ table.fieldConfig.defaults.custom.cellOptions.TableColoredBackgroundCellOptions.withMode("basic")
+ table.fieldConfig.defaults.custom.cellOptions.TableColoredBackgroundCellOptions.withType()
+ table.gridPos.withW(24)
+ table.standardOptions.withOverrides([
table.standardOptions.override.byName.new('Value')
+ table.standardOptions.override.byName.withPropertiesFromOptions(
table.standardOptions.thresholds.withMode("absolute")
+ table.standardOptions.withUnit('s')
+ table.standardOptions.thresholds.withSteps([
table.standardOptions.threshold.step.withValue(null) + table.standardOptions.threshold.step.withColor("red"),
table.standardOptions.threshold.step.withValue(24*60*60) + table.standardOptions.threshold.step.withColor("orange"),
table.standardOptions.threshold.step.withValue(7*24*60*60) + table.standardOptions.threshold.step.withColor("green"),
])
),
table.standardOptions.override.byRegexp.new('(Time|container|endpoint|job|namespace|prometheus.*|service|pod)')
+ table.standardOptions.override.byRegexp.withPropertiesFromOptions(table.fieldConfig.defaults.custom.withHidden())
],
)
+ table.queryOptions.withTransformations([
table.queryOptions.transformation.withId('organize')
+ table.queryOptions.transformation.withOptions({
renameByName: {
Value: "Expires In",
cluster: "Cluester",
cn: "CN",
issuer_cn: "IssuerCN",
serial_no: "Serial No."
},
}
)
],)
+ table.queryOptions.withTargets([
prometheus.new('$datasource', query)
+ prometheus.withInstant(true)
+ prometheus.withFormat('table'),
])
,
local sslExternalDesc = 'External SSL Certificates',
local sslKubeconfigDesc = 'Kubeconfig Certificates',
local sslK8sFileDesc = 'Internal Kubernetes Certificates',
local sslK8sSecretDesc = 'Kubernetes Secret Certificates',
grafanaDashboards+:: {
'ssl-exporter-new':
local panels = {
totalUniqueCerts: statPanel(
title='Total Unique Certificates',
query='count(max(ssl_cert_not_after{cluster="$cluster", job=~"$job"}) by (issuer_cn, serial_no))'
),
totalProbeTargets: statPanel(
title='Total Probe Targets',
query='count(ssl_probe_success{cluster="$cluster"})',
),
failedSSLCount: statPanelThreshold(
title='Expired/Failed Certificates',
query='(count(up{job=~"$job", cluster="$cluster"}==0) OR on() vector(0))+(count(ssl_probe_success{cluster="$cluster"}==0) OR on() vector(0))+(count((ssl_cert_not_after{cluster="$cluster"}-time())<0) OR on() vector(0))+\n (count((ssl_file_not_after{cluster="$cluster"}-time())<0) OR on() vector(0))+\n (count((ssl_kubeconfig_cert_not_after{cluster="$cluster"}-time())<0) OR on()vector(0))+(count((ssl_kubernetes_cert_not_after{cluster="$cluster"}-time())<0) OR on()vector(0))',
steps=[{index:0, value: 0, color: 'green' },{index:0, value: 1, color: 'red' }],
),
nearingExpiryCount : statPanelThreshold(
title='Certificates Nearing Expiration',
query='(count(0<(ssl_cert_not_after{cluster="$cluster"}-time())<8*24*60*60) OR on() vector(0))+(count(0<(ssl_file_not_after{cluster="$cluster"}-time())<8*24*60*60) OR on() vector(0))+(count(0<(ssl_kubeconfig_cert_not_after{cluster="$cluster"}-time())<8*24*60*60) OR on() vector(0))+(count(0<(ssl_kubernetes_cert_not_after{cluster="$cluster"}-time())<8*24*60*60) OR on() vector(0))',
steps=[{index:0, value: 0, color: 'green' },{index:0, value: 1, color: 'orange' }],

),
failedSSLConnect: failedSSLConnectTable
,
externalCerts : sslExporterTable(
title=sslExternalDesc,
query='ssl_cert_not_after{ job=~"$job", cluster="$cluster" } - time()'
),
k8sKubeconfigCerts : sslExporterTable(
title=sslKubeconfigDesc,
query='ssl_kubeconfig_cert_not_after{ job=~"$job", cluster="$cluster" } - time()',
),
k8sFiles: sslExporterTable(
title=sslK8sFileDesc,
query='ssl_file_cert_not_after{ job=~"$job", cluster="$cluster" }* on(pod) group_left(node) kube_pod_info{ cluster="$cluster"} - time()',
),
k8sSecrets: sslExporterTable(
title=sslK8sSecretDesc,
query='ssl_kubernetes_cert_not_after{ job=~"$job", cluster="$cluster" } - time()',
),
};

local grid =
g.util.grid.makeGrid(
[
row.new('Overview')
+ row.withPanels([
panels.totalUniqueCerts,
panels.totalProbeTargets,
panels.failedSSLCount,
panels.nearingExpiryCount
])],panelWidth=6, panelHeight=6, startY=0)
+ g.util.grid.makeGrid([
row.new('Failed SSL Connects')
+ row.withPanels([
panels.failedSSLConnect
]),
row.new(sslExternalDesc)
+ row.withPanels([
panels.externalCerts,
]),
row.new(sslKubeconfigDesc)
+ row.withCollapsed()
+ row.withPanels([
panels.k8sKubeconfigCerts,
]),
row.new(sslK8sFileDesc)
+ row.withCollapsed()
+ row.withPanels([
panels.k8sFiles,
]),
row.new(sslK8sSecretDesc)
+ row.withCollapsed()
+ row.withPanels([
panels.k8sSecrets,
])],panelWidth=24, panelHeight=6, startY=7);

local variables = {
datasource:
var.datasource.new('datasource', 'prometheus')
+ var.datasource.generalOptions.showOnDashboard.withLabelAndValue()
+ var.datasource.generalOptions.withCurrent('thanos')
+ var.datasource.generalOptions.withLabel('Data source'),
cluster:
var.query.new('cluster')
+ var.query.withDatasourceFromVariable(self.datasource)
+ var.query.queryTypes.withLabelValues('cluster','node_uname_info')
+ var.query.generalOptions.withLabel('Cluster')
+ var.query.refresh.onTime()
+ var.query.withSort(type='alphabetical'),
job:
var.query.new('job')
+ var.query.withDatasourceFromVariable(self.datasource)
+ var.query.generalOptions.withLabel('Job')
+ var.query.generalOptions.showOnDashboard.withLabelAndValue()
+ var.query.refresh.onTime()
+ var.query.selectionOptions.withIncludeAll(true)
+ var.query.withSort(type='alphabetical')
+ var.query.queryTypes.withLabelValues('job','ssl_probe_success{cluster="$cluster"}'),
instance:
var.query.new('instance')
+ var.query.withDatasourceFromVariable(self.datasource)
+ var.query.refresh.onTime()
+ var.query.withSort(type='alphabetical')
+ var.query.generalOptions.showOnDashboard.withLabelAndValue()
+ var.query.selectionOptions.withIncludeAll(true)
+ var.query.queryTypes.withLabelValues('instance','{job=~"$job"}'),


};
// hack: g.util has a makeGrid function, however it supports only panels of equal width
local rowfunc(row) = g.util.grid.wrapPanels([row.content],24,1,row.y-1) + g.util.grid.wrapPanels(
row.content.panels,
row.w,
row.h,
row.y
);

g.dashboard.new('SSL Certificates')
+ g.dashboard.withUid($._config.grafanaDashboards.ids.sslExporter)
+ g.dashboard.withEditable($._config.grafanaDashboards.editable)
+ g.dashboard.withRefresh($._config.grafanaDashboards.refresh)
+ g.dashboard.time.withFrom($._config.grafanaDashboards.time_from)
+ g.dashboard.withTags($._config.grafanaDashboards.tags.k8sApps)
+ g.dashboard.withVariables([variables.datasource, variables.cluster, variables.job, variables.instance])
+ g.dashboard.withPanels(grid)
},

}
1 change: 1 addition & 0 deletions jsonnet/dashboards/dashboards.libsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
(import 'apps/jvm.libsonnet') +
(import 'apps/prometheus.libsonnet') +
(import 'apps/ssl-exporter.libsonnet') +
(import 'apps/ssl-exporter-new.libsonnet') +
(import 'apps/harbor.libsonnet') +

// VMs dashboards
Expand Down

0 comments on commit 20cdefc

Please sign in to comment.