chore: Update manifests after change

This commit is contained in:
2026-04-07 15:36:18 +00:00
parent 2a93e737d5
commit bd80da0e79
795 changed files with 117244 additions and 28 deletions

View File

@@ -0,0 +1,66 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: grafana-operator-postgresql-18-cluster
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-operator-postgresql-18-cluster
helm.sh/chart: postgres-18-cluster-7.11.2
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/version: "7.11.2"
app.kubernetes.io/managed-by: Helm
spec:
instances: 3
imageName: "ghcr.io/cloudnative-pg/postgresql:18.3-standard-trixie"
imagePullPolicy: IfNotPresent
postgresUID: 26
postgresGID: 26
storage:
size: 10Gi
storageClass: local-path
walStorage:
size: 2Gi
storageClass: local-path
resources:
limits:
hugepages-2Mi: 256Mi
requests:
cpu: 20m
memory: 80Mi
affinity:
enablePodAntiAffinity: true
topologyKey: kubernetes.io/hostname
primaryUpdateMethod: switchover
primaryUpdateStrategy: unsupervised
logLevel: info
enableSuperuserAccess: false
enablePDB: true
postgresql:
parameters:
hot_standby_feedback: "on"
max_slot_wal_keep_size: 2000MB
shared_buffers: 128MB
monitoring:
enablePodMonitor: true
disableDefaultQueries: false
plugins:
- name: barman-cloud.cloudnative-pg.io
enabled: true
isWALArchiver: true
parameters:
barmanObjectName: "grafana-operator-postgresql-18-backup-garage-local"
serverName: "grafana-operator-postgresql-18-backup-2"
bootstrap:
recovery:
database: app
source: grafana-operator-postgresql-18-backup-2
externalClusters:
- name: grafana-operator-postgresql-18-backup-2
plugin:
name: barman-cloud.cloudnative-pg.io
enabled: true
isWALArchiver: false
parameters:
barmanObjectName: "grafana-operator-postgresql-18-recovery"
serverName: grafana-operator-postgresql-18-backup-2

View File

@@ -0,0 +1,97 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: grafana-operator
labels:
helm.sh/chart: grafana-operator-5.22.2
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "v5.22.2"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/component: operator
rules:
- apiGroups:
- ""
resources:
- configmaps
- persistentvolumeclaims
- secrets
- serviceaccounts
- services
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
- events.k8s.io
resources:
- events
verbs:
- create
- patch
- apiGroups:
- apps
resources:
- deployments
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- httproutes
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- grafana.integreatly.org
resources:
- '*'
verbs:
- get
- list
- patch
- watch
- apiGroups:
- grafana.integreatly.org
resources:
- '*/finalizers'
verbs:
- patch
- update
- apiGroups:
- grafana.integreatly.org
resources:
- '*/status'
verbs:
- get
- patch
- update
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- create
- delete
- get
- list
- patch
- update
- watch

View File

@@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: grafana-operator
labels:
helm.sh/chart: grafana-operator-5.22.2
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "v5.22.2"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/component: operator
roleRef:
kind: ClusterRole
name: grafana-operator
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: grafana-operator
namespace: grafana-operator

View File

@@ -0,0 +1,58 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-operator-valkey-remote-cache-init-scripts
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
data:
init.sh: |-
#!/bin/sh
set -eu
# Default config paths
VALKEY_CONFIG=${VALKEY_CONFIG_PATH:-/data/conf/valkey.conf}
LOGFILE="/data/init.log"
DATA_DIR="/data/conf"
# Logging function (outputs to stderr and file)
log() {
echo "$(date) $1" | tee -a "$LOGFILE" >&2
}
# Clean old log if requested
if [ "${KEEP_OLD_LOGS:-false}" != "true" ]; then
rm -f "$LOGFILE"
fi
if [ -f "$LOGFILE" ]; then
log "Detected restart of this instance ($HOSTNAME)"
fi
log "Creating configuration in $DATA_DIR..."
mkdir -p "$DATA_DIR"
rm -f "$VALKEY_CONFIG"
# Base valkey.conf
log "Generating base valkey.conf"
{
echo "port 6379"
echo "protected-mode no"
echo "bind * -::*"
echo "dir /data"
} >>"$VALKEY_CONFIG"
# Append extra configs if present
if [ -f /usr/local/etc/valkey/valkey.conf ]; then
log "Appending /usr/local/etc/valkey/valkey.conf"
cat /usr/local/etc/valkey/valkey.conf >>"$VALKEY_CONFIG"
fi
if [ -d /extravalkeyconfigs ]; then
log "Appending files in /extravalkeyconfigs/"
cat /extravalkeyconfigs/* >>"$VALKEY_CONFIG"
fi

View File

@@ -0,0 +1,87 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-operator-valkey-unified-alerting-init-scripts
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
data:
init.sh: |-
#!/bin/sh
set -eu
# Default config paths
VALKEY_CONFIG=${VALKEY_CONFIG_PATH:-/data/conf/valkey.conf}
LOGFILE="/data/init.log"
DATA_DIR="/data/conf"
# Logging function (outputs to stderr and file)
log() {
echo "$(date) $1" | tee -a "$LOGFILE" >&2
}
# Clean old log if requested
if [ "${KEEP_OLD_LOGS:-false}" != "true" ]; then
rm -f "$LOGFILE"
fi
if [ -f "$LOGFILE" ]; then
log "Detected restart of this instance ($HOSTNAME)"
fi
log "Creating configuration in $DATA_DIR..."
mkdir -p "$DATA_DIR"
rm -f "$VALKEY_CONFIG"
# Base valkey.conf
log "Generating base valkey.conf"
{
echo "port 6379"
echo "protected-mode no"
echo "bind * -::*"
echo "dir /data"
} >>"$VALKEY_CONFIG"
# Replica mode configuration
log "Configuring replication mode"
# Use POD_INDEX from Kubernetes metadata
POD_INDEX=${POD_INDEX:-0}
IS_MASTER=false
# Check if this is pod-0 (master)
if [ "$POD_INDEX" = "0" ]; then
IS_MASTER=true
log "This pod (index $POD_INDEX) is configured as MASTER"
else
log "This pod (index $POD_INDEX) is configured as REPLICA"
fi
# Configure replica settings
if [ "$IS_MASTER" = "false" ]; then
MASTER_HOST="grafana-operator-valkey-unified-alerting-0.grafana-operator-valkey-unified-alerting-headless.grafana-operator.svc.cluster.local"
MASTER_PORT="6379"
log "Configuring replica to follow master at $MASTER_HOST:$MASTER_PORT"
{
echo ""
echo "# Replica Configuration"
echo "replicaof $MASTER_HOST $MASTER_PORT"
echo "replica-announce-ip grafana-operator-valkey-unified-alerting-$POD_INDEX.grafana-operator-valkey-unified-alerting-headless.grafana-operator.svc.cluster.local"
} >>"$VALKEY_CONFIG"
fi
# Append extra configs if present
if [ -f /usr/local/etc/valkey/valkey.conf ]; then
log "Appending /usr/local/etc/valkey/valkey.conf"
cat /usr/local/etc/valkey/valkey.conf >>"$VALKEY_CONFIG"
fi
if [ -d /extravalkeyconfigs ]; then
log "Appending files in /extravalkeyconfigs/"
cat /extravalkeyconfigs/* >>"$VALKEY_CONFIG"
fi

View File

@@ -0,0 +1,374 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafanaalertrulegroups.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaAlertRuleGroup
listKind: GrafanaAlertRuleGroupList
plural: grafanaalertrulegroups
singular: grafanaalertrulegroup
scope: Namespaced
versions:
- additionalPrinterColumns:
- format: date-time
jsonPath: .status.lastResync
name: Last resync
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaAlertRuleGroup is the Schema for the grafanaalertrulegroups API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaAlertRuleGroupSpec defines the desired state of GrafanaAlertRuleGroup
properties:
allowCrossNamespaceImport:
default: false
description: Allow the Operator to match this resource with Grafanas outside the current namespace
type: boolean
editable:
description: Whether to enable or disable editing of the alert rule group in Grafana UI
type: boolean
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
folderRef:
description: Match GrafanaFolders CRs to infer the uid
type: string
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
folderUID:
description: |-
UID of the folder containing this rule group
Overrides the FolderSelector
type: string
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
instanceSelector:
description: Selects Grafana instances for import
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: spec.instanceSelector is immutable
rule: self == oldSelf
interval:
format: duration
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
name:
description: Name of the alert rule group. If not specified, the resource name will be used.
type: string
resyncPeriod:
description: How often the resource is synced, defaults to 10m0s if not set
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
rules:
items:
description: AlertRule defines a specific rule to be evaluated. It is based on the upstream model with some k8s specific type mappings
properties:
annotations:
additionalProperties:
type: string
type: object
condition:
type: string
dashboardUid:
description: 'Deprecated: The field is not used, use rules[].annotations.__dashboardUid__'
type: string
data:
items:
properties:
datasourceUid:
description: Grafana data source unique identifier; it should be '__expr__' for a Server Side Expression operation.
type: string
model:
description: JSON is the raw JSON query and includes the above properties as well as custom properties.
x-kubernetes-preserve-unknown-fields: true
queryType:
description: |-
QueryType is an optional identifier for the type of query.
It can be used to distinguish different types of queries.
type: string
refId:
description: RefID is the unique identifier of the query, set by the frontend call.
type: string
relativeTimeRange:
description: relative time range
properties:
from:
description: from
format: int64
type: integer
to:
description: to
format: int64
type: integer
type: object
type: object
type: array
execErrState:
enum:
- OK
- Alerting
- Error
- KeepLast
type: string
for:
default: 0s
pattern: ^([0-9]+(\.[0-9]+)?(s|m|h|d|w))+$
type: string
isPaused:
type: boolean
keepFiringFor:
format: duration
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
labels:
additionalProperties:
type: string
type: object
missingSeriesEvalsToResolve:
description: The number of missing series evaluations that must occur before the rule is considered to be resolved.
format: int64
type: integer
noDataState:
enum:
- Alerting
- NoData
- OK
- KeepLast
type: string
notificationSettings:
properties:
active_time_intervals:
description: ActiveTimeIntervals defines the time intervals during which notifications should NOT be muted.
items:
type: string
type: array
group_by:
description: GroupBy defines the labels by which incoming alerts are grouped together.
items:
type: string
type: array
group_interval:
description: |-
GroupInterval defines how long to wait before sending a notification about new alerts added
to a group for which an initial notification has already been sent. (e.g. 5m)
type: string
group_wait:
description: GroupWait defines how long to initially wait to send a notification for a group of alerts. (e.g. 30s)
type: string
mute_time_intervals:
description: |-
MuteTimeIntervals defines the time intervals during which notifications should be muted.
These must match the name of a mute time interval defined in the Alertmanager configuration.
items:
type: string
type: array
receiver:
description: Receiver is the name of the receiver to send notifications to.
minLength: 1
type: string
repeat_interval:
description: |-
RepeatInterval defines how long to wait before sending a notification again if it has already
been sent successfully for an alert. (e.g. 4h)
Should not be less than GroupInterval.
type: string
required:
- receiver
type: object
panelId:
description: 'Deprecated: The field is not used, use rules[].annotations.__panelId__'
type: integer
record:
properties:
from:
type: string
metric:
type: string
targetDatasourceUid:
type: string
required:
- from
- metric
type: object
title:
example: Always firing
maxLength: 190
minLength: 1
type: string
uid:
description: UID of the alert rule. Can be any string consisting of alphanumeric characters, - and _ with a maximum length of 40
maxLength: 40
pattern: ^[a-zA-Z0-9-_]+$
type: string
required:
- condition
- data
- execErrState
- for
- noDataState
- title
- uid
type: object
minItems: 1
type: array
suspend:
description: Suspend pauses synchronizing attempts and tells the operator to ignore changes
type: boolean
required:
- instanceSelector
- interval
- rules
type: object
x-kubernetes-validations:
- message: Only one of FolderUID or FolderRef can be set and one must be defined
rule: (has(self.folderUID) && !(has(self.folderRef))) || (has(self.folderRef) && !(has(self.folderUID)))
- message: spec.editable is immutable
rule: ((!has(oldSelf.editable) && !has(self.editable)) || (has(oldSelf.editable) && has(self.editable)))
- message: spec.folderUID is immutable
rule: ((!has(oldSelf.folderUID) && !has(self.folderUID)) || (has(oldSelf.folderUID) && has(self.folderUID)))
- message: spec.folderRef is immutable
rule: ((!has(oldSelf.folderRef) && !has(self.folderRef)) || (has(oldSelf.folderRef) && has(self.folderRef)))
- message: disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state
rule: '!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)'
status:
description: The most recent observed state of a Grafana resource
properties:
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,377 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafanacontactpoints.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaContactPoint
listKind: GrafanaContactPointList
plural: grafanacontactpoints
singular: grafanacontactpoint
scope: Namespaced
versions:
- additionalPrinterColumns:
- format: date-time
jsonPath: .status.lastResync
name: Last resync
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaContactPoint is the Schema for the grafanacontactpoints API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaContactPointSpec defines the desired state of GrafanaContactPoint
properties:
allowCrossNamespaceImport:
default: false
description: Allow the Operator to match this resource with Grafanas outside the current namespace
type: boolean
disableResolveMessage:
description: |-
Deprecated: define the receiver under .spec.receivers[]
Will be removed in a later version
type: boolean
editable:
description: Whether to enable or disable editing of the contact point in Grafana UI
type: boolean
x-kubernetes-validations:
- message: spec.editable is immutable
rule: self == oldSelf
instanceSelector:
description: Selects Grafana instances for import
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: spec.instanceSelector is immutable
rule: self == oldSelf
name:
description: |-
Receivers are grouped under the same ContactPoint using the Name
Defaults to the name of the CR
type: string
x-kubernetes-validations:
- message: spec.name is immutable
rule: self == oldSelf
receivers:
description: List of receivers that Grafana will fan out notifications to
items:
description: Represents an integration to external services that receive Grafana notifications
properties:
disableResolveMessage:
type: boolean
settings:
x-kubernetes-preserve-unknown-fields: true
type:
minLength: 1
type: string
uid:
description: Manually specify the UID the Contact Point is created with. Can be any string consisting of alphanumeric characters, - and _ with a maximum length of 40
maxLength: 40
pattern: ^[a-zA-Z0-9-_]+$
type: string
valuesFrom:
items:
properties:
targetPath:
type: string
valueFrom:
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
x-kubernetes-validations:
- message: Either configMapKeyRef or secretKeyRef must be set
rule: (has(self.configMapKeyRef) && !has(self.secretKeyRef)) || (!has(self.configMapKeyRef) && has(self.secretKeyRef))
required:
- targetPath
- valueFrom
type: object
maxItems: 99
type: array
required:
- settings
- type
type: object
maxItems: 99
type: array
resyncPeriod:
description: How often the resource is synced, defaults to 10m0s if not set
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
settings:
description: |-
Deprecated: define the receiver under .spec.receivers[]
Will be removed in a later version
x-kubernetes-preserve-unknown-fields: true
suspend:
description: Suspend pauses synchronizing attempts and tells the operator to ignore changes
type: boolean
type:
description: |-
Deprecated: define the receiver under .spec.receivers[]
Will be removed in a later version
minLength: 1
type: string
uid:
description: |-
Deprecated: define the receiver under .spec.receivers[]
Manually specify the UID the Contact Point is created with. Can be any string consisting of alphanumeric characters, - and _ with a maximum length of 40
maxLength: 40
pattern: ^[a-zA-Z0-9-_]+$
type: string
x-kubernetes-validations:
- message: spec.uid is immutable
rule: self == oldSelf
valuesFrom:
description: |-
Deprecated: define the receiver under .spec.receivers[]
Will be removed in a later version
items:
properties:
targetPath:
type: string
valueFrom:
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
x-kubernetes-validations:
- message: Either configMapKeyRef or secretKeyRef must be set
rule: (has(self.configMapKeyRef) && !has(self.secretKeyRef)) || (!has(self.configMapKeyRef) && has(self.secretKeyRef))
required:
- targetPath
- valueFrom
type: object
maxItems: 99
type: array
required:
- instanceSelector
type: object
x-kubernetes-validations:
- message: spec.name is immutable
rule: ((!has(oldSelf.name) && !has(self.name)) || (has(oldSelf.name) && has(self.name)))
- message: spec.editable is immutable
rule: ((!has(oldSelf.editable) && !has(self.editable)) || (has(oldSelf.editable) && has(self.editable)))
- message: disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state
rule: '!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)'
status:
description: The most recent observed state of a Grafana resource
properties:
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,486 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafanadashboards.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaDashboard
listKind: GrafanaDashboardList
plural: grafanadashboards
singular: grafanadashboard
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .status.NoMatchingInstances
name: No matching instances
type: boolean
- format: date-time
jsonPath: .status.lastResync
name: Last resync
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaDashboard is the Schema for the grafanadashboards API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaDashboardSpec defines the desired state of GrafanaDashboard
properties:
allowCrossNamespaceImport:
default: false
description: Allow the Operator to match this resource with Grafanas outside the current namespace
type: boolean
configMapRef:
description: model from configmap
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
contentCacheDuration:
description: Cache duration for models fetched from URLs
type: string
datasources:
description: maps required data sources to existing ones
items:
description: |-
GrafanaResourceDatasource is used to set the datasource name of any templated datasources in
content definitions (e.g., dashboard JSON).
properties:
datasourceName:
type: string
inputName:
type: string
required:
- datasourceName
- inputName
type: object
type: array
envFrom:
description: environments variables from secrets or config maps
items:
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
type: array
envs:
description: environments variables as a map
items:
properties:
name:
type: string
value:
description: Inline env value
type: string
valueFrom:
description: Reference on value source, might be the reference on a secret or config map
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
required:
- name
type: object
type: array
folder:
description: folder assignment for dashboard
type: string
folderRef:
description: Name of a `GrafanaFolder` resource in the same namespace
type: string
folderUID:
description: UID of the target folder for this dashboard
type: string
grafanaCom:
description: grafana.com/dashboards
properties:
id:
type: integer
revision:
type: integer
required:
- id
type: object
gzipJson:
description: GzipJson the model's JSON compressed with Gzip. Base64-encoded when in YAML.
format: byte
type: string
instanceSelector:
description: Selects Grafana instances for import
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: spec.instanceSelector is immutable
rule: self == oldSelf
json:
description: model json
type: string
jsonnet:
description: Jsonnet
type: string
jsonnetLib:
description: Jsonnet project build
properties:
fileName:
type: string
gzipJsonnetProject:
format: byte
type: string
jPath:
items:
type: string
type: array
required:
- fileName
- gzipJsonnetProject
type: object
plugins:
description: plugins
items:
properties:
name:
minLength: 1
type: string
version:
pattern: ^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?|latest)$
type: string
required:
- name
- version
type: object
type: array
resyncPeriod:
description: How often the resource is synced, defaults to 10m0s if not set
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
suspend:
description: Suspend pauses synchronizing attempts and tells the operator to ignore changes
type: boolean
uid:
description: |-
Manually specify the uid, overwrites uids already present in the json model.
Can be any string consisting of alphanumeric characters, - and _ with a maximum length of 40.
maxLength: 40
pattern: ^[a-zA-Z0-9-_]+$
type: string
x-kubernetes-validations:
- message: spec.uid is immutable
rule: self == oldSelf
url:
description: model url
pattern: ^https?://.+$
type: string
urlAuthorization:
description: authorization options for model from url
properties:
basicAuth:
properties:
password:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
username:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
type: object
required:
- instanceSelector
type: object
x-kubernetes-validations:
- message: Only one of folderUID or folderRef can be declared at the same time
rule: (has(self.folderUID) && !(has(self.folderRef))) || (has(self.folderRef) && !(has(self.folderUID))) || !(has(self.folderRef) && (has(self.folderUID)))
- message: folder field cannot be set when folderUID or folderRef is already declared
rule: (has(self.folder) && !(has(self.folderRef) || has(self.folderUID))) || !(has(self.folder))
- message: spec.uid is immutable
rule: ((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))
- message: disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state
rule: '!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)'
status:
description: GrafanaDashboardStatus defines the observed state of GrafanaDashboard
properties:
NoMatchingInstances:
description: The dashboard instanceSelector can't find matching grafana instances
type: boolean
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
contentCache:
format: byte
type: string
contentTimestamp:
format: date-time
type: string
contentUrl:
type: string
hash:
type: string
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
uid:
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,326 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafanadatasources.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaDatasource
listKind: GrafanaDatasourceList
plural: grafanadatasources
singular: grafanadatasource
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .status.NoMatchingInstances
name: No matching instances
type: boolean
- format: date-time
jsonPath: .status.lastResync
name: Last resync
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaDatasource is the Schema for the grafanadatasources API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaDatasourceSpec defines the desired state of GrafanaDatasource
properties:
allowCrossNamespaceImport:
default: false
description: Allow the Operator to match this resource with Grafanas outside the current namespace
type: boolean
datasource:
properties:
access:
type: string
basicAuth:
type: boolean
basicAuthUser:
type: string
database:
type: string
editable:
description: Whether to enable/disable editing of the datasource in Grafana UI
type: boolean
isDefault:
type: boolean
jsonData:
type: object
x-kubernetes-preserve-unknown-fields: true
name:
type: string
orgId:
description: Deprecated field, it has no effect
format: int64
type: integer
secureJsonData:
type: object
x-kubernetes-preserve-unknown-fields: true
type:
type: string
uid:
description: Deprecated field, use spec.uid instead
type: string
url:
type: string
user:
type: string
type: object
instanceSelector:
description: Selects Grafana instances for import
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: spec.instanceSelector is immutable
rule: self == oldSelf
plugins:
description: plugins
items:
properties:
name:
minLength: 1
type: string
version:
pattern: ^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?|latest)$
type: string
required:
- name
- version
type: object
type: array
resyncPeriod:
description: How often the resource is synced, defaults to 10m0s if not set
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
suspend:
description: Suspend pauses synchronizing attempts and tells the operator to ignore changes
type: boolean
uid:
description: |-
The UID, for the datasource, fallback to the deprecated spec.datasource.uid
and metadata.uid. Can be any string consisting of alphanumeric characters,
- and _ with a maximum length of 40 +optional
maxLength: 40
pattern: ^[a-zA-Z0-9-_]+$
type: string
x-kubernetes-validations:
- message: spec.uid is immutable
rule: self == oldSelf
valuesFrom:
description: environments variables from secrets or config maps
items:
properties:
targetPath:
type: string
valueFrom:
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
x-kubernetes-validations:
- message: Either configMapKeyRef or secretKeyRef must be set
rule: (has(self.configMapKeyRef) && !has(self.secretKeyRef)) || (!has(self.configMapKeyRef) && has(self.secretKeyRef))
required:
- targetPath
- valueFrom
type: object
maxItems: 99
type: array
required:
- datasource
- instanceSelector
type: object
x-kubernetes-validations:
- message: spec.uid is immutable
rule: ((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))
- message: disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state
rule: '!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)'
status:
description: GrafanaDatasourceStatus defines the observed state of GrafanaDatasource
properties:
NoMatchingInstances:
description: The datasource instanceSelector can't find matching grafana instances
type: boolean
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
hash:
type: string
lastMessage:
description: 'Deprecated: Check status.conditions or operator logs'
type: string
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
uid:
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,217 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafanafolders.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaFolder
listKind: GrafanaFolderList
plural: grafanafolders
singular: grafanafolder
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .status.NoMatchingInstances
name: No matching instances
type: boolean
- format: date-time
jsonPath: .status.lastResync
name: Last resync
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaFolder is the Schema for the grafanafolders API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaFolderSpec defines the desired state of GrafanaFolder
properties:
allowCrossNamespaceImport:
default: false
description: Allow the Operator to match this resource with Grafanas outside the current namespace
type: boolean
instanceSelector:
description: Selects Grafana instances for import
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: spec.instanceSelector is immutable
rule: self == oldSelf
parentFolderRef:
description: Reference to an existing GrafanaFolder CR in the same namespace
type: string
parentFolderUID:
description: UID of the folder in which the current folder should be created
type: string
permissions:
description: Raw json with folder permissions, potentially exported from Grafana
type: string
resyncPeriod:
description: How often the resource is synced, defaults to 10m0s if not set
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
suspend:
description: Suspend pauses synchronizing attempts and tells the operator to ignore changes
type: boolean
title:
description: Display name of the folder in Grafana
type: string
uid:
description: Manually specify the UID the Folder is created with. Can be any string consisting of alphanumeric characters, - and _ with a maximum length of 40
maxLength: 40
pattern: ^[a-zA-Z0-9-_]+$
type: string
x-kubernetes-validations:
- message: spec.uid is immutable
rule: self == oldSelf
required:
- instanceSelector
type: object
x-kubernetes-validations:
- message: Only one of parentFolderUID or parentFolderRef can be set
rule: (has(self.parentFolderUID) && !(has(self.parentFolderRef))) || (has(self.parentFolderRef) && !(has(self.parentFolderUID))) || !(has(self.parentFolderRef) && (has(self.parentFolderUID)))
- message: spec.uid is immutable
rule: ((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))
- message: disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state
rule: '!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)'
status:
description: GrafanaFolderStatus defines the observed state of GrafanaFolder
properties:
NoMatchingInstances:
description: The folder instanceSelector can't find matching grafana instances
type: boolean
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
hash:
type: string
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,475 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafanalibrarypanels.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaLibraryPanel
listKind: GrafanaLibraryPanelList
plural: grafanalibrarypanels
singular: grafanalibrarypanel
scope: Namespaced
versions:
- additionalPrinterColumns:
- format: date-time
jsonPath: .status.lastResync
name: Last resync
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaLibraryPanel is the Schema for the grafanalibrarypanels API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaLibraryPanelSpec defines the desired state of GrafanaLibraryPanel
properties:
allowCrossNamespaceImport:
default: false
description: Allow the Operator to match this resource with Grafanas outside the current namespace
type: boolean
configMapRef:
description: model from configmap
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
contentCacheDuration:
description: Cache duration for models fetched from URLs
type: string
datasources:
description: maps required data sources to existing ones
items:
description: |-
GrafanaResourceDatasource is used to set the datasource name of any templated datasources in
content definitions (e.g., dashboard JSON).
properties:
datasourceName:
type: string
inputName:
type: string
required:
- datasourceName
- inputName
type: object
type: array
envFrom:
description: environments variables from secrets or config maps
items:
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
type: array
envs:
description: environments variables as a map
items:
properties:
name:
type: string
value:
description: Inline env value
type: string
valueFrom:
description: Reference on value source, might be the reference on a secret or config map
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
required:
- name
type: object
type: array
folderRef:
description: Name of a `GrafanaFolder` resource in the same namespace
type: string
folderUID:
description: UID of the target folder for this dashboard
type: string
grafanaCom:
description: grafana.com/dashboards
properties:
id:
type: integer
revision:
type: integer
required:
- id
type: object
gzipJson:
description: GzipJson the model's JSON compressed with Gzip. Base64-encoded when in YAML.
format: byte
type: string
instanceSelector:
description: Selects Grafana instances for import
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: spec.instanceSelector is immutable
rule: self == oldSelf
json:
description: model json
type: string
jsonnet:
description: Jsonnet
type: string
jsonnetLib:
description: Jsonnet project build
properties:
fileName:
type: string
gzipJsonnetProject:
format: byte
type: string
jPath:
items:
type: string
type: array
required:
- fileName
- gzipJsonnetProject
type: object
plugins:
description: plugins
items:
properties:
name:
minLength: 1
type: string
version:
pattern: ^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?|latest)$
type: string
required:
- name
- version
type: object
type: array
resyncPeriod:
description: How often the resource is synced, defaults to 10m0s if not set
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
suspend:
description: Suspend pauses synchronizing attempts and tells the operator to ignore changes
type: boolean
uid:
description: |-
Manually specify the uid, overwrites uids already present in the json model.
Can be any string consisting of alphanumeric characters, - and _ with a maximum length of 40.
maxLength: 40
pattern: ^[a-zA-Z0-9-_]+$
type: string
x-kubernetes-validations:
- message: spec.uid is immutable
rule: self == oldSelf
url:
description: model url
pattern: ^https?://.+$
type: string
urlAuthorization:
description: authorization options for model from url
properties:
basicAuth:
properties:
password:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
username:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
type: object
required:
- instanceSelector
type: object
x-kubernetes-validations:
- message: Only one of folderUID or folderRef can be declared at the same time
rule: (has(self.folderUID) && !(has(self.folderRef))) || (has(self.folderRef) && !(has(self.folderUID))) || !(has(self.folderRef) && (has(self.folderUID)))
- message: spec.uid is immutable
rule: ((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))
- message: disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state
rule: '!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)'
status:
description: GrafanaLibraryPanelStatus defines the observed state of GrafanaLibraryPanel
properties:
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
contentCache:
format: byte
type: string
contentTimestamp:
format: date-time
type: string
contentUrl:
type: string
hash:
type: string
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
uid:
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,315 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafanamanifests.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaManifest
listKind: GrafanaManifestList
plural: grafanamanifests
singular: grafanamanifest
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.template.kind
name: Kind
type: string
- format: date-time
jsonPath: .status.lastResync
name: Last resync
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaManifest is the Schema for the grafana manifests
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaManifestSpec defines the desired state of a GrafanaManifest
properties:
allowCrossNamespaceImport:
default: false
description: Allow the Operator to match this resource with Grafanas outside the current namespace
type: boolean
instanceSelector:
description: Selects Grafana instances for import
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: spec.instanceSelector is immutable
rule: self == oldSelf
patch:
properties:
env:
items:
properties:
name:
type: string
valueFrom:
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
grafanaRef:
description: ObjectFieldSelector selects an APIVersioned field of an object.
properties:
apiVersion:
description: Version of the schema the FieldPath is written in terms of, defaults to "v1".
type: string
fieldPath:
description: Path of the field to select in the specified API version.
type: string
required:
- fieldPath
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
required:
- name
- valueFrom
type: object
type: array
scripts:
items:
type: string
type: array
required:
- scripts
type: object
resyncPeriod:
description: How often the resource is synced, defaults to 10m0s if not set
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
suspend:
description: Suspend pauses synchronizing attempts and tells the operator to ignore changes
type: boolean
template:
properties:
apiVersion:
description: APIVersion defines the versioned schema of this representation of an object.
type: string
kind:
description: Kind is a string value representing the REST resource this object represents.
type: string
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
metadata:
description: |-
RequiredObjectMeta contains only a [subset of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#objectmeta-v1-meta).
It requires `name` to be set
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
name:
type: string
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
namespace:
type: string
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
required:
- name
type: object
x-kubernetes-validations:
- message: namespace is immutable
rule: ((!has(oldSelf.__namespace__) && !has(self.__namespace__)) || (has(oldSelf.__namespace__) && has(self.__namespace__)))
spec:
x-kubernetes-preserve-unknown-fields: true
required:
- apiVersion
- kind
- metadata
type: object
required:
- instanceSelector
- template
type: object
x-kubernetes-validations:
- message: disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state
rule: '!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)'
status:
description: GrafanaManifestStatus defines the observed state of GrafanaManifest
properties:
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,250 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafanamutetimings.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaMuteTiming
listKind: GrafanaMuteTimingList
plural: grafanamutetimings
singular: grafanamutetiming
scope: Namespaced
versions:
- additionalPrinterColumns:
- format: date-time
jsonPath: .status.lastResync
name: Last resync
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaMuteTiming is the Schema for the GrafanaMuteTiming API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaMuteTimingSpec defines the desired state of GrafanaMuteTiming
properties:
allowCrossNamespaceImport:
default: false
description: Allow the Operator to match this resource with Grafanas outside the current namespace
type: boolean
editable:
default: true
description: Whether to enable or disable editing of the mute timing in Grafana UI
type: boolean
x-kubernetes-validations:
- message: spec.editable is immutable
rule: self == oldSelf
instanceSelector:
description: Selects Grafana instances for import
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: spec.instanceSelector is immutable
rule: self == oldSelf
name:
description: A unique name for the mute timing
type: string
resyncPeriod:
description: How often the resource is synced, defaults to 10m0s if not set
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
suspend:
description: Suspend pauses synchronizing attempts and tells the operator to ignore changes
type: boolean
time_intervals:
description: Time intervals for muting
items:
properties:
days_of_month:
description: |-
The date 1-31 of a month. Negative values can also be used to represent days that begin at the end of the month.
For example: -1 for the last day of the month.
items:
type: string
type: array
location:
description: Depending on the location, the time range is displayed in local time.
type: string
months:
description: |-
The months of the year in either numerical or the full calendar month.
For example: 1, may.
items:
type: string
type: array
times:
description: The time inclusive of the start and exclusive of the end time (in UTC if no location has been selected, otherwise local time).
items:
properties:
end_time:
description: end time
type: string
start_time:
description: start time
type: string
required:
- end_time
- start_time
type: object
type: array
weekdays:
description: |-
The day or range of days of the week.
For example: monday, thursday
items:
type: string
type: array
years:
description: |-
The year or years for the interval.
For example: 2021
items:
type: string
type: array
type: object
minItems: 1
type: array
required:
- instanceSelector
- name
- time_intervals
type: object
x-kubernetes-validations:
- message: disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state
rule: '!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)'
status:
description: The most recent observed state of a Grafana resource
properties:
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,337 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafananotificationpolicies.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaNotificationPolicy
listKind: GrafanaNotificationPolicyList
plural: grafananotificationpolicies
singular: grafananotificationpolicy
scope: Namespaced
versions:
- additionalPrinterColumns:
- format: date-time
jsonPath: .status.lastResync
name: Last resync
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaNotificationPolicy is the Schema for the GrafanaNotificationPolicy API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaNotificationPolicySpec defines the desired state of GrafanaNotificationPolicy
properties:
allowCrossNamespaceImport:
default: false
description: Allow the Operator to match this resource with Grafanas outside the current namespace
type: boolean
editable:
description: Whether to enable or disable editing of the notification policy in Grafana UI
type: boolean
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
instanceSelector:
description: Selects Grafana instances for import
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: spec.instanceSelector is immutable
rule: self == oldSelf
resyncPeriod:
description: How often the resource is synced, defaults to 10m0s if not set
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
route:
description: Routes for alerts to match against
properties:
active_time_intervals:
description: 'Deprecated: Never worked on the top level route node'
items:
type: string
type: array
continue:
description: 'Deprecated: Never worked on the top level route node'
type: boolean
group_by:
description: group by
items:
type: string
type: array
group_interval:
description: group interval
type: string
group_wait:
description: group wait
type: string
match_re:
additionalProperties:
type: string
description: 'Deprecated: Never worked on the top level route node'
type: object
matchers:
description: 'Deprecated: Never worked on the top level route node'
items:
properties:
isEqual:
description: is equal
type: boolean
isRegex:
description: is regex
type: boolean
name:
description: name
type: string
value:
description: value
type: string
required:
- isRegex
- value
type: object
type: array
mute_time_intervals:
description: 'Deprecated: Never worked on the top level route node'
items:
type: string
type: array
object_matchers:
description: 'Deprecated: Never worked on the top level route node'
items:
description: |-
ObjectMatcher ObjectMatcher is a matcher that can be used to filter alerts.
swagger:model ObjectMatcher
items:
type: string
type: array
type: array
provenance:
description: 'Deprecated: Does nothing'
type: string
receiver:
description: receiver
minLength: 1
type: string
repeat_interval:
description: repeat interval
type: string
routeSelector:
description: |-
selects GrafanaNotificationPolicyRoutes to merge in when specified
mutually exclusive with Routes
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
routes:
description: routes, mutually exclusive with RouteSelector
x-kubernetes-preserve-unknown-fields: true
required:
- receiver
type: object
x-kubernetes-validations:
- message: continue is invalid on the top level route node
rule: '!has(self.__continue__)'
- message: match_re is invalid on the top level route node
rule: '!has(self.match_re)'
- message: matchers is invalid on the top level route node
rule: '!has(self.matchers)'
- message: object_matchers is invalid on the top level route node
rule: '!has(self.object_matchers)'
- message: mute_time_intervals is invalid on the top level route node
rule: '!has(self.mute_time_intervals)'
- message: active_time_intervals is invalid on the top level route node
rule: '!has(self.active_time_intervals)'
suspend:
description: Suspend pauses synchronizing attempts and tells the operator to ignore changes
type: boolean
required:
- instanceSelector
- route
type: object
x-kubernetes-validations:
- message: spec.editable is immutable
rule: ((!has(oldSelf.editable) && !has(self.editable)) || (has(oldSelf.editable) && has(self.editable)))
- message: disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state
rule: '!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)'
status:
description: GrafanaNotificationPolicyStatus defines the observed state of GrafanaNotificationPolicy
properties:
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
discoveredRoutes:
items:
type: string
type: array
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,236 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafananotificationpolicyroutes.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaNotificationPolicyRoute
listKind: GrafanaNotificationPolicyRouteList
plural: grafananotificationpolicyroutes
singular: grafananotificationpolicyroute
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaNotificationPolicyRoute is the Schema for the grafananotificationpolicyroutes API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaNotificationPolicyRouteSpec defines the desired state of GrafanaNotificationPolicyRoute
properties:
active_time_intervals:
description: active time intervals
items:
type: string
type: array
continue:
description: continue
type: boolean
group_by:
description: group by
items:
type: string
type: array
group_interval:
description: group interval
type: string
group_wait:
description: group wait
type: string
match_re:
additionalProperties:
type: string
description: match re
type: object
matchers:
description: matchers
items:
properties:
isEqual:
description: is equal
type: boolean
isRegex:
description: is regex
type: boolean
name:
description: name
type: string
value:
description: value
type: string
required:
- isRegex
- value
type: object
type: array
mute_time_intervals:
description: mute time intervals
items:
type: string
type: array
object_matchers:
description: object matchers
items:
description: |-
ObjectMatcher ObjectMatcher is a matcher that can be used to filter alerts.
swagger:model ObjectMatcher
items:
type: string
type: array
type: array
provenance:
description: 'Deprecated: Does nothing'
type: string
receiver:
description: receiver
minLength: 1
type: string
repeat_interval:
description: repeat interval
type: string
routeSelector:
description: |-
selects GrafanaNotificationPolicyRoutes to merge in when specified
mutually exclusive with Routes
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
routes:
description: routes, mutually exclusive with RouteSelector
x-kubernetes-preserve-unknown-fields: true
required:
- receiver
type: object
status:
description: The most recent observed state of a Grafana resource
properties:
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,200 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafananotificationtemplates.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaNotificationTemplate
listKind: GrafanaNotificationTemplateList
plural: grafananotificationtemplates
singular: grafananotificationtemplate
scope: Namespaced
versions:
- additionalPrinterColumns:
- format: date-time
jsonPath: .status.lastResync
name: Last resync
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaNotificationTemplate is the Schema for the GrafanaNotificationTemplate API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaNotificationTemplateSpec defines the desired state of GrafanaNotificationTemplate
properties:
allowCrossNamespaceImport:
default: false
description: Allow the Operator to match this resource with Grafanas outside the current namespace
type: boolean
editable:
description: Whether to enable or disable editing of the notification template in Grafana UI
type: boolean
x-kubernetes-validations:
- message: spec.editable is immutable
rule: self == oldSelf
instanceSelector:
description: Selects Grafana instances for import
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: spec.instanceSelector is immutable
rule: self == oldSelf
name:
description: Template name
type: string
resyncPeriod:
description: How often the resource is synced, defaults to 10m0s if not set
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
suspend:
description: Suspend pauses synchronizing attempts and tells the operator to ignore changes
type: boolean
template:
description: Template content
type: string
required:
- instanceSelector
- name
type: object
x-kubernetes-validations:
- message: spec.editable is immutable
rule: ((!has(oldSelf.editable) && !has(self.editable)) || (has(oldSelf.editable) && has(self.editable)))
- message: disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state
rule: '!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)'
status:
description: The most recent observed state of a Grafana resource
properties:
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,241 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
name: grafanaserviceaccounts.grafana.integreatly.org
spec:
group: grafana.integreatly.org
names:
categories:
- grafana-operator
kind: GrafanaServiceAccount
listKind: GrafanaServiceAccountList
plural: grafanaserviceaccounts
singular: grafanaserviceaccount
scope: Namespaced
versions:
- additionalPrinterColumns:
- format: date-time
jsonPath: .status.lastResync
name: Last resync
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: GrafanaServiceAccount is the Schema for the grafanaserviceaccounts API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GrafanaServiceAccountSpec defines the desired state of a GrafanaServiceAccount.
properties:
instanceName:
description: Name of the Grafana instance to create the service account for
minLength: 1
type: string
x-kubernetes-validations:
- message: spec.instanceName is immutable
rule: self == oldSelf
isDisabled:
default: false
description: Whether the service account is disabled
type: boolean
name:
description: Name of the service account in Grafana
minLength: 1
type: string
x-kubernetes-validations:
- message: spec.name is immutable
rule: self == oldSelf
resyncPeriod:
description: How often the resource is synced, defaults to 10m0s if not set
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
type: string
x-kubernetes-validations:
- message: spec.resyncPeriod must be greater than 0
rule: duration(self) > duration('0s')
role:
description: Role of the service account (Viewer, Editor, Admin)
enum:
- Viewer
- Editor
- Admin
type: string
suspend:
default: false
description: Suspend pauses reconciliation of the service account
type: boolean
tokens:
description: Tokens to create for the service account
items:
description: GrafanaServiceAccountTokenSpec defines a token for a service account
properties:
expires:
description: Expiration date of the token. If not set, the token never expires
format: date-time
type: string
name:
description: Name of the token
minLength: 1
type: string
secretName:
description: Name of the secret to store the token. If not set, a name will be generated
minLength: 1
type: string
required:
- name
type: object
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
required:
- instanceName
- role
type: object
x-kubernetes-validations:
- message: spec.name is immutable
rule: ((!has(oldSelf.name) && !has(self.name)) || (has(oldSelf.name) && has(self.name)))
status:
description: GrafanaServiceAccountStatus defines the observed state of a GrafanaServiceAccount
properties:
account:
description: Info contains the Grafana service account information
properties:
id:
description: ID of the service account in Grafana
format: int64
type: integer
isDisabled:
description: IsDisabled indicates if the service account is disabled
type: boolean
login:
type: string
name:
type: string
role:
description: Role is the Grafana role for the service account (Viewer, Editor, Admin)
type: string
tokens:
description: Information about tokens
items:
description: GrafanaServiceAccountTokenStatus describes a token created in Grafana.
properties:
expires:
description: |-
Expiration time of the token
N.B. There's possible discrepancy with the expiration time in spec
It happens because Grafana API accepts TTL in seconds then calculates the expiration time against the current time
format: date-time
type: string
id:
description: ID of the token in Grafana
format: int64
type: integer
name:
type: string
secret:
description: Name of the secret containing the token
properties:
name:
type: string
namespace:
type: string
type: object
required:
- id
- name
type: object
type: array
required:
- id
- isDisabled
- login
- name
- role
type: object
conditions:
description: Results when synchronizing resource with Grafana instances
items:
description: Condition contains details for one aspect of the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastResync:
description: Last time the resource was synchronized with Grafana instances
format: date-time
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,113 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana-operator-valkey-remote-cache
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
spec:
replicas: 1
strategy:
type: RollingUpdate
selector:
matchLabels:
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
template:
metadata:
labels:
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
annotations:
checksum/initconfig: d790dfe3185267fe6c217c9572cfa9fb
spec:
automountServiceAccountToken: false
serviceAccountName: grafana-operator-valkey-remote-cache
securityContext:
fsGroup: 1000
runAsGroup: 1000
runAsUser: 1000
initContainers:
- name: grafana-operator-valkey-remote-cache-init
image: docker.io/valkey/valkey:9.0.3
imagePullPolicy: IfNotPresent
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
command: ["/scripts/init.sh"]
volumeMounts:
- name: valkey-data
mountPath: /data
- name: scripts
mountPath: /scripts
containers:
- name: grafana-operator-valkey-remote-cache
image: docker.io/valkey/valkey:9.0.3
imagePullPolicy: IfNotPresent
command: ["valkey-server"]
args: ["/data/conf/valkey.conf"]
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
env:
- name: VALKEY_LOGLEVEL
value: "notice"
ports:
- name: tcp
containerPort: 6379
protocol: TCP
startupProbe:
exec:
command: ["sh", "-c", "valkey-cli ping"]
livenessProbe:
exec:
command: ["sh", "-c", "valkey-cli ping"]
resources:
requests:
cpu: 10m
memory: 20Mi
volumeMounts:
- name: valkey-data
mountPath: /data
- name: metrics
image: ghcr.io/oliver006/redis_exporter:v1.82.0
imagePullPolicy: "IfNotPresent"
ports:
- name: metrics
containerPort: 9121
startupProbe:
tcpSocket:
port: metrics
livenessProbe:
tcpSocket:
port: metrics
readinessProbe:
httpGet:
path: /
port: metrics
resources:
requests:
cpu: 1m
memory: 10M
env:
- name: REDIS_ALIAS
value: grafana-operator-valkey-remote-cache
volumes:
- name: scripts
configMap:
name: grafana-operator-valkey-remote-cache-init-scripts
defaultMode: 0555
- name: valkey-data
persistentVolumeClaim:
claimName: grafana-operator-valkey-remote-cache

View File

@@ -0,0 +1,98 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana-operator
namespace: grafana-operator
labels:
helm.sh/chart: grafana-operator-5.22.2
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "v5.22.2"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/component: operator
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator
template:
metadata:
labels:
helm.sh/chart: grafana-operator-5.22.2
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "v5.22.2"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/component: operator
spec:
serviceAccountName: grafana-operator
containers:
- name: grafana-operator
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
image: "ghcr.io/grafana/grafana-operator:v5.22.2@sha256:d45fc24e8f43d83286d81625ee8d919d0fc88255a6500b63f68d7966a4f9e9af"
imagePullPolicy: IfNotPresent
env:
- name: WATCH_NAMESPACE
value: ""
- name: WATCH_NAMESPACE_SELECTOR
value: ""
- name: WATCH_LABEL_SELECTORS
value: ""
- name: ENFORCE_CACHE_LABELS
value: "safe"
- name: CLUSTER_DOMAIN
value: ""
args:
- --health-probe-bind-address=:8081
- --metrics-bind-address=0.0.0.0:9090
- --pprof-addr=0.0.0.0:8888
- --zap-encoder=console
- --zap-log-level=info
- --zap-time-encoding=rfc3339
- --default-resync-period=10m
- --leader-elect
- --max-concurrent-reconciles=1
volumeMounts:
- name: dashboards-dir
mountPath: /tmp/dashboards
- name: kubeauth-token-volume
mountPath: /var/run/secrets/grafana.com/serviceaccount
readOnly: true
ports:
- containerPort: 9090
name: metrics
protocol: TCP
- containerPort: 8888
name: pprof
protocol: TCP
livenessProbe:
httpGet:
path: /healthz
port: 8081
readinessProbe:
httpGet:
path: /readyz
port: 8081
resources:
requests:
cpu: 1m
memory: 50Mi
volumes:
- name: dashboards-dir
emptyDir: {}
- name: kubeauth-token-volume
projected:
sources:
- serviceAccountToken:
audience: operator.grafana.com
expirationSeconds: 3600
path: token

View File

@@ -0,0 +1,22 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: grafana-auth-secret
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-auth-secret
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: admin-user
remoteRef:
key: /cl01tl/grafana/auth
property: admin-user
- secretKey: admin-password
remoteRef:
key: /cl01tl/grafana/auth
property: admin-password

View File

@@ -0,0 +1,22 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: grafana-oauth-secret
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-oauth-secret
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: AUTH_CLIENT_ID
remoteRef:
key: /authentik/oidc/grafana
property: client
- secretKey: AUTH_CLIENT_SECRET
remoteRef:
key: /authentik/oidc/grafana
property: secret

View File

@@ -0,0 +1,38 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: grafana-operator-postgresql-18-backup-garage-local-secret
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-operator-postgresql-18-backup-garage-local-secret
helm.sh/chart: postgres-18-cluster-7.11.2
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/version: "7.11.2"
app.kubernetes.io/managed-by: Helm
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ACCESS_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /garage/home-infra/postgres-backups
metadataPolicy: None
property: ACCESS_REGION
- secretKey: ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /garage/home-infra/postgres-backups
metadataPolicy: None
property: ACCESS_KEY_ID
- secretKey: ACCESS_SECRET_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /garage/home-infra/postgres-backups
metadataPolicy: None
property: ACCESS_SECRET_KEY

View File

@@ -0,0 +1,26 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: grafana-operator-postgresql-18-cluster-backup-secret-garage
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-operator-postgresql-18-cluster-backup-secret-garage
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ACCESS_KEY_ID
remoteRef:
key: /garage/home-infra/postgres-backups
property: ACCESS_KEY_ID
- secretKey: ACCESS_SECRET_KEY
remoteRef:
key: /garage/home-infra/postgres-backups
property: ACCESS_SECRET_KEY
- secretKey: ACCESS_REGION
remoteRef:
key: /garage/home-infra/postgres-backups
property: ACCESS_REGION

View File

@@ -0,0 +1,22 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: grafana-operator-postgresql-18-cluster-backup-secret
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-operator-postgresql-18-cluster-backup-secret
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ACCESS_KEY_ID
remoteRef:
key: /digital-ocean/home-infra/postgres-backups
property: access
- secretKey: ACCESS_SECRET_KEY
remoteRef:
key: /digital-ocean/home-infra/postgres-backups
property: secret

View File

@@ -0,0 +1,38 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: grafana-operator-postgresql-18-recovery-secret
namespace: grafana-operator
labels:
helm.sh/chart: postgres-18-cluster-7.11.2
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/version: "7.11.2"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: grafana-operator-postgresql-18-recovery-secret
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ACCESS_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /garage/home-infra/postgres-backups
metadataPolicy: None
property: ACCESS_REGION
- secretKey: ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /garage/home-infra/postgres-backups
metadataPolicy: None
property: ACCESS_KEY_ID
- secretKey: ACCESS_SECRET_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /garage/home-infra/postgres-backups
metadataPolicy: None
property: ACCESS_SECRET_KEY

View File

@@ -0,0 +1,118 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: Grafana
metadata:
name: grafana-main
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-main
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
app: grafana-main
spec:
config:
analytics:
enabled: "false"
check_for_updates: "false"
reporting_enabled: "false"
server:
domain: alexlebens.net
root_url: https://grafana.alexlebens.net
log:
mode: "console"
users:
auto_assign_org: "true"
auto_assign_org_id: "1"
auth:
disable_login_form: "true"
auto_login: "true"
signout_redirect_url: https://authentik.alexlebens.net/application/o/grafana/end-session/
auth.generic_oauth:
enabled: "true"
name: Authentik
allow_sign_up: "true"
client_id: ${AUTH_CLIENT_ID}
client_secret: ${AUTH_CLIENT_SECRET}
scopes: openid profile email
auth_url: https://authentik.alexlebens.net/application/o/authorize/
token_url: https://authentik.alexlebens.net/application/o/token/
api_url: https://authentik.alexlebens.net/application/o/userinfo/
role_attribute_path: contains(groups, 'Grafana Admins') && 'Admin' || contains(groups, 'Grafana Editors') && 'Editor' || 'Viewer'
database:
type: postgres
host: "${DB_HOST}:${DB_PORT}"
name: ${DB_DATABASE}
user: ${DB_USER}
password: ${DB_PASSWORD}
remote_cache:
type: redis
connstr: addr=grafana-operator-valkey-remote-cache.grafana-operator:6379,pool_size=100,db=0,ssl=false
unified_alerting:
enabled: "true"
ha_redis_address: grafana-operator-valkey-unified-alerting.grafana-operator:6379
deployment:
spec:
replicas: 3
template:
spec:
containers:
- name: grafana
image: grafana/grafana:12.4.2@sha256:83749231c3835e390a3144e5e940203e42b9589761f20ef3169c716e734ad505
resources:
requests:
cpu: 20m
memory: 150Mi
env:
- name: AUTH_CLIENT_ID
valueFrom:
secretKeyRef:
name: grafana-oauth-secret
key: AUTH_CLIENT_ID
- name: AUTH_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: grafana-oauth-secret
key: AUTH_CLIENT_SECRET
- name: ADMIN_USER
valueFrom:
secretKeyRef:
name: grafana-auth-secret
key: admin-user
- name: ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: grafana-auth-secret
key: admin-password
- name: DB_HOST
valueFrom:
secretKeyRef:
name: grafana-operator-postgresql-18-cluster-app
key: host
- name: DB_DATABASE
valueFrom:
secretKeyRef:
name: grafana-operator-postgresql-18-cluster-app
key: dbname
- name: DB_PORT
valueFrom:
secretKeyRef:
name: grafana-operator-postgresql-18-cluster-app
key: port
- name: DB_USER
valueFrom:
secretKeyRef:
name: grafana-operator-postgresql-18-cluster-app
key: user
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: grafana-operator-postgresql-18-cluster-app
key: password
httpRoute:
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- grafana.alexlebens.net

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-airgradient
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-airgradient
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-iot
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/iot/airgradient.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-argocd
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-argocd
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/argocd.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-authentik
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-authentik
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-platform
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/platform/authentik.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-blocky
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-blocky
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/blocky.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-ceph
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-ceph
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-system
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/system/ceph.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-cert-manager
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-cert-manager
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/cert-manager.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-cloudnative-pg
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-cloudnative-pg
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/cloudnative-pg.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-coredns
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-coredns
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-system
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/system/coredns.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-descheduler
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-descheduler
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/descheduler.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-etcd
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-etcd
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-system
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/system/etcd.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-garage
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-garage
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-system
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/system/garage.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-gatus
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-gatus
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/gatus.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-gitea
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-gitea
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-platform
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/platform/gitea.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-harbor
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-harbor
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/harbor.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-immich
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-immich
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-application
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/application/immich.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-jellyfin
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-jellyfin
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-application
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/application/jellyfin.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-loki
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-loki
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-system
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/system/loki.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-node-full
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-node-full
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-system
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/system/node-full.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-node-short
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-node-short
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-system
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/system/node-short.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-ntfy
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-ntfy
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-platform
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/platform/ntfy.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-operator
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-operator
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/grafana-operator.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-pods
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-pods
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-system
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/system/pods.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-qbittorrent
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-qbittorrent
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-platform
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/platform/qbittorrent.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-radarr
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-radarr
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-application
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/application/radarr.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-s3
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-s3
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-platform
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/platform/s3.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-server-power-consumption
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-server-power-consumption
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-iot
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/iot/server-power-consumption.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-sonarr
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-sonarr
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-application
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/application/sonarr.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-speedtest-exporter
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-speedtest-exporter
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/speedtest-exporter.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-spegel
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-spegel
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/spegel.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-tdarr
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-tdarr
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/tdarr.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-traefik
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-traefik
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/traefik.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-unpoller
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-unpoller
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/unpoller.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-vault
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-vault
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-platform
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/platform/vault.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-version-checker-internal
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-version-checker-internal
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/version-checker-internal.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-version-checker
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-version-checker
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/version-checker.json

View File

@@ -0,0 +1,17 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-dashboard-volsync
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-dashboard-volsync
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
contentCacheDuration: 6h
folderUID: grafana-folder-service
resyncPeriod: 6h
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/volsync.json

View File

@@ -0,0 +1,20 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDatasource
metadata:
name: grafana-datasource-loki
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-datasource-loki
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
datasource:
name: Loki
type: loki
url: http://loki.loki:3100/
access: proxy
instanceSelector:
matchLabels:
app: grafana-main
resyncPeriod: 30s
uid: loki

View File

@@ -0,0 +1,26 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDatasource
metadata:
name: grafana-datasource-prometheus
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-datasource-prometheus
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
datasource:
name: Prometheus
type: prometheus
url: http://kube-prometheus-stack-prometheus.kube-prometheus-stack:9090/
access: proxy
isDefault: true
jsonData:
timeInterval: 30s
instanceSelector:
matchLabels:
app: grafana-main
plugins:
- name: camptocamp-prometheus-alertmanager-datasource
version: 2.1.0
resyncPeriod: 30s
uid: kube-prometheus-stack

View File

@@ -0,0 +1,33 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
name: grafana-folder-application
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-folder-application
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
title: Application
uid: grafana-folder-application
resyncPeriod: 30s
permissions: |
{
"items": [
{
"role": "Admin",
"permission": 4
},
{
"role": "Editor",
"permission": 2
},
{
"role": "Viewer",
"permission": 1
}
]
}

View File

@@ -0,0 +1,33 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
name: grafana-folder-iot
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-folder-iot
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
title: IoT
uid: grafana-folder-iot
resyncPeriod: 30s
permissions: |
{
"items": [
{
"role": "Admin",
"permission": 4
},
{
"role": "Editor",
"permission": 2
},
{
"role": "Viewer",
"permission": 1
}
]
}

View File

@@ -0,0 +1,33 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
name: grafana-folder-platform
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-folder-platform
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
title: Platform
uid: grafana-folder-platform
resyncPeriod: 30s
permissions: |
{
"items": [
{
"role": "Admin",
"permission": 4
},
{
"role": "Editor",
"permission": 2
},
{
"role": "Viewer",
"permission": 1
}
]
}

View File

@@ -0,0 +1,33 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
name: grafana-folder-service
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-folder-service
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app: grafana-main
title: Service
uid: grafana-folder-service
resyncPeriod: 30s
permissions: |
{
"items": [
{
"role": "Admin",
"permission": 4
},
{
"role": "Editor",
"permission": 2
},
{
"role": "Viewer",
"permission": 1
}
]
}

View File

@@ -0,0 +1,33 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
name: grafana-folder-system
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-folder-system
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
spec:
instanceSelector:
matchLabels:
app.kubernetes.io/name: grafana-main
title: System
uid: grafana-folder-system
resyncPeriod: 30s
permissions: |
{
"items": [
{
"role": "Admin",
"permission": 4
},
{
"role": "Editor",
"permission": 2
},
{
"role": "Viewer",
"permission": 1
}
]
}

View File

@@ -0,0 +1,33 @@
apiVersion: barmancloud.cnpg.io/v1
kind: ObjectStore
metadata:
name: grafana-operator-postgresql-18-backup-garage-local
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-operator-postgresql-18-backup-garage-local
helm.sh/chart: postgres-18-cluster-7.11.2
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/version: "7.11.2"
app.kubernetes.io/managed-by: Helm
spec:
retentionPolicy: 7d
instanceSidecarConfiguration:
env:
- name: AWS_REQUEST_CHECKSUM_CALCULATION
value: when_required
- name: AWS_RESPONSE_CHECKSUM_VALIDATION
value: when_required
configuration:
destinationPath: s3://postgres-backups/cl01tl/grafana-operator/grafana-operator-postgresql-18-cluster
endpointURL: http://garage-main.garage:3900
s3Credentials:
accessKeyId:
name: grafana-operator-postgresql-18-backup-garage-local-secret
key: ACCESS_KEY_ID
secretAccessKey:
name: grafana-operator-postgresql-18-backup-garage-local-secret
key: ACCESS_SECRET_KEY
region:
name: grafana-operator-postgresql-18-backup-garage-local-secret
key: ACCESS_REGION

View File

@@ -0,0 +1,32 @@
apiVersion: barmancloud.cnpg.io/v1
kind: ObjectStore
metadata:
name: "grafana-operator-postgresql-18-recovery"
namespace: grafana-operator
labels:
helm.sh/chart: postgres-18-cluster-7.11.2
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/version: "7.11.2"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: "grafana-operator-postgresql-18-recovery"
spec:
configuration:
destinationPath: s3://postgres-backups/cl01tl/grafana-operator/grafana-operator-postgresql-18-cluster
endpointURL: http://garage-main.garage:3900
wal:
compression: snappy
maxParallel: 1
data:
compression: snappy
jobs: 1
s3Credentials:
accessKeyId:
name: grafana-operator-postgresql-18-recovery-secret
key: ACCESS_KEY_ID
secretAccessKey:
name: grafana-operator-postgresql-18-recovery-secret
key: ACCESS_SECRET_KEY
region:
name: grafana-operator-postgresql-18-recovery-secret
key: ACCESS_REGION

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: grafana-operator-valkey-remote-cache
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: ceph-block

View File

@@ -0,0 +1,23 @@
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: grafana-operator-valkey-remote-cache
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: valkey
app.kubernetes.io/component: podmonitor
spec:
podMetricsEndpoints:
- port: metrics
interval: 30s
namespaceSelector:
matchNames:
- grafana-operator
selector:
matchLabels:
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator

View File

@@ -0,0 +1,23 @@
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: grafana-operator-valkey-unified-alerting
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: valkey
app.kubernetes.io/component: podmonitor
spec:
podMetricsEndpoints:
- port: metrics
interval: 30s
namespaceSelector:
matchNames:
- grafana-operator
selector:
matchLabels:
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator

View File

@@ -0,0 +1,270 @@
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: grafana-operator-postgresql-18-alert-rules
namespace: grafana-operator
labels:
app.kubernetes.io/name: grafana-operator-postgresql-18-alert-rules
helm.sh/chart: postgres-18-cluster-7.11.2
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/version: "7.11.2"
app.kubernetes.io/managed-by: Helm
spec:
groups:
- name: cloudnative-pg/grafana-operator-postgresql-18
rules:
- alert: CNPGClusterBackendsWaitingWarning
annotations:
summary: CNPG Cluster a backend is waiting for longer than 5 minutes.
description: |-
Pod {{ $labels.pod }}
has been waiting for longer than 5 minutes
expr: |
cnpg_backends_waiting_total{namespace="grafana-operator"} > 300
for: 1m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterDatabaseDeadlockConflictsWarning
annotations:
summary: CNPG Cluster has over 10 deadlock conflicts.
description: |-
There are over 10 deadlock conflicts in
{{ $labels.pod }}
expr: |
cnpg_pg_stat_database_deadlocks{namespace="grafana-operator"} > 10
for: 1m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterHACritical
annotations:
summary: CNPG Cluster has no standby replicas!
description: |-
CloudNativePG Cluster "{{`{{`}} $labels.job {{`}}`}}" has no ready standby replicas. Your cluster at a severe
risk of data loss and downtime if the primary instance fails.
The primary instance is still online and able to serve queries, although connections to the `-ro` endpoint
will fail. The `-r` endpoint os operating at reduced capacity and all traffic is being served by the main.
This can happen during a normal fail-over or automated minor version upgrades in a cluster with 2 or less
instances. The replaced instance may need some time to catch-up with the cluster primary instance.
This alarm will be always trigger if your cluster is configured to run with only 1 instance. In this
case you may want to silence it.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterHACritical.md
expr: |
max by (job) (cnpg_pg_replication_streaming_replicas{namespace="grafana-operator"} - cnpg_pg_replication_is_wal_receiver_up{namespace="grafana-operator"}) < 1
for: 5m
labels:
severity: critical
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterHAWarning
annotations:
summary: CNPG Cluster less than 2 standby replicas.
description: |-
CloudNativePG Cluster "{{`{{`}} $labels.job {{`}}`}}" has only {{`{{`}} $value {{`}}`}} standby replicas, putting
your cluster at risk if another instance fails. The cluster is still able to operate normally, although
the `-ro` and `-r` endpoints operate at reduced capacity.
This can happen during a normal fail-over or automated minor version upgrades. The replaced instance may
need some time to catch-up with the cluster primary instance.
This alarm will be constantly triggered if your cluster is configured to run with less than 3 instances.
In this case you may want to silence it.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterHAWarning.md
expr: |
max by (job) (cnpg_pg_replication_streaming_replicas{namespace="grafana-operator"} - cnpg_pg_replication_is_wal_receiver_up{namespace="grafana-operator"}) < 2
for: 5m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterHighConnectionsCritical
annotations:
summary: CNPG Instance maximum number of connections critical!
description: |-
CloudNativePG Cluster "grafana-operator/grafana-operator-postgresql-18-cluster" instance {{`{{`}} $labels.pod {{`}}`}} is using {{`{{`}} $value {{`}}`}}% of
the maximum number of connections.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterHighConnectionsCritical.md
expr: |
sum by (pod) (cnpg_backends_total{namespace="grafana-operator", pod=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"}) / max by (pod) (cnpg_pg_settings_setting{name="max_connections", namespace="grafana-operator", pod=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"}) * 100 > 95
for: 5m
labels:
severity: critical
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterHighConnectionsWarning
annotations:
summary: CNPG Instance is approaching the maximum number of connections.
description: |-
CloudNativePG Cluster "grafana-operator/grafana-operator-postgresql-18-cluster" instance {{`{{`}} $labels.pod {{`}}`}} is using {{`{{`}} $value {{`}}`}}% of
the maximum number of connections.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterHighConnectionsWarning.md
expr: |
sum by (pod) (cnpg_backends_total{namespace="grafana-operator", pod=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"}) / max by (pod) (cnpg_pg_settings_setting{name="max_connections", namespace="grafana-operator", pod=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"}) * 100 > 80
for: 5m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterHighReplicationLag
annotations:
summary: CNPG Cluster high replication lag
description: |-
CloudNativePG Cluster "grafana-operator/grafana-operator-postgresql-18-cluster" is experiencing a high replication lag of
{{`{{`}} $value {{`}}`}}ms.
High replication lag indicates network issues, busy instances, slow queries or suboptimal configuration.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterHighReplicationLag.md
expr: |
max(cnpg_pg_replication_lag{namespace="grafana-operator",pod=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"}) * 1000 > 1000
for: 5m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterInstancesOnSameNode
annotations:
summary: CNPG Cluster instances are located on the same node.
description: |-
CloudNativePG Cluster "grafana-operator/grafana-operator-postgresql-18-cluster" has {{`{{`}} $value {{`}}`}}
instances on the same node {{`{{`}} $labels.node {{`}}`}}.
A failure or scheduled downtime of a single node will lead to a potential service disruption and/or data loss.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterInstancesOnSameNode.md
expr: |
count by (node) (kube_pod_info{namespace="grafana-operator", pod=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"}) > 1
for: 5m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterLongRunningTransactionWarning
annotations:
summary: CNPG Cluster query is taking longer than 5 minutes.
description: |-
CloudNativePG Cluster Pod {{ $labels.pod }}
is taking more than 5 minutes (300 seconds) for a query.
expr: |-
cnpg_backends_max_tx_duration_seconds{namespace="grafana-operator"} > 300
for: 1m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterLowDiskSpaceCritical
annotations:
summary: CNPG Instance is running out of disk space!
description: |-
CloudNativePG Cluster "grafana-operator/grafana-operator-postgresql-18-cluster" is running extremely low on disk space. Check attached PVCs!
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterLowDiskSpaceCritical.md
expr: |
max(max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"} / kubelet_volume_stats_capacity_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"})) > 0.9 OR
max(max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$-wal"} / kubelet_volume_stats_capacity_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$-wal"})) > 0.9 OR
max(sum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_used_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$-tbs.*"})
/
sum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_capacity_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$-tbs.*"})
*
on(namespace, persistentvolumeclaim) group_left(volume)
kube_pod_spec_volumes_persistentvolumeclaims_info{pod=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"}
) > 0.9
for: 5m
labels:
severity: critical
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterLowDiskSpaceWarning
annotations:
summary: CNPG Instance is running out of disk space.
description: |-
CloudNativePG Cluster "grafana-operator/grafana-operator-postgresql-18-cluster" is running low on disk space. Check attached PVCs.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterLowDiskSpaceWarning.md
expr: |
max(max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"} / kubelet_volume_stats_capacity_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"})) > 0.7 OR
max(max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$-wal"} / kubelet_volume_stats_capacity_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$-wal"})) > 0.7 OR
max(sum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_used_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$-tbs.*"})
/
sum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_capacity_bytes{namespace="grafana-operator", persistentvolumeclaim=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$-tbs.*"})
*
on(namespace, persistentvolumeclaim) group_left(volume)
kube_pod_spec_volumes_persistentvolumeclaims_info{pod=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"}
) > 0.7
for: 5m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterOffline
annotations:
summary: CNPG Cluster has no running instances!
description: |-
CloudNativePG Cluster "grafana-operator/grafana-operator-postgresql-18-cluster" has no ready instances.
Having an offline cluster means your applications will not be able to access the database, leading to
potential service disruption and/or data loss.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterOffline.md
expr: |
(count(cnpg_collector_up{namespace="grafana-operator",pod=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"}) OR on() vector(0)) == 0
for: 5m
labels:
severity: critical
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterPGDatabaseXidAgeWarning
annotations:
summary: CNPG Cluster has a number of transactions from the frozen XID to the current one.
description: |-
Over 300,000,000 transactions from frozen xid
on pod {{ $labels.pod }}
expr: |
cnpg_pg_database_xid_age{namespace="grafana-operator"} > 300000000
for: 1m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterPGReplicationWarning
annotations:
summary: CNPG Cluster standby is lagging behind the primary.
description: |-
Standby is lagging behind by over 300 seconds (5 minutes)
expr: |
cnpg_pg_replication_lag{namespace="grafana-operator"} > 300
for: 1m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterReplicaFailingReplicationWarning
annotations:
summary: CNPG Cluster has a replica is failing to replicate.
description: |-
Replica {{ $labels.pod }}
is failing to replicate
expr: |
cnpg_pg_replication_in_recovery{namespace="grafana-operator"} > cnpg_pg_replication_is_wal_receiver_up{namespace="grafana-operator"}
for: 1m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster
- alert: CNPGClusterZoneSpreadWarning
annotations:
summary: CNPG Cluster instances in the same zone.
description: |-
CloudNativePG Cluster "grafana-operator/grafana-operator-postgresql-18-cluster" has instances in the same availability zone.
A disaster in one availability zone will lead to a potential service disruption and/or data loss.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterZoneSpreadWarning.md
expr: |
3 > count(count by (label_topology_kubernetes_io_zone) (kube_pod_info{namespace="grafana-operator", pod=~"grafana-operator-postgresql-18-cluster-([1-9][0-9]*)$"} * on(node,instance) group_left(label_topology_kubernetes_io_zone) kube_node_labels)) < 3
for: 5m
labels:
severity: warning
namespace: grafana-operator
cnpg_cluster: grafana-operator-postgresql-18-cluster

View File

@@ -0,0 +1,47 @@
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: grafana-operator-valkey-remote-cache
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: valkey
spec:
groups:
- name: grafana-operator-valkey-remote-cache
rules:
- alert: ValkeyDown
annotations:
description: Valkey instance {{ $labels.instance }} is down.
summary: Valkey instance {{ $labels.instance }} down
expr: |
redis_up{service="grafana-operator-valkey-remote-cache-metrics"} == 0
for: 2m
labels:
severity: error
- alert: ValkeyMemoryHigh
annotations:
description: |
Valkey instance {{ $labels.instance }} is using {{ $value }}% of its available memory.
summary: Valkey instance {{ $labels.instance }} is using too much memory
expr: |
redis_memory_used_bytes{service="grafana-operator-valkey-remote-cache-metrics"} * 100
/
redis_memory_max_bytes{service="grafana-operator-valkey-remote-cache-metrics"}
> 90 <= 100
for: 2m
labels:
severity: error
- alert: ValkeyKeyEviction
annotations:
description: |
Valkey instance {{ $labels.instance }} has evicted {{ $value }} keys in the last 5 minutes.
summary: Valkey instance {{ $labels.instance }} has evicted keys
expr: |
increase(redis_evicted_keys_total{service="grafana-operator-valkey-remote-cache-metrics"}[5m]) > 0
for: 1s
labels:
severity: error

View File

@@ -0,0 +1,47 @@
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: grafana-operator-valkey-unified-alerting
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: valkey
spec:
groups:
- name: grafana-operator-valkey-unified-alerting
rules:
- alert: ValkeyDown
annotations:
description: Valkey instance {{ $labels.instance }} is down.
summary: Valkey instance {{ $labels.instance }} down
expr: |
redis_up{service="grafana-operator-valkey-unified-alerting-metrics"} == 0
for: 2m
labels:
severity: error
- alert: ValkeyMemoryHigh
annotations:
description: |
Valkey instance {{ $labels.instance }} is using {{ $value }}% of its available memory.
summary: Valkey instance {{ $labels.instance }} is using too much memory
expr: |
redis_memory_used_bytes{service="grafana-operator-valkey-unified-alerting-metrics"} * 100
/
redis_memory_max_bytes{service="grafana-operator-valkey-unified-alerting-metrics"}
> 90 <= 100
for: 2m
labels:
severity: error
- alert: ValkeyKeyEviction
annotations:
description: |
Valkey instance {{ $labels.instance }} has evicted {{ $value }} keys in the last 5 minutes.
summary: Valkey instance {{ $labels.instance }} has evicted keys
expr: |
increase(redis_evicted_keys_total{service="grafana-operator-valkey-unified-alerting-metrics"}[5m]) > 0
for: 1s
labels:
severity: error

View File

@@ -0,0 +1,26 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: grafana-operator
name: grafana-operator-leases
labels:
helm.sh/chart: grafana-operator-5.22.2
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "v5.22.2"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/component: operator
rules:
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete

View File

@@ -0,0 +1,21 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: grafana-operator-leases
namespace: grafana-operator
labels:
helm.sh/chart: grafana-operator-5.22.2
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "v5.22.2"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/component: operator
subjects:
- kind: ServiceAccount
name: grafana-operator
namespace: grafana-operator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: grafana-operator-leases

View File

@@ -0,0 +1,24 @@
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: "grafana-operator-postgresql-18-scheduled-backup-live-backup"
namespace: grafana-operator
labels:
app.kubernetes.io/name: "grafana-operator-postgresql-18-scheduled-backup-live-backup"
helm.sh/chart: postgres-18-cluster-7.11.2
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/version: "7.11.2"
app.kubernetes.io/managed-by: Helm
spec:
immediate: true
suspend: false
schedule: "0 30 14 * * *"
backupOwnerReference: self
cluster:
name: grafana-operator-postgresql-18-cluster
method: plugin
pluginConfiguration:
name: barman-cloud.cloudnative-pg.io
parameters:
barmanObjectName: "grafana-operator-postgresql-18-backup-garage-local"

View File

@@ -0,0 +1,27 @@
apiVersion: v1
kind: Service
metadata:
name: grafana-operator-metrics-service
namespace: grafana-operator
labels:
helm.sh/chart: grafana-operator-5.22.2
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "v5.22.2"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/component: operator
spec:
type: ClusterIP
ports:
- port: 9090
targetPort: metrics
protocol: TCP
name: metrics
- port: 8888
targetPort: pprof
protocol: TCP
name: pprof
selector:
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator

View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: Service
metadata:
name: grafana-operator-valkey-remote-cache-metrics
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: metrics
app.kubernetes.io/part-of: valkey
annotations:
spec:
type: ClusterIP
ports:
- name: metrics
port: 9121
protocol: TCP
targetPort: metrics
selector:
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator

View File

@@ -0,0 +1,21 @@
apiVersion: v1
kind: Service
metadata:
name: grafana-operator-valkey-remote-cache
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: primary
spec:
type: ClusterIP
ports:
- port: 6379
targetPort: tcp
protocol: TCP
name: tcp
selector:
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator

View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: Service
metadata:
name: grafana-operator-valkey-unified-alerting-headless
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: headless
spec:
type: ClusterIP
clusterIP: None
publishNotReadyAddresses: true
ports:
- name: tcp
port: 6379
targetPort: tcp
protocol: TCP
selector:
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator

View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: Service
metadata:
name: grafana-operator-valkey-unified-alerting-metrics
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: metrics
app.kubernetes.io/part-of: valkey
annotations:
spec:
type: ClusterIP
ports:
- name: metrics
port: 9121
protocol: TCP
targetPort: metrics
selector:
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator

View File

@@ -0,0 +1,21 @@
apiVersion: v1
kind: Service
metadata:
name: grafana-operator-valkey-unified-alerting-read
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: read
spec:
type: ClusterIP
ports:
- name: tcp
port: 6379
targetPort: tcp
protocol: TCP
selector:
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator

View File

@@ -0,0 +1,22 @@
apiVersion: v1
kind: Service
metadata:
name: grafana-operator-valkey-unified-alerting
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: primary
spec:
type: ClusterIP
ports:
- port: 6379
targetPort: tcp
protocol: TCP
name: tcp
selector:
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
statefulset.kubernetes.io/pod-name: grafana-operator-valkey-unified-alerting-0

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: grafana-operator-valkey-remote-cache
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
automountServiceAccountToken: false

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: grafana-operator-valkey-unified-alerting
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
automountServiceAccountToken: false

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: grafana-operator
namespace: grafana-operator
labels:
helm.sh/chart: grafana-operator-5.22.2
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "v5.22.2"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/component: operator
automountServiceAccountToken: true

View File

@@ -0,0 +1,24 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: grafana-operator-valkey-remote-cache
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: valkey
app.kubernetes.io/component: service-monitor
spec:
endpoints:
- port: metrics
interval: 30s
namespaceSelector:
matchNames:
- grafana-operator
selector:
matchLabels:
app.kubernetes.io/name: valkey-remote-cache
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/component: metrics

View File

@@ -0,0 +1,24 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: grafana-operator-valkey-unified-alerting
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: valkey
app.kubernetes.io/component: service-monitor
spec:
endpoints:
- port: metrics
interval: 30s
namespaceSelector:
matchNames:
- grafana-operator
selector:
matchLabels:
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/component: metrics

View File

@@ -0,0 +1,27 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: grafana-operator
namespace: grafana-operator
labels:
helm.sh/chart: grafana-operator-5.22.2
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "v5.22.2"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: grafana-operator
app.kubernetes.io/component: operator
spec:
jobLabel: grafana-operator
namespaceSelector:
matchNames:
- grafana-operator
selector:
matchLabels:
app.kubernetes.io/name: grafana-operator
app.kubernetes.io/instance: grafana-operator
endpoints:
- port: metrics
path: /metrics
interval: 1m
scrapeTimeout: 10s

View File

@@ -0,0 +1,129 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: grafana-operator-valkey-unified-alerting
labels:
helm.sh/chart: valkey-0.9.3
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
app.kubernetes.io/version: "9.0.3"
app.kubernetes.io/managed-by: Helm
spec:
serviceName: grafana-operator-valkey-unified-alerting-headless
replicas: 3
podManagementPolicy: OrderedReady
selector:
matchLabels:
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
volumeClaimTemplates:
- metadata:
name: valkey-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: "ceph-block"
resources:
requests:
storage: "1Gi"
template:
metadata:
labels:
app.kubernetes.io/name: valkey-unified-alerting
app.kubernetes.io/instance: grafana-operator
annotations:
checksum/initconfig: "cc97af05b1fa8109e641f83996efbf01"
spec:
automountServiceAccountToken: false
serviceAccountName: grafana-operator-valkey-unified-alerting
securityContext:
fsGroup: 1000
runAsGroup: 1000
runAsUser: 1000
initContainers:
- name: grafana-operator-valkey-unified-alerting-init
image: docker.io/valkey/valkey:9.0.3
imagePullPolicy: IfNotPresent
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
command: ["/scripts/init.sh"]
env:
- name: POD_INDEX
valueFrom:
fieldRef:
fieldPath: metadata.labels['apps.kubernetes.io/pod-index']
volumeMounts:
- name: valkey-data
mountPath: /data
- name: scripts
mountPath: /scripts
containers:
- name: grafana-operator-valkey-unified-alerting
image: docker.io/valkey/valkey:9.0.3
imagePullPolicy: IfNotPresent
command: ["valkey-server"]
args: ["/data/conf/valkey.conf"]
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
env:
- name: POD_INDEX
valueFrom:
fieldRef:
fieldPath: metadata.labels['apps.kubernetes.io/pod-index']
- name: VALKEY_LOGLEVEL
value: "notice"
ports:
- name: tcp
containerPort: 6379
protocol: TCP
startupProbe:
exec:
command: ["sh", "-c", "valkey-cli ping"]
livenessProbe:
exec:
command: ["sh", "-c", "valkey-cli ping"]
resources:
requests:
cpu: 10m
memory: 20Mi
volumeMounts:
- name: valkey-data
mountPath: /data
- name: metrics
image: ghcr.io/oliver006/redis_exporter:v1.82.0
imagePullPolicy: "IfNotPresent"
ports:
- name: metrics
containerPort: 9121
startupProbe:
tcpSocket:
port: metrics
livenessProbe:
tcpSocket:
port: metrics
readinessProbe:
httpGet:
path: /
port: metrics
resources:
requests:
cpu: 1m
memory: 10M
env:
- name: REDIS_ALIAS
value: grafana-operator-valkey-unified-alerting
volumes:
- name: scripts
configMap:
name: grafana-operator-valkey-unified-alerting-init-scripts
defaultMode: 0555