From 0048ffb4ad4a341705e7d1499cd24e5c67c5f8e1 Mon Sep 17 00:00:00 2001 From: Jean-Francois Roy Date: Thu, 29 Aug 2024 23:21:07 -0700 Subject: [PATCH] feat(nut-exporter): deploy --- .../apps/observability/kustomization.yaml | 1 + .../nut-exporter/app/externalsecret.yaml | 19 +++++ .../nut-exporter/app/helmrelease.yaml | 62 ++++++++++++++ .../nut-exporter/app/kustomization.yaml | 9 ++ .../nut-exporter/app/prometheusrule.yaml | 56 +++++++++++++ .../nut-exporter/app/servicemonitor.yaml | 84 +++++++++++++++++++ .../apps/observability/nut-exporter/ks.yaml | 23 +++++ 7 files changed, 254 insertions(+) create mode 100644 kubernetes/apps/observability/nut-exporter/app/externalsecret.yaml create mode 100644 kubernetes/apps/observability/nut-exporter/app/helmrelease.yaml create mode 100644 kubernetes/apps/observability/nut-exporter/app/kustomization.yaml create mode 100644 kubernetes/apps/observability/nut-exporter/app/prometheusrule.yaml create mode 100644 kubernetes/apps/observability/nut-exporter/app/servicemonitor.yaml create mode 100644 kubernetes/apps/observability/nut-exporter/ks.yaml diff --git a/kubernetes/apps/observability/kustomization.yaml b/kubernetes/apps/observability/kustomization.yaml index 380bec785..2030167e3 100644 --- a/kubernetes/apps/observability/kustomization.yaml +++ b/kubernetes/apps/observability/kustomization.yaml @@ -8,6 +8,7 @@ resources: - ./gatus/ks.yaml - ./grafana/ks.yaml - ./kube-prometheus-stack/ks.yaml + - ./nut-exporter/ks.yaml - ./policy-reporter/ks.yaml - ./prometheus-operator-crds/ks.yaml # - ./scrutiny/ks.yaml diff --git a/kubernetes/apps/observability/nut-exporter/app/externalsecret.yaml b/kubernetes/apps/observability/nut-exporter/app/externalsecret.yaml new file mode 100644 index 000000000..8820e380d --- /dev/null +++ b/kubernetes/apps/observability/nut-exporter/app/externalsecret.yaml @@ -0,0 +1,19 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1beta1.json +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: nut-exporter +spec: + secretStoreRef: + kind: ClusterSecretStore + name: onepassword + target: + name: nut-exporter-secret + template: + data: + NUT_EXPORTER_USERNAME: "{{ .username }}" + NUT_EXPORTER_PASSWORD: "{{ .password }}" + dataFrom: + - extract: + key: nut-exporter diff --git a/kubernetes/apps/observability/nut-exporter/app/helmrelease.yaml b/kubernetes/apps/observability/nut-exporter/app/helmrelease.yaml new file mode 100644 index 000000000..bf4213d9a --- /dev/null +++ b/kubernetes/apps/observability/nut-exporter/app/helmrelease.yaml @@ -0,0 +1,62 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: nut-exporter +spec: + interval: 30m + chart: + spec: + chart: app-template + version: 3.4.0 + sourceRef: + kind: HelmRepository + name: bjw-s + namespace: flux-system + driftDetection: + mode: enabled + install: + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + strategy: rollback + retries: 3 + values: + controllers: + nut-exporter: + annotations: + reloader.stakater.com/auto: "true" + containers: + nut-exporter: + image: + repository: ghcr.io/druggeri/nut_exporter + tag: 3.1.1 + args: + # the first time I set this, the first and last entries were ignored, so I have doubled them. + - --nut.vars_enable="battery.charge,battery.charge,battery.runtime,battery.voltage,battery.voltage.nominal,input.voltage,input.voltage.nominal,output.voltage,output.voltage.nominal,ups.realpower,ups.load,ups.status,ups.status" + env: + TZ: America/Los_Angeles + envFrom: + - secretRef: + name: nut-exporter-secret + resources: + requests: + cpu: 1m + limits: + memory: 100Mi + service: + app: + controller: nut-exporter + ports: + metrics: + protocol: TCP + port: 9199 + ipFamilyPolicy: PreferDualStack + serviceMonitor: + app: + serviceName: nut-exporter + endpoints: + - name: metrics diff --git a/kubernetes/apps/observability/nut-exporter/app/kustomization.yaml b/kubernetes/apps/observability/nut-exporter/app/kustomization.yaml new file mode 100644 index 000000000..b9ea01577 --- /dev/null +++ b/kubernetes/apps/observability/nut-exporter/app/kustomization.yaml @@ -0,0 +1,9 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./externalsecret.yaml + - ./helmrelease.yaml + - ./prometheusrule.yaml + - ./servicemonitor.yaml diff --git a/kubernetes/apps/observability/nut-exporter/app/prometheusrule.yaml b/kubernetes/apps/observability/nut-exporter/app/prometheusrule.yaml new file mode 100644 index 000000000..8eeb11910 --- /dev/null +++ b/kubernetes/apps/observability/nut-exporter/app/prometheusrule.yaml @@ -0,0 +1,56 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/prometheusrule_v1.json +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: nut-exporter +spec: + groups: + - name: nut-exporter.rules + rules: + - alert: NutExporterAbsent + annotations: + description: NUT exporter has disappeared from Prometheus target discovery. + summary: NUT Exporter is down. + expr: | + absent(up{job=~".*nut-exporter.*"} == 1) + for: 5m + labels: + severity: critical + - alert: UpsOnBattery + annotations: + description: "{{ $labels.instance }} has lost power and is running on battery." + summary: is running on battery. + expr: network_ups_tools_ups_status{flag="OB"} == 1 + for: 10s + labels: + severity: warning + - alert: UpsLowRuntime + annotations: + description: "{{ $labels.instance }} battery is low and the system is getting ready to shutdown." + summary: battery is low. + expr: | + ( + network_ups_tools_ups_status{flag="OB"} == 1 + and + network_ups_tools_battery_runtime < 600 + ) + for: 1m + labels: + severity: critical + - alert: UpsLowBattery + expr: network_ups_tools_battery_charge < 50 + labels: + severity: warning + annotations: + description: "{{ $labels.instance }} battery charge is {{ $value }} which is below 50%." + summary: battery low + - alert: UpsBatteryReplace + annotations: + description: UPS {{ $labels.ups }} battery needs to be replaced. + summary: Replace UPS battery. + expr: | + network_ups_tools_ups_status{flag="RB"} == 1 + for: 10s + labels: + severity: warning diff --git a/kubernetes/apps/observability/nut-exporter/app/servicemonitor.yaml b/kubernetes/apps/observability/nut-exporter/app/servicemonitor.yaml new file mode 100644 index 000000000..3441cc3df --- /dev/null +++ b/kubernetes/apps/observability/nut-exporter/app/servicemonitor.yaml @@ -0,0 +1,84 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/servicemonitor_v1.json +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: metrics + app.kubernetes.io/instance: homeassistant + app.kubernetes.io/name: nut-exporter + name: nut-exporter-homeassistant + namespace: monitoring +spec: + endpoints: + - interval: 30s + metricRelabelings: + - action: replace + replacement: homeassistant + sourceLabels: + - instance + targetLabel: instance + - action: replace + replacement: homeassistant.flat + sourceLabels: + - server + targetLabel: server + - action: labeldrop + regex: (pod) + params: + server: + - homeassistant.flat + path: /ups_metrics + port: metrics + scheme: http + scrapeTimeout: 30s + jobLabel: nut-exporter + namespaceSelector: + matchNames: + - monitoring + selector: + matchLabels: + app.kubernetes.io/instance: nut-exporter + app.kubernetes.io/name: nut-exporter +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/servicemonitor_v1.json +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/component: metrics + app.kubernetes.io/instance: pikvm + app.kubernetes.io/name: nut-exporter + name: nut-exporter-pikvm + namespace: monitoring +spec: + endpoints: + - interval: 30s + metricRelabelings: + - action: replace + replacement: pikvm + sourceLabels: + - instance + targetLabel: instance + - action: replace + replacement: pikvm.flat + sourceLabels: + - server + targetLabel: server + - action: labeldrop + regex: (pod) + params: + server: + - pikvm.flat + path: /ups_metrics + port: metrics + scheme: http + scrapeTimeout: 30s + jobLabel: nut-exporter + namespaceSelector: + matchNames: + - monitoring + selector: + matchLabels: + app.kubernetes.io/instance: nut-exporter + app.kubernetes.io/name: nut-exporter diff --git a/kubernetes/apps/observability/nut-exporter/ks.yaml b/kubernetes/apps/observability/nut-exporter/ks.yaml new file mode 100644 index 000000000..38863af69 --- /dev/null +++ b/kubernetes/apps/observability/nut-exporter/ks.yaml @@ -0,0 +1,23 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app nut-exporter + namespace: flux-system +spec: + targetNamespace: observability + commonMetadata: + labels: + app.kubernetes.io/name: *app + dependsOn: + - name: external-secrets-stores + path: ./kubernetes/apps/observability/nut-exporter/app + prune: true + sourceRef: + kind: GitRepository + name: home-kubernetes + wait: false + interval: 30m + retryInterval: 1m + timeout: 5m