Add VictoriaMetrics observability stack + sync catalog for monitoring test
- VM stack 10 charts: victoria-metrics-cluster/auth, victoria-logs-cluster, victoria-metrics-agent/alert, opentelemetry-collector, kube-state-metrics, prometheus-node-exporter, alertmanager, perses (JWT/OIDC, Infisical-ready) - ArgoCD ApplicationSet (syncWave) + per-chart dip-values overlays - doc/victoria-metrics-architecture.md, define-chart-resources updates - includes pending working-tree changes (mlflow, kubeflow, apisix, CLAUDE.md) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
{{- if and .Values.config.database.file .Values.config.database.sql }}
|
||||
{{ fail "[ERROR] 'config.database' must be set as file or SQL, and those options are mutually exclusive." }}
|
||||
{{ end }}
|
||||
|
||||
{{- if and .Values.persistence.enabled (eq .Values.persistence.storageClass "") }}
|
||||
{{ fail "[ERROR] 'persistencen.storageClass' must be set." }}
|
||||
{{ end }}
|
||||
|
||||
{{- define "perses.validateDatabaseConfig" -}}
|
||||
{{- if and .Values.config.database.file .Values.config.database.sql }}
|
||||
{{- fail "[ERROR] Both 'config.database.file' and 'config.database.sql' cannot be set at the same time. Please configure only one of them." }}
|
||||
{{- end }}
|
||||
{{- $sqlConfig := .Values.config.database.sql }}
|
||||
{{- if $sqlConfig }}
|
||||
{{- $tlsConfig := $sqlConfig.tls_config }}
|
||||
{{- if and $tlsConfig (kindIs "map" $tlsConfig) }}
|
||||
{{- if or (hasKey $tlsConfig "ca_file") (hasKey $tlsConfig "cert_file") (hasKey $tlsConfig "key_file") (hasKey $tlsConfig "server_name") (hasKey $tlsConfig "insecure_skip_verify") (hasKey $tlsConfig "min_version") (hasKey $tlsConfig "max_version") }}
|
||||
{{- fail "[ERROR] Legacy SQL TLS keys detected under 'config.database.sql.tls_config'. Use camelCase keys: ca_file->caFile, cert_file->certFile, key_file->keyFile, server_name->serverName, insecure_skip_verify->insecureSkipVerify, min_version->minVersion, max_version->maxVersion." }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.datasources }}
|
||||
#################################################################################
|
||||
###### WARNING: The 'datasources' configuration field is deprecated #####
|
||||
###### and will be removed in the future version. #####
|
||||
###### Please migrate to using the 'sidecar' configuration #####
|
||||
###### for provisioning datasources. #####
|
||||
#################################################################################
|
||||
{{- end }}
|
||||
@@ -0,0 +1,49 @@
|
||||
{{- if .Values.sidecar.enabled }}
|
||||
{{- $nsConfig := dict "customEnv" false }}
|
||||
{{- range .Values.sidecar.extraEnvVars }}
|
||||
{{- if eq .name "NAMESPACE" }}
|
||||
{{- $_ := set $nsConfig "customEnv" true }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $hasCustomNamespaceEnv := $nsConfig.customEnv }}
|
||||
{{- $clusterScope := or .Values.sidecar.allNamespaces $hasCustomNamespaceEnv }}
|
||||
{{- $roleKind := ternary "ClusterRole" "Role" $clusterScope }}
|
||||
{{- $bindingKind := ternary "ClusterRoleBinding" "RoleBinding" $clusterScope }}
|
||||
{{- $roleName := ternary (printf "%s-clusterrole" (include "perses.fullname" .)) (printf "%s-role" (include "perses.fullname" .)) $clusterScope }}
|
||||
{{- $bindingName := ternary (printf "%s-clusterrolebinding" (include "perses.fullname" .)) (printf "%s-rolebinding" (include "perses.fullname" .)) $clusterScope }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: {{ $roleKind }}
|
||||
metadata:
|
||||
name: {{ $roleName }}
|
||||
{{- if not $clusterScope }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: iam
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
{{- if .Values.sidecar.enableSecretAccess }}
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: {{ $bindingKind }}
|
||||
metadata:
|
||||
name: {{ $bindingName }}
|
||||
{{- if not $clusterScope }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
roleRef:
|
||||
kind: {{ $roleKind }}
|
||||
name: {{ $roleName }}
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "perses.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,23 @@
|
||||
{{- $shouldCreate := (include "perses.shouldCreateEnvVarsSecret" . | trim) }}
|
||||
{{- if eq $shouldCreate "true" }}
|
||||
{{- $mergedEnvVars := include "perses.mergedEnvVars" . | fromYamlArray }}
|
||||
{{- if $mergedEnvVars }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "perses.envVarsSecretName" . }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: configuration
|
||||
{{- with .Values.config.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
data:
|
||||
{{- range $mergedEnvVars }}
|
||||
{{- if and (kindIs "map" .) (hasKey . "value") }}
|
||||
{{ .name | kebabcase }}: {{ .value | b64enc }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "perses.fullname" . }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: configuration
|
||||
{{- with .Values.config.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
data:
|
||||
config.yaml: |-
|
||||
{{ $config := unset .Values.config "annotations" }}
|
||||
{{- with $config }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.datasources }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "perses.fullname" . }}-datasources
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: configuration
|
||||
data:
|
||||
{{- range $.Values.datasources }}
|
||||
{{ .metadata.name | lower }}.json: |-
|
||||
{{- tpl (toJson .) $ | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,218 @@
|
||||
{{- include "perses.validateDatabaseConfig" . }}
|
||||
|
||||
{{- if .Values.config.database.sql }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "perses.fullname" . }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: workload
|
||||
{{- with .Values.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "perses.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "perses.selectorLabels" . | nindent 8 }}
|
||||
annotations:
|
||||
{{- if .Values.datasources }}
|
||||
checksum/config: {{ include (print $.Template.BasePath "/datasources.yaml") . | sha256sum }}
|
||||
{{- else }}
|
||||
checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "perses.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.persistence.securityContext | nindent 8 }}
|
||||
containers:
|
||||
{{- if .Values.sidecar.enabled }}
|
||||
{{- $nsConfig := dict "customEnv" false }}
|
||||
{{- range .Values.sidecar.extraEnvVars }}
|
||||
{{- if eq .name "NAMESPACE" }}
|
||||
{{- $_ := set $nsConfig "customEnv" true }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $hasCustomNamespaceEnv := $nsConfig.customEnv }}
|
||||
- name: {{ .Chart.Name }}-provisioning-sidecar
|
||||
image: "{{ .Values.sidecar.image.registry | default .Values.image.registry }}/{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}"
|
||||
{{- with .Values.sidecar.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: provisioning
|
||||
mountPath: {{ .Values.config.provisioning.folders | first }}
|
||||
env:
|
||||
- name: LABEL
|
||||
value: {{ .Values.sidecar.label }}
|
||||
- name: LABEL_VALUE
|
||||
value: {{ .Values.sidecar.labelValue | quote }}
|
||||
- name: FOLDER
|
||||
value: {{ .Values.config.provisioning.folders | first }}
|
||||
- name: HEALTH_PORT
|
||||
value: "{{ .Values.sidecar.healthPort }}"
|
||||
{{- if and (not $hasCustomNamespaceEnv) .Values.sidecar.allNamespaces }}
|
||||
- name: NAMESPACE
|
||||
value: ALL
|
||||
{{- end }}
|
||||
{{- if .Values.sidecar.enableSecretAccess}}
|
||||
- name: RESOURCE
|
||||
value: both
|
||||
{{- end }}
|
||||
{{- with .Values.sidecar.extraEnvVars -}}
|
||||
{{ toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
- name: {{ .Chart.Name }}
|
||||
image: "{{ .Values.image.registry }}/{{ .Values.image.name }}:{{ .Values.image.version | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
args:
|
||||
- --config=/etc/perses/config/config.yaml
|
||||
- --web.listen-address=:{{ .Values.service.targetPort }}
|
||||
- --web.hide-port=false
|
||||
- --web.telemetry-path={{ .Values.config.api_prefix }}/metrics
|
||||
- --log.level={{ .Values.logLevel }}
|
||||
- --log.method-trace=true
|
||||
{{- range $key, $value := .Values.extraArgs }}
|
||||
{{- if $value }}
|
||||
- --{{ $key }}={{ tpl ($value | toString) $ }}
|
||||
{{- else }}
|
||||
- --{{ $key }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $mergedEnvVars := include "perses.mergedEnvVars" . | fromYamlArray }}
|
||||
{{- if $mergedEnvVars }}
|
||||
env:
|
||||
{{- range $mergedEnvVars }}
|
||||
{{- if and (kindIs "map" .) (hasKey . "name") }}
|
||||
- name: {{ .name }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "perses.envVarsSecretName" $ }}
|
||||
key: {{ .name | kebabcase }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
{{- if .Values.volumeMounts }}
|
||||
{{- tpl (toYaml .Values.volumeMounts | nindent 10) . }}
|
||||
{{- end }}
|
||||
- name: config
|
||||
mountPath: "/etc/perses/config"
|
||||
- mountPath: "/etc/perses/storage"
|
||||
name: storage
|
||||
{{- if .Values.tls.enabled }}
|
||||
{{- if .Values.tls.caCert.enabled }}
|
||||
- name: ca-cert
|
||||
mountPath: {{ .Values.tls.caCert.mountPath }}
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.tls.clientCert.enabled }}
|
||||
- name: client-cert
|
||||
mountPath: {{ .Values.tls.clientCert.mountPath }}
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.targetPort}}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.config.api_prefix }}/api/v1/health
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
|
||||
successThreshold: {{ .Values.readinessProbe.successThreshold }}
|
||||
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.config.api_prefix }}/api/v1/health
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
|
||||
successThreshold: {{ .Values.livenessProbe.successThreshold }}
|
||||
failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
|
||||
{{- with .Values.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
volumes:
|
||||
{{- if .Values.volumes }}
|
||||
{{- tpl (toYaml .Values.volumes | nindent 8) . }}
|
||||
{{- end }}
|
||||
- name: config
|
||||
configMap:
|
||||
defaultMode: 420
|
||||
name: {{ include "perses.fullname" . }}
|
||||
- name: storage
|
||||
emptyDir: {}
|
||||
{{- if .Values.sidecar.enabled }}
|
||||
- name: provisioning
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- if .Values.tls.enabled }}
|
||||
{{- if .Values.tls.caCert.enabled }}
|
||||
- name: ca-cert
|
||||
secret:
|
||||
secretName: {{ .Values.tls.caCert.secretName | default (printf "%s-tls" (include "perses.fullname" .)) }}
|
||||
defaultMode: 420
|
||||
{{- end }}
|
||||
{{- if .Values.tls.clientCert.enabled }}
|
||||
- name: client-cert
|
||||
secret:
|
||||
secretName: {{ .Values.tls.clientCert.secretName | default (printf "%s-tls" (include "perses.fullname" .)) }}
|
||||
defaultMode: 420
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if or .Values.affinity .Values.podAntiAffinity }}
|
||||
affinity:
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if eq .Values.podAntiAffinity "hard" }}
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- topologyKey: {{ .Values.podAntiAffinityTopologyKey }}
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- {key: app.kubernetes.io/name, operator: In, values: [{{ template "perses.name" . }}]}
|
||||
{{- else if eq .Values.podAntiAffinity "soft" }}
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
topologyKey: {{ .Values.podAntiAffinityTopologyKey }}
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- {key: app.kubernetes.io/name, operator: In, values: [{{ template "perses.name" . }}]}
|
||||
{{- end }}
|
||||
{{- with .Values.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,4 @@
|
||||
{{ range .Values.extraObjects }}
|
||||
---
|
||||
{{ tpl (toYaml .) $ }}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,42 @@
|
||||
{{- if and .Values.gateway.enabled .Values.gateway.createGateway }}
|
||||
{{- $fullName := include "perses.fullname" . -}}
|
||||
{{- $gatewayName := default (printf "%s-gateway" $fullName) .Values.gateway.name -}}
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: {{ $gatewayName }}
|
||||
{{- if .Values.gateway.namespace }}
|
||||
namespace: {{ .Values.gateway.namespace }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: networking
|
||||
{{- with .Values.gateway.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
gatewayClassName: {{ required "gateway.gatewayClassName is required when creating a Gateway" .Values.gateway.gatewayClassName }}
|
||||
{{- if .Values.gateway.listeners }}
|
||||
listeners:
|
||||
{{- range .Values.gateway.listeners }}
|
||||
- name: {{ .name }}
|
||||
port: {{ .port }}
|
||||
protocol: {{ .protocol }}
|
||||
{{- if .hostname }}
|
||||
hostname: {{ .hostname | quote }}
|
||||
{{- end }}
|
||||
{{- if .tls }}
|
||||
tls:
|
||||
{{- toYaml .tls | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .allowedRoutes }}
|
||||
allowedRoutes:
|
||||
{{- toYaml .allowedRoutes | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,30 @@
|
||||
{{- if and .Values.sidecar.enabled .Values.sidecar.globalAdminUsers .Values.config.security.enable_auth }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "perses.fullname" . }}-admin-bootstrap
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
{{ .Values.sidecar.label }}: {{ .Values.sidecar.labelValue | quote }}
|
||||
data:
|
||||
global-admin-role.yaml: |
|
||||
kind: GlobalRole
|
||||
metadata:
|
||||
name: global-admin
|
||||
spec:
|
||||
permissions:
|
||||
- actions: ["*"]
|
||||
scopes: ["*"]
|
||||
|
||||
global-admin-binding.yaml: |
|
||||
kind: GlobalRoleBinding
|
||||
metadata:
|
||||
name: global-admin-binding
|
||||
spec:
|
||||
role: global-admin
|
||||
subjects:
|
||||
{{- range .Values.sidecar.globalAdminUsers }}
|
||||
- kind: User
|
||||
name: {{ . | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,90 @@
|
||||
{{/* ========================================================================
|
||||
Configuration helpers
|
||||
========================================================================= */}}
|
||||
|
||||
{{/*
|
||||
Return env vars generated from authentication providers for client_id/client_secret.
|
||||
We include entries even when the value is empty so they can be sourced from an external Secret.
|
||||
NOTE: When using external secrets (secret.create=false or envVarsExternalSecretName),
|
||||
this should return empty to avoid duplicate secret creation.
|
||||
*/}}
|
||||
{{- define "perses.authProviderEnvVars" -}}
|
||||
{{- $result := list }}
|
||||
{{- $usingExternalSecret := or (and .Values.secret (not (default true .Values.secret.create))) .Values.envVarsExternalSecretName }}
|
||||
{{- if not $usingExternalSecret }}
|
||||
{{- $auth := .Values.config.security.authentication }}
|
||||
{{- if and .Values.config.security.enable_auth $auth }}
|
||||
{{- range $i, $provider := $auth.providers.oidc }}
|
||||
{{- $result = append $result (dict "name" (printf "PERSES_SECURITY_AUTHENTICATION_PROVIDERS_OIDC_%d_CLIENT_ID" $i) "value" ($provider.client_id | default "")) }}
|
||||
{{- $result = append $result (dict "name" (printf "PERSES_SECURITY_AUTHENTICATION_PROVIDERS_OIDC_%d_CLIENT_SECRET" $i) "value" ($provider.client_secret | default "")) }}
|
||||
{{- end }}
|
||||
{{- range $i, $provider := $auth.providers.oauth }}
|
||||
{{- $result = append $result (dict "name" (printf "PERSES_SECURITY_AUTHENTICATION_PROVIDERS_OAUTH_%d_CLIENT_ID" $i) "value" ($provider.client_id | default "")) }}
|
||||
{{- $result = append $result (dict "name" (printf "PERSES_SECURITY_AUTHENTICATION_PROVIDERS_OAUTH_%d_CLIENT_SECRET" $i) "value" ($provider.client_secret | default "")) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- toYaml $result }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Merge user-provided envVars with auto-generated auth provider env vars.
|
||||
Auto-generated env vars are only added if not already provided by the user.
|
||||
*/}}
|
||||
{{- define "perses.mergedEnvVars" -}}
|
||||
{{- $autoRaw := include "perses.authProviderEnvVars" . }}
|
||||
{{- $auto := $autoRaw | fromYamlArray | default (list) }}
|
||||
{{- $userRaw := .Values.envVars | default (list) }}
|
||||
{{- $user := (kindIs "slice" $userRaw | ternary $userRaw (list $userRaw)) }}
|
||||
{{- /* Build a map of user-provided env var names for deduplication */ -}}
|
||||
{{- $userEnvNames := dict }}
|
||||
{{- range $user }}
|
||||
{{- if and (kindIs "map" .) (hasKey . "name") }}
|
||||
{{- $_ := set $userEnvNames .name true }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- /* Only add auto-generated env vars if not already provided by user */ -}}
|
||||
{{- $filteredAuto := list }}
|
||||
{{- range $auto }}
|
||||
{{- if and (kindIs "map" .) (hasKey . "name") }}
|
||||
{{- if not (hasKey $userEnvNames .name) }}
|
||||
{{- $filteredAuto = append $filteredAuto . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $merged := concat $user $filteredAuto }}
|
||||
{{- if $merged }}
|
||||
{{- toYaml $merged }}
|
||||
{{- else }}
|
||||
[]
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Resolve env vars Secret name (generated or custom override).
|
||||
*/}}
|
||||
{{- define "perses.envVarsSecretName" -}}
|
||||
{{- $name := "" }}
|
||||
{{- if and .Values.secret .Values.secret.name }}
|
||||
{{- $name = .Values.secret.name }}
|
||||
{{- else if .Values.envVarsExternalSecretName }}
|
||||
{{- $name = .Values.envVarsExternalSecretName }}
|
||||
{{- else }}
|
||||
{{- $name = (include "perses.fullname" .) }}
|
||||
{{- end }}
|
||||
{{- $name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Should we create the env vars Secret?
|
||||
*/}}
|
||||
{{- define "perses.shouldCreateEnvVarsSecret" -}}
|
||||
{{- $create := true }}
|
||||
{{- if hasKey .Values "secret" }}
|
||||
{{- if hasKey .Values.secret "create" }}
|
||||
{{- $create = .Values.secret.create }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $shouldCreate := and $create (not .Values.envVarsExternalSecretName) }}
|
||||
{{- if $shouldCreate }}true{{- else }}false{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,75 @@
|
||||
{{/* ========================================================================
|
||||
Naming & identity helpers
|
||||
========================================================================= */}}
|
||||
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "perses.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "perses.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "perses.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "perses.labels" -}}
|
||||
helm.sh/chart: {{ include "perses.chart" . }}
|
||||
{{ include "perses.selectorLabels" . }}
|
||||
app.kubernetes.io/version: {{ default .Chart.AppVersion .Values.image.version }}
|
||||
app.kubernetes.io/part-of: {{ include "perses.name" . }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- if not (empty .Values.additionalLabels) }}
|
||||
{{ toYaml .Values.additionalLabels }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "perses.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "perses.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "perses.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "perses.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Render an internal DNS endpoint for the Perses service.
|
||||
*/}}
|
||||
{{- define "perses.dns" -}}
|
||||
http://{{ include "perses.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.targetPort }}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,81 @@
|
||||
{{- if .Values.gateway.enabled }}
|
||||
{{- $fullName := include "perses.fullname" . -}}
|
||||
{{- $gatewayName := default (printf "%s-gateway" $fullName) .Values.gateway.name -}}
|
||||
{{- $routeName := default (printf "%s-http-route" $fullName) .Values.gateway.httpRoute.name -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- $defaultParentRef := dict "name" $gatewayName -}}
|
||||
{{- if .Values.gateway.namespace }}
|
||||
{{- $_ := set $defaultParentRef "namespace" .Values.gateway.namespace -}}
|
||||
{{- end }}
|
||||
{{- $parentRefs := .Values.gateway.httpRoute.parentRefs }}
|
||||
{{- if and (empty $parentRefs) .Values.gateway.createGateway }}
|
||||
{{- $parentRefs = (list $defaultParentRef) }}
|
||||
{{- end }}
|
||||
{{- if empty $parentRefs }}
|
||||
{{- fail "gateway.httpRoute.parentRefs must be set when gateway.enabled is true and gateway.createGateway is false" }}
|
||||
{{- end }}
|
||||
{{- $rules := .Values.gateway.httpRoute.rules }}
|
||||
{{- if empty $rules }}
|
||||
{{- $rules = list (dict "matches" (list (dict "path" (dict "type" "PathPrefix" "value" "/"))) "backendRefs" (list (dict "name" $fullName "port" $svcPort))) }}
|
||||
{{- end }}
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: {{ $routeName }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: networking
|
||||
{{- with .Values.gateway.httpRoute.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.httpRoute.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
parentRefs:
|
||||
{{- range $parentRefs }}
|
||||
- name: {{ .name }}
|
||||
{{- if .namespace }}
|
||||
namespace: {{ .namespace }}
|
||||
{{- end }}
|
||||
{{- if .sectionName }}
|
||||
sectionName: {{ .sectionName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.httpRoute.hostnames }}
|
||||
hostnames:
|
||||
{{- range .Values.gateway.httpRoute.hostnames }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range $rules }}
|
||||
- {{- if .matches }}
|
||||
matches:
|
||||
{{- toYaml .matches | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .filters }}
|
||||
filters:
|
||||
{{- toYaml .filters | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- $backendRefs := .backendRefs | default (list (dict "name" $fullName "port" $svcPort)) }}
|
||||
backendRefs:
|
||||
{{- range $backendRefs }}
|
||||
- name: {{ .name | default $fullName }}
|
||||
{{- if .namespace }}
|
||||
namespace: {{ .namespace }}
|
||||
{{- end }}
|
||||
{{- if .kind }}
|
||||
kind: {{ .kind }}
|
||||
{{- end }}
|
||||
{{- if .group }}
|
||||
group: {{ .group }}
|
||||
{{- end }}
|
||||
port: {{ .port | default $svcPort }}
|
||||
{{- if .weight }}
|
||||
weight: {{ .weight }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,43 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "perses.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.ingressClassName }}
|
||||
ingressClassName: {{ .Values.ingress.ingressClassName }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
pathType: {{ .pathType }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,24 @@
|
||||
{{- if .Values.persistence.enabled }}
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ include "perses.fullname" . }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: storage
|
||||
{{- with .Values.persistence.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.persistence.storageClass }}
|
||||
storageClassName: {{ .Values.persistence.storageClass }}
|
||||
{{- end }}
|
||||
accessModes:
|
||||
{{- range .Values.persistence.accessModes }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.size | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,43 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "perses.fullname" . }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: networking
|
||||
{{- with .Values.service.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }}
|
||||
type: ClusterIP
|
||||
{{- with .Values.service.clusterIP }}
|
||||
clusterIP: {{ . }}
|
||||
{{- end }}
|
||||
{{- else if eq .Values.service.type "LoadBalancer" }}
|
||||
type: {{ .Values.service.type }}
|
||||
{{- with .Values.service.loadBalancerIP }}
|
||||
loadBalancerIP: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.loadBalancerSourceRanges }}
|
||||
loadBalancerSourceRanges:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
type: {{ .Values.service.type }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: {{ .Values.service.portName }}
|
||||
port: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
targetPort: {{ .Values.service.targetPort }}
|
||||
{{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }}
|
||||
nodePort: {{ .Values.service.nodePort }}
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "perses.selectorLabels" . | nindent 4 }}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "perses.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: iam
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,24 @@
|
||||
{{- if .Values.serviceMonitor.selfMonitor -}}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: {{ include "perses.fullname" . }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceMonitor.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- with .Values.serviceMonitor.selector.matchLabels }}
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- {{ .Release.Namespace}}
|
||||
endpoints:
|
||||
- port: {{ .Values.service.portName }}
|
||||
interval: {{ .Values.serviceMonitor.interval }}
|
||||
path: {{ .Values.config.api_prefix }}/metrics
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,275 @@
|
||||
{{- include "perses.validateDatabaseConfig" . }}
|
||||
|
||||
{{- if .Values.config.database.file }}
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: {{ include "perses.fullname" . }}
|
||||
labels:
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: workload
|
||||
{{- with .Values.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicas }}
|
||||
serviceName: {{ include "perses.fullname" . }}-headless
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "perses.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "perses.selectorLabels" . | nindent 8 }}
|
||||
annotations:
|
||||
{{- if .Values.datasources }}
|
||||
checksum/config: {{ include (print $.Template.BasePath "/datasources.yaml") . | sha256sum }}
|
||||
{{- else }}
|
||||
checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "perses.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.persistence.securityContext | nindent 8 }}
|
||||
containers:
|
||||
{{- if .Values.sidecar.enabled }}
|
||||
{{- $nsConfig := dict "customEnv" false }}
|
||||
{{- range .Values.sidecar.extraEnvVars }}
|
||||
{{- if eq .name "NAMESPACE" }}
|
||||
{{- $_ := set $nsConfig "customEnv" true }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $hasCustomNamespaceEnv := $nsConfig.customEnv }}
|
||||
- name: {{ .Chart.Name }}-provisioning-sidecar
|
||||
image: "{{ .Values.sidecar.image.registry | default .Values.image.registry }}/{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}"
|
||||
{{- with .Values.sidecar.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: provisioning
|
||||
mountPath: {{ .Values.config.provisioning.folders | first }}
|
||||
env:
|
||||
- name: LABEL
|
||||
value: {{ .Values.sidecar.label }}
|
||||
- name: LABEL_VALUE
|
||||
value: {{ .Values.sidecar.labelValue | quote }}
|
||||
- name: FOLDER
|
||||
value: {{ .Values.config.provisioning.folders | first }}
|
||||
- name: HEALTH_PORT
|
||||
value: "{{ .Values.sidecar.healthPort }}"
|
||||
{{- if and (not $hasCustomNamespaceEnv) .Values.sidecar.allNamespaces }}
|
||||
- name: NAMESPACE
|
||||
value: ALL
|
||||
{{- end }}
|
||||
{{- if .Values.sidecar.enableSecretAccess}}
|
||||
- name: RESOURCE
|
||||
value: both
|
||||
{{- end }}
|
||||
{{- with .Values.sidecar.extraEnvVars -}}
|
||||
{{ toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
- name: {{ .Chart.Name }}
|
||||
image: "{{ .Values.image.registry }}/{{ .Values.image.name }}:{{ .Values.image.version | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
args:
|
||||
- --config=/etc/perses/config/config.yaml
|
||||
- --web.listen-address=:{{ .Values.service.targetPort }}
|
||||
- --web.hide-port=false
|
||||
- --web.telemetry-path={{ .Values.config.api_prefix }}/metrics
|
||||
- --log.level={{ .Values.logLevel }}
|
||||
- --log.method-trace=true
|
||||
{{- range $key, $value := .Values.extraArgs }}
|
||||
{{- if $value }}
|
||||
- --{{ $key }}={{ tpl ($value | toString) $ }}
|
||||
{{- else }}
|
||||
- --{{ $key }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $mergedEnvVars := include "perses.mergedEnvVars" . | fromYamlArray }}
|
||||
{{- if $mergedEnvVars }}
|
||||
env:
|
||||
{{- range $mergedEnvVars }}
|
||||
{{- if and (kindIs "map" .) (hasKey . "name") }}
|
||||
- name: {{ .name }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "perses.envVarsSecretName" $ }}
|
||||
key: {{ .name | kebabcase }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
{{- if .Values.volumeMounts }}
|
||||
{{- tpl (toYaml .Values.volumeMounts | nindent 10) . }}
|
||||
{{- end }}
|
||||
{{- if .Values.ociArtifacts }}
|
||||
- name: {{ .Values.ociArtifacts.name }}
|
||||
mountPath: {{ .Values.ociArtifacts.mountPath }}
|
||||
{{- if .Values.ociArtifacts.subPath }}
|
||||
subPath: {{ .Values.ociArtifacts.subPath }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
- name: config
|
||||
mountPath: "/etc/perses/config"
|
||||
{{- if .Values.config.database.file }}
|
||||
- name: data
|
||||
mountPath: {{ .Values.config.database.file.folder }}
|
||||
{{- end }}
|
||||
{{- if .Values.datasources }}
|
||||
- name: datasources
|
||||
mountPath: /etc/perses/datasources
|
||||
{{- end }}
|
||||
{{- if or .Values.sidecar.enabled .Values.provisioningPersistence.enabled }}
|
||||
- name: provisioning
|
||||
mountPath: {{ .Values.config.provisioning.folders | first }}
|
||||
{{- end }}
|
||||
{{- if .Values.tls.enabled }}
|
||||
{{- if .Values.tls.caCert.enabled }}
|
||||
- name: ca-cert
|
||||
mountPath: {{ .Values.tls.caCert.mountPath }}
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.tls.clientCert.enabled }}
|
||||
- name: client-cert
|
||||
mountPath: {{ .Values.tls.clientCert.mountPath }}
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.targetPort }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.config.api_prefix }}/api/v1/health
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
|
||||
successThreshold: {{ .Values.readinessProbe.successThreshold }}
|
||||
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.config.api_prefix }}/api/v1/health
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
|
||||
successThreshold: {{ .Values.livenessProbe.successThreshold }}
|
||||
failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
|
||||
{{- with .Values.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
{{- if .Values.volumes }}
|
||||
{{- tpl (toYaml .Values.volumes | nindent 8) . }}
|
||||
{{- end }}
|
||||
{{- if .Values.ociArtifacts }}
|
||||
- name: {{ .Values.ociArtifacts.name }}
|
||||
image:
|
||||
reference: {{ .Values.ociArtifacts.image.reference }}
|
||||
{{- if .Values.ociArtifacts.image.pullPolicy }}
|
||||
pullPolicy: {{ .Values.ociArtifacts.image.pullPolicy }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.config.database.file }}
|
||||
- name: data
|
||||
{{- if .Values.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "perses.fullname" . }}
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
- name: config
|
||||
configMap:
|
||||
defaultMode: 420
|
||||
name: {{ include "perses.fullname" . }}
|
||||
{{- if .Values.datasources }}
|
||||
- name: datasources
|
||||
configMap:
|
||||
name: {{ include "perses.fullname" . }}-datasources
|
||||
{{- end }}
|
||||
{{- if and .Values.sidecar.enabled (not .Values.provisioningPersistence.enabled) }}
|
||||
- name: provisioning
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- if .Values.tls.enabled }}
|
||||
{{- if .Values.tls.caCert.enabled }}
|
||||
- name: ca-cert
|
||||
secret:
|
||||
secretName: {{ .Values.tls.caCert.secretName | default (printf "%s-tls" (include "perses.fullname" .)) }}
|
||||
defaultMode: 420
|
||||
{{- end }}
|
||||
{{- if .Values.tls.clientCert.enabled }}
|
||||
- name: client-cert
|
||||
secret:
|
||||
secretName: {{ .Values.tls.clientCert.secretName | default (printf "%s-tls" (include "perses.fullname" .)) }}
|
||||
defaultMode: 420
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if or .Values.affinity .Values.podAntiAffinity }}
|
||||
affinity:
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if eq .Values.podAntiAffinity "hard" }}
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- topologyKey: {{ .Values.podAntiAffinityTopologyKey }}
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- {key: app.kubernetes.io/name, operator: In, values: [{{ template "perses.name" . }}]}
|
||||
{{- else if eq .Values.podAntiAffinity "soft" }}
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
topologyKey: {{ .Values.podAntiAffinityTopologyKey }}
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- {key: app.kubernetes.io/name, operator: In, values: [{{ template "perses.name" . }}]}
|
||||
{{- end }}
|
||||
{{- with .Values.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.provisioningPersistence.enabled }}
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: provisioning
|
||||
{{- with .Values.provisioningPersistence.labels }}
|
||||
labels:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- with .Values.provisioningPersistence.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
{{- range .Values.provisioningPersistence.accessModes }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.provisioningPersistence.size | quote }}
|
||||
{{- if .Values.provisioningPersistence.storageClass }}
|
||||
storageClassName: {{ .Values.provisioningPersistence.storageClass | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,75 @@
|
||||
{{- if .Values.testFramework.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-test
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
type: helm-chart-test
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded"
|
||||
data:
|
||||
run.sh: |-
|
||||
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load "/usr/lib/bats/bats-detik/utils"
|
||||
load "/usr/lib/bats/bats-detik/detik"
|
||||
|
||||
DETIK_CLIENT_NAME="kubectl"
|
||||
|
||||
|
||||
@test "Verify that there is a service named {{ include "perses.fullname" . }}" {
|
||||
verify "there is 1 service named '^{{ include "perses.fullname" . }}$'"
|
||||
}
|
||||
|
||||
@test "Verify that there is a configmap named {{ include "perses.fullname" . }}" {
|
||||
verify "there is 1 configmap named '^{{ include "perses.fullname" . }}$'"
|
||||
}
|
||||
|
||||
{{- if .Values.config.database.file }}
|
||||
@test "Verify successful statefulset and running status of the {{ .Release.Name }} pod" {
|
||||
verify "there is 1 statefulset named '{{ include "perses.fullname" . }}'"
|
||||
try "at most 3 times every 20s to get pods named '{{ include "perses.fullname" . }}.*' and verify that '.status.phase' is 'running'"
|
||||
}
|
||||
{{- end -}}
|
||||
|
||||
{{- if .Values.config.database.sql }}
|
||||
@test "Verify successful deployment and running status of the {{ .Release.Name }} pod" {
|
||||
verify "there is 1 deployment named '{{ include "perses.fullname" . }}'"
|
||||
try "at most 3 times every 20s to get pods named '{{ include "perses.fullname" . }}.*' and verify that '.status.phase' is 'running'"
|
||||
}
|
||||
{{- end -}}
|
||||
|
||||
{{- if .Values.persistence.enabled }}
|
||||
@test "Verify successful creation and bound status of {{ include "perses.fullname" . }} persistent volume claims" {
|
||||
try "at most 3 times every 5s to get persistentvolumeclaims named '{{ include "perses.fullname" . }}.*' and verify that '.status.phase' is 'Bound'"
|
||||
}
|
||||
{{- end -}}
|
||||
|
||||
{{- if .Values.ingress.enabled }}
|
||||
@test "Verify successful creation of ingress resource" {
|
||||
verify "there is 1 ingress named '^{{ include "perses.fullname" . }}$'"
|
||||
}
|
||||
{{- end -}}
|
||||
|
||||
{{- if and .Values.gateway.enabled .Values.gateway.createGateway }}
|
||||
@test "Verify successful creation of gateway resource" {
|
||||
verify "there is 1 gateways.gateway.networking.k8s.io named '^{{ default (printf "%s-gateway" (include "perses.fullname" .)) .Values.gateway.name }}$'"
|
||||
}
|
||||
{{- end -}}
|
||||
|
||||
{{- if .Values.gateway.enabled }}
|
||||
@test "Verify successful creation of HTTPRoute resource" {
|
||||
verify "there is 1 httproutes.gateway.networking.k8s.io named '^{{ default (printf "%s-http-route" (include "perses.fullname" .)) .Values.gateway.httpRoute.name }}$'"
|
||||
}
|
||||
{{- end -}}
|
||||
|
||||
{{ if .Values.serviceMonitor.selfMonitor }}
|
||||
@test "Verify succesful creation of ServiceMonitor" {
|
||||
verify "there is 1 servicemonitor named '^{{ include "perses.fullname" . }}$'"
|
||||
}
|
||||
{{ end }}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,57 @@
|
||||
{{- if .Values.testFramework.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-test
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
type: helm-chart-test
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-test
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
type: helm-chart-test
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["statefulsets","deployments"]
|
||||
verbs: ["get", "list"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods", "persistentvolumeclaims", "services", "configmaps"]
|
||||
verbs: ["get", "list"]
|
||||
- apiGroups: ["networking.k8s.io"]
|
||||
resources: ["ingresses"]
|
||||
verbs: ["get", "list"]
|
||||
{{- if .Values.gateway.enabled }}
|
||||
- apiGroups: ["gateway.networking.k8s.io"]
|
||||
resources: ["gateways", "httproutes"]
|
||||
verbs: ["get", "list"]
|
||||
{{- end }}
|
||||
{{- if .Values.serviceMonitor.selfMonitor }}
|
||||
- apiGroups: ["monitoring.coreos.com"]
|
||||
resources: ["servicemonitors"]
|
||||
verbs: ["get", "list"]
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-test
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
type: helm-chart-test
|
||||
{{- include "perses.labels" . | nindent 4 }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Release.Name }}-test
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: {{ .Release.Name }}-test
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
---
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,28 @@
|
||||
{{- if .Values.testFramework.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-test
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
type: helm-chart-test
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded"
|
||||
spec:
|
||||
serviceAccountName: {{ .Release.Name }}-test
|
||||
containers:
|
||||
- name: bats-test
|
||||
image: "{{ .Values.testFramework.image.registry}}/{{ .Values.testFramework.image.repository}}:{{ .Values.testFramework.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.testFramework.image.pullPolicy }}
|
||||
command: ["bats", "-t", "/tests/run.sh"]
|
||||
volumeMounts:
|
||||
- name: tests
|
||||
mountPath: /tests
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: tests
|
||||
configMap:
|
||||
name: {{ .Release.Name }}-test
|
||||
restartPolicy: Never
|
||||
{{- end -}}
|
||||
Reference in New Issue
Block a user