feat: Implement grafana-operator Dashboard and Folder CRD health checks (#22493)

Signed-off-by: Arnaud Farbos <afarbos@nvidia.com>
This commit is contained in:
afarbos
2025-05-09 12:05:19 -07:00
committed by GitHub
parent 59b9ffa094
commit 5a3a104793
10 changed files with 325 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
-- Reference CRD can be found here:
-- https://grafana.github.io/grafana-operator/docs/api/#grafanadashboard
function getStatusFromConditions(obj, hs)
if obj.status ~= nil and obj.status.conditions ~= nil then
for i, condition in ipairs(obj.status.conditions) do
if condition.status ~= nil then
if hs.message ~= "" then
hs.message = hs.message .. ", "
end
if condition.reason ~= nil then
hs.message = hs.message .. condition.reason
if condition.type ~= nil then
hs.message = hs.message .. " for " .. condition.type
if condition.message ~= nil then
hs.message = hs.message .. " because " .. condition.message
end
end
end
if condition.status == "False" then
hs.status = "Degraded"
return hs
end
if condition.status == "True" then
hs.status = "Healthy"
end
end
end
end
return hs
end
local hs = {}
hs.status = "Progressing"
hs.message = ""
hs = getStatusFromConditions(obj, hs)
return hs

View File

@@ -0,0 +1,16 @@
tests:
- healthStatus:
status: Progressing
message: ""
inputPath: testdata/progressing.yaml
- healthStatus:
status: Healthy
message: "ApplySuccessful for DashboardSynchronized because Dashboard was successfully applied to 1 instances"
inputPath: testdata/healthy.yaml
- healthStatus:
status: Degraded
message: >-
ApplyFailed for DashboardSynchronized because Dashboard failed to be applied for 1 out of 1 instances. Errors:
- grafana-operator/grafana: Get "https://dashboards.grafana.com/api/search?limit=1000&page=1&type=dash-db": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
inputPath: testdata/degraded.yaml

View File

@@ -0,0 +1,42 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
annotations:
argocd.argoproj.io/installation-id: argocd.com
argocd.argoproj.io/tracking-id: >-
foo:grafana.integreatly.org/GrafanaDashboard:grafana-operator/degraded
creationTimestamp: '2025-03-21T20:19:50Z'
finalizers:
- operator.grafana.com/finalizer
generation: 1
labels:
argocd.argoproj.io/instance: foo
name: degraded
namespace: grafana-operator
resourceVersion: '185954752'
uid: a7d497f7-5a8d-450b-8b44-50d5f50ce72e
spec:
allowCrossNamespaceImport: false
folderRef: barfolder
instanceSelector:
matchLabels:
dashboards: grafana
json: |
{
}
resyncPeriod: 10m0s
status:
conditions:
- lastTransitionTime: '2025-03-21T20:20:21Z'
message: >-
Dashboard failed to be applied for 1 out of 1 instances. Errors:
- grafana-operator/grafana: Get
"https://dashboards.grafana.com/api/search?limit=1000&page=1&type=dash-db":
net/http: request canceled while waiting for connection (Client.Timeout
exceeded while awaiting headers)
observedGeneration: 1
reason: ApplyFailed
status: 'False'
type: DashboardSynchronized
lastResync: '2025-03-26T15:02:40Z'

View File

@@ -0,0 +1,38 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
annotations:
argocd.argoproj.io/installation-id: argocd.com
argocd.argoproj.io/tracking-id: >-
foo:grafana.integreatly.org/GrafanaDashboard:grafana-operator/healthy
creationTimestamp: '2025-03-21T20:19:50Z'
finalizers:
- operator.grafana.com/finalizer
generation: 1
labels:
argocd.argoproj.io/instance: foo
name: healthy
namespace: grafana-operator
resourceVersion: '185954752'
uid: a7d497f7-5a8d-450b-8b44-50d5f50ce72e
spec:
allowCrossNamespaceImport: false
folderRef: barfolder
instanceSelector:
matchLabels:
dashboards: grafana
json: |
{
}
resyncPeriod: 10m0s
status:
conditions:
- lastTransitionTime: '2025-03-21T20:27:27Z'
message: Dashboard was successfully applied to 1 instances
observedGeneration: 1
reason: ApplySuccessful
status: 'True'
type: DashboardSynchronized
hash: 783fb827a235e91feb4a5a38c90b36bc072015970789b334724dfc42b6f1a3f6
lastResync: '2025-03-26T15:05:34Z'
uid: 72e0e05bef5099e5f049b05fdc429ed4

View File

@@ -0,0 +1,27 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
annotations:
argocd.argoproj.io/installation-id: argocd.com
argocd.argoproj.io/tracking-id: >-
foo:grafana.integreatly.org/GrafanaDashboard:grafana-operator/progressing
creationTimestamp: '2025-03-21T20:19:50Z'
finalizers:
- operator.grafana.com/finalizer
generation: 1
labels:
argocd.argoproj.io/instance: foo
name: progressing
namespace: grafana-operator
resourceVersion: '185954752'
uid: a7d497f7-5a8d-450b-8b44-50d5f50ce72e
spec:
allowCrossNamespaceImport: false
folderRef: barfolder
instanceSelector:
matchLabels:
dashboards: grafana
json: |
{
}
resyncPeriod: 10m0s

View File

@@ -0,0 +1,43 @@
-- Reference CRD can be found here:
-- https://grafana.github.io/grafana-operator/docs/api/#grafanafolder
function getStatusFromConditions(obj, hs)
if obj.status ~= nil and obj.status.conditions ~= nil then
for i, condition in ipairs(obj.status.conditions) do
if condition.status ~= nil then
if hs.message ~= "" then
hs.message = hs.message .. ", "
end
if condition.reason ~= nil then
hs.message = hs.message .. condition.reason
if condition.type ~= nil then
hs.message = hs.message .. " for " .. condition.type
if condition.message ~= nil then
hs.message = hs.message .. " because " .. condition.message
end
end
end
if condition.status == "False" then
hs.status = "Degraded"
return hs
end
if condition.status == "True" then
hs.status = "Healthy"
end
end
end
end
return hs
end
local hs = {}
hs.status = "Progressing"
hs.message = ""
hs = getStatusFromConditions(obj, hs)
return hs

View File

@@ -0,0 +1,16 @@
tests:
- healthStatus:
status: Progressing
message: ""
inputPath: testdata/progressing.yaml
- healthStatus:
status: Healthy
message: "ApplySuccessful for FolderSynchronized because Folder was successfully applied to 1 instances"
inputPath: testdata/healthy.yaml
- healthStatus:
status: Degraded
message: >-
ApplyFailed for FolderSynchronized because Folder failed to be applied for 1 out of 1 instances. Errors:
- grafana-operator/grafana: Get "https://dashboards.grafana.com/api/folders?limit=10000&page=1": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
inputPath: testdata/degraded.yaml

View File

@@ -0,0 +1,40 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
annotations:
argocd.argoproj.io/installation-id: argocd.com
argocd.argoproj.io/tracking-id: >-
foo:grafana.integreatly.org/GrafanaFolder:grafana-operator/bar
creationTimestamp: '2025-03-21T19:55:18Z'
finalizers:
- operator.grafana.com/finalizer
generation: 1
labels:
argocd.argoproj.io/instance: foo
name: bar
namespace: grafana-operator
resourceVersion: '185973434'
uid: ada2bab9-613e-4a1c-98c0-75094b72978e
spec:
allowCrossNamespaceImport: false
instanceSelector:
matchLabels:
dashboards: grafana
resyncPeriod: 10m0s
title: Baz-Folder
status:
conditions:
- lastTransitionTime: '2025-03-21T19:55:38Z'
message: >-
Folder failed to be applied for 1 out of 1 instances. Errors:
- grafana-operator/grafana: Get
"https://dashboards.grafana.com/api/folders?limit=10000&page=1":
net/http: request canceled while waiting for connection (Client.Timeout
exceeded while awaiting headers)
observedGeneration: 1
reason: ApplyFailed
status: 'False'
type: FolderSynchronized
hash: d6cea1a429ba926fb709e2ac7f468f5a99e534049a96eecc28e1d881f49d93f2
lastResync: '2025-03-26T15:29:24Z'

View File

@@ -0,0 +1,35 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
annotations:
argocd.argoproj.io/installation-id: argocd.com
argocd.argoproj.io/tracking-id: >-
foo:grafana.integreatly.org/GrafanaFolder:grafana-operator/bar
creationTimestamp: '2025-03-26T14:50:23Z'
finalizers:
- operator.grafana.com/finalizer
generation: 1
labels:
argocd.argoproj.io/instance: foo
name: bar
namespace: grafana-operator
resourceVersion: '185974148'
uid: 226a9af3-4a5d-4ebb-9705-ddfec0f6db47
spec:
allowCrossNamespaceImport: false
instanceSelector:
matchLabels:
dashboards: grafana
parentFolderRef: baz
resyncPeriod: 10m0s
title: Bar-Folder
status:
conditions:
- lastTransitionTime: '2025-03-26T14:50:23Z'
message: Folder was successfully applied to 1 instances
observedGeneration: 1
reason: ApplySuccessful
status: 'True'
type: FolderSynchronized
hash: f929c3bb9a96dbba11dd9ecf049ab28f98d7f8fbf5403aee0877c2c7b6f2547f
lastResync: '2025-03-26T15:30:24Z'

View File

@@ -0,0 +1,25 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
annotations:
argocd.argoproj.io/installation-id: argocd.com
argocd.argoproj.io/tracking-id: >-
foo:grafana.integreatly.org/GrafanaFolder:grafana-operator/bar
creationTimestamp: '2025-03-26T14:50:23Z'
finalizers:
- operator.grafana.com/finalizer
generation: 1
labels:
argocd.argoproj.io/instance: foo
name: bar
namespace: grafana-operator
resourceVersion: '185974148'
uid: 226a9af3-4a5d-4ebb-9705-ddfec0f6db47
spec:
allowCrossNamespaceImport: false
instanceSelector:
matchLabels:
dashboards: grafana
parentFolderRef: baz
resyncPeriod: 10m0s
title: Bar-Folder