Merge pull request #524 from samuelattwood/main

Release Partner Charts
pull/531/head
Samuel Attwood 2022-09-29 17:52:48 -04:00 committed by GitHub
commit 90e2e25c00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
381 changed files with 50179 additions and 0 deletions

Binary file not shown.

BIN
assets/k10/k10-5.0.900.tgz Normal file

Binary file not shown.

View File

@ -0,0 +1,25 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
tests/

View File

@ -0,0 +1,23 @@
annotations:
catalog.cattle.io/certified: partner
catalog.cattle.io/display-name: Dynatrace Operator
catalog.cattle.io/kube-version: '>=1.21.0-0'
catalog.cattle.io/release-name: dynatrace-operator
apiVersion: v2
appVersion: 0.9.0
description: The Dynatrace Operator Helm chart for Kubernetes and OpenShift
home: https://www.dynatrace.com/
icon: https://assets.dynatrace.com/global/resources/Signet_Logo_RGB_CP_512x512px.png
kubeVersion: '>=1.21.0-0'
maintainers:
- email: marcell.sevcsik@dynatrace.com
name: 0sewa0
- email: christoph.muellner@dynatrace.com
name: chrismuellner
- email: lukas.hinterreiter@dynatrace.com
name: luhi-DT
name: dynatrace-operator
sources:
- https://github.com/Dynatrace/dynatrace-operator
type: application
version: 0.9.0

View File

@ -0,0 +1,33 @@
# Dynatrace Operator Helm Chart
The Dynatrace Operator supports rollout and lifecycle of various Dynatrace components in Kubernetes and OpenShift.
This Helm Chart requires Helm 3.
## Quick Start
Migration instructions can be found in the [official help page](https://www.dynatrace.com/support/help/shortlink/k8s-dto-helm#migrate).
Install the Dynatrace Operator via Helm by running the following commands.
### Installation
> For instructions on how to install the dynatrace-operator on Openshift, head to the
> [official help page](https://www.dynatrace.com/support/help/shortlink/k8s-helm)
Add `dynatrace` helm repository:
```
helm repo add dynatrace https://raw.githubusercontent.com/Dynatrace/dynatrace-operator/master/config/helm/repos/stable
```
Install `dynatrace-operator` helm chart and create the corresponding `dynatrace` namespace:
```console
helm install dynatrace-operator dynatrace/dynatrace-operator -n dynatrace --create-namespace --atomic
```
## Uninstall chart
> Full instructions can be found in the [official help page](https://www.dynatrace.com/support/help/shortlink/k8s-helm#uninstall-dynatrace-operator)
Uninstall the Dynatrace Operator by running the following command:
```console
helm uninstall dynatrace-operator -n dynatrace
```

View File

@ -0,0 +1,5 @@
# Dynatrace Operator
The Dynatrace Operator supports rollout and lifecycle of various Dynatrace components in Kubernetes and OpenShift.
As of launch, the Dynatrace Operator can be used to deploy a containerized ActiveGate for Kubernetes API monitoring. New capabilities will be added to the Dynatrace Operator over time including metric routing, and API monitoring for AWS, Azure, GCP, and vSphere.

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@ -0,0 +1,250 @@
categories:
- APM
- Monitoring
questions:
#################### Global Configuration ####################
- variable: installCRD
label: "Install Custom Resource Definitions"
description: "Installs the Custom Resource Definitions for the Dynakube. This is recommended if you haven't installed it manually yet. Default: true"
default: true
type: boolean
group: "Global Configuration"
- variable: image
label: "Set a custom image for operator components"
description: "Set a custom image for operator. Defaults to docker.io/dynatrace/dynatrace-operator"
default: ""
type: string
group: "Global Configuration"
- variable: customPullSecret
label: "Set a custom pull secret for operator image"
description: "Set a custom pull secret for the operator image"
default: ""
type: string
group: "Global Configuration"
#################### Operator Deployment Configuration ####################
- variable: operator.nodeSelector
label: "Assign the Dynatrace Operator's pod to certain nodes"
description: "Defines a NodeSelector to customize to which nodes the Dynatrace Operator can be deployed on - Please edit as Yaml for the best experience - see https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector"
default: ""
type: string
group: "Operator Deployment Configuration"
- variable: operator.tolerations
label: "Custom tolerations for the Dynatrace Operator's pod"
description: "Defines custom tolerations to the Dynatrace Operator - Please edit as Yaml for the best experience - see https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/"
default: ""
type: string
group: "Operator Deployment Configuration"
- variable: operator.apparmor
label: "Enable AppArmor for the Dynatrace Operator's pod"
description: "Adds AppArmor security annotations to the Dynatrace Operator's pod. Default: false"
default: false
type: boolean
group: "Operator Deployment Configuration"
- variable: operator.requests.cpu
label: "CPU resource requests settings for Dynatrace Operator's pods"
description: "The minimum amount of CPU resources that the Dynatrace Operator's pods should request. Affects scheduling. Default: 50m"
default: "50m"
type: string
group: "Operator Deployment Configuration"
- variable: operator.requests.memory
label: "Memory resource requests settings for Dynatrace Operator's pods"
description: "The minimum amount of memory that the Dynatrace Operator's pods should request. Affects scheduling. Default: 64Mi"
default: "64Mi"
type: string
group: "Operator Deployment Configuration"
- variable: operator.limits.cpu
label: "CPU resource limits settings for Dynatrace Operator's pods"
description: "The maximum amount of CPU resources that the Dynatrace Operator's pods can use. Default: 100m"
default: "100m"
type: string
group: "Operator Deployment Configuration"
- variable: operator.limits.memory
label: "Memory resource limits settings for Dynatrace Operator's pods"
description: "The maximum amount of memory that the Dynatrace Operator's pods can use. Pod restarted if exceeded. Default: 128Mi"
default: "128Mi"
type: string
group: "Operator Deployment Configuration"
#################### Webhook Deployment Configuration ####################
- variable: webhook.apparmor
label: "Enable AppArmor for the Dynatrace Webhook's pod"
description: "Adds AppArmor security annotations to the Dynatrace Webhook's pod. Default: false"
default: false
type: boolean
group: "Webhook Deployment Configuration"
- variable: webhook.highAvailability
label: "Enable high availability for the Dynatrace Webhook's pod"
description: "Adds topologySpreadConstraints and increases the replicas to 2 for the Dynatrace Webhook's pod. Default: false"
default: false
type: boolean
group: "Webhook Deployment Configuration"
- variable: webhook.hostNetwork
label: "Enable hostNetwork for the Dynatrace Webhook's pod"
description: "Enables hostNetwork for the Dynatrace Webhook's pod. Default: false"
default: false
type: boolean
group: "Webhook Deployment Configuration"
- variable: webhook.requests.cpu
label: "CPU resource requests settings for Dynatrace Webhook's pods"
description: "The minimum amount of CPU resources that the Dynatrace Webhook's pods should request. Affects scheduling. Default: 300m"
default: "300m"
type: string
group: "Webhook Deployment Configuration"
- variable: webhook.requests.memory
label: "Memory resource requests settings for Dynatrace Webhook's pods"
description: "The minimum amount of memory that the Dynatrace Webhook's pods should request. Affects scheduling. Default: 128Mi"
default: "128Mi"
type: string
group: "Webhook Deployment Configuration"
- variable: webhook.limits.cpu
label: "CPU resource limits settings for Dynatrace Webhook's pods"
description: "The maximum amount of CPU resources that the Dynatrace Webhook's pods can use. Default: 300m"
default: "300m"
type: string
group: "Webhook Deployment Configuration"
- variable: webhook.limits.memory
label: "Memory resource limits settings for Dynatrace Webhook's pods"
description: "The maximum amount of memory that the Dynatrace Webhook's pods can use. Pod restarted if exceeded. Default: 128Mi"
default: "128Mi"
type: string
group: "Webhook Deployment Configuration"
#################### CSI Driver Deployment Configuration ####################
- variable: csidriver.enabled
label: "Deploy the Dynatrace CSI Driver"
description: "Deploys the Dynatrace CSI Driver via a DaemonSet to enable Cloud Native FullStack. Default: false"
default: false
type: boolean
group: "CSI Driver Deployment Configuration"
- variable: csidriver.server.requests.cpu
label: "CPU resource requests settings for Dynatrace CSI Driver's server container"
description: "The minimum amount of CPU resources that the Dynatrace CSI Driver's server container should request. Affects scheduling. Default: 50m"
default: "50m"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.server.requests.memory
label: "Memory resource requests settings for Dynatrace CSI Driver's server container"
description: "The minimum amount of memory that the Dynatrace CSI Driver's server container should request. Affects scheduling. Default: 100Mi"
default: "100Mi"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.server.limits.cpu
label: "CPU resource limits settings for Dynatrace CSI Driver's server container"
description: "The maximum amount of CPU resources that the Dynatrace CSI Driver's server container can use. Default: 50m"
default: "50m"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.server.limits.memory
label: "Memory resource limits settings for Dynatrace CSI Driver's server container"
description: "The maximum amount of memory that the Dynatrace CSI Driver's server container can use. Pod restarted if exceeded. Default: 100Mi"
default: "100Mi"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.provisioner.requests.cpu
label: "CPU resource requests settings for Dynatrace CSI Driver's provisioner container"
description: "The minimum amount of CPU resources that the Dynatrace CSI Driver's provisioner container should request. Affects scheduling. Default: 300m"
default: "300m"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.provisioner.requests.memory
label: "Memory resource requests settings for Dynatrace CSI Driver's provisioner container"
description: "The minimum amount of memory that the Dynatrace CSI Driver's provisioner container should request. Affects scheduling. Default: 100Mi"
default: "100Mi"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.provisioner.limits.cpu
label: "CPU resource limits settings for Dynatrace CSI Driver's provisioner container"
description: "The maximum amount of CPU resources that the Dynatrace CSI Driver's provisioner container can use. Default: 300m"
default: "300m"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.provisioner.limits.memory
label: "Memory resource limits settings for Dynatrace CSI Driver's provisioner container"
description: "The maximum amount of memory that the Dynatrace CSI Driver's provisioner container can use. Pod restarted if exceeded. Default: 100Mi"
default: "100Mi"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.registrar.requests.cpu
label: "CPU resource requests settings for Dynatrace CSI Driver's registrar container"
description: "The minimum amount of CPU resources that the Dynatrace CSI Driver's registrar container should request. Affects scheduling. Default: 20m"
default: "20m"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.registrar.requests.memory
label: "Memory resource requests settings for Dynatrace CSI Driver's registrar container"
description: "The minimum amount of memory that the Dynatrace CSI Driver's registrar container should request. Affects scheduling. Default: 30Mi"
default: "30Mi"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.registrar.limits.cpu
label: "CPU resource limits settings for Dynatrace CSI Driver's registrar container"
description: "The maximum amount of CPU resources that the Dynatrace CSI Driver's registrar container can use. Default: 20m"
default: "20m"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.registrar.limits.memory
label: "Memory resource limits settings for Dynatrace CSI Driver's registrar container"
description: "The maximum amount of memory that the Dynatrace CSI Driver's registrar container can use. Pod restarted if exceeded. Default: 30Mi"
default: "30Mi"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.livenessprobe.requests.cpu
label: "CPU resource requests settings for Dynatrace CSI Driver's livenessprobe container"
description: "The minimum amount of CPU resources that the Dynatrace CSI Driver's livenessprobe container should request. Affects scheduling. Default: 20m"
default: "20m"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.livenessprobe.requests.memory
label: "Memory resource requests settings for Dynatrace CSI Driver's livenessprobe container"
description: "The minimum amount of memory that the Dynatrace CSI Driver's livenessprobe container should request. Affects scheduling. Default: 30Mi"
default: "30Mi"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.livenessprobe.limits.cpu
label: "CPU resource limits settings for Dynatrace CSI Driver's livenessprobe container"
description: "The maximum amount of CPU resources that the Dynatrace CSI Driver's livenessprobe container can use. Default: 20m"
default: "20m"
type: string
group: "CSI Driver Deployment Configuration"
- variable: csidriver.livenessprobe.limits.memory
label: "Memory resource limits settings for Dynatrace CSI Driver's livenessprobe container"
description: "The maximum amount of memory that the Dynatrace CSI Driver's livenessprobe container can use. Pod restarted if exceeded. Default: 30Mi"
default: "30Mi"
type: string
group: "CSI Driver Deployment Configuration"

View File

@ -0,0 +1,35 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if eq (default false .Values.olm) true}}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dynatrace-activegate
labels:
{{- include "dynatrace-operator.activegateLabels" . | nindent 4 }}
rules:
- apiGroups:
- security.openshift.io
resourceNames:
- host
- privileged
resources:
- securitycontextconstraints
verbs:
- use
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,32 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if eq (default false .Values.olm) true}}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dynatrace-activegate
labels:
{{- include "dynatrace-operator.activegateLabels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: dynatrace-activegate
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
name: dynatrace-activegate
apiGroup: rbac.authorization.k8s.io
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,23 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
name: dynatrace-activegate
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.activegateLabels" . | nindent 4 }}
{{ end }}

View File

@ -0,0 +1,4 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if and .Values.installCRD (eq (include "dynatrace-operator.partial" .) "false") }}
{{ .Files.Get "generated/dynatrace-operator-crd.yaml" }}
{{- end -}}

View File

@ -0,0 +1,65 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.needCSI" .) "true" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dynatrace-oneagent-csi-driver
labels:
{{- include "dynatrace-operator.csiLabels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- list
- watch
- create
- update
- patch
- apiGroups:
- storage.k8s.io
resources:
- csinodes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
{{- end -}}

View File

@ -0,0 +1,30 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.needCSI" .) "true" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dynatrace-oneagent-csi-driver
labels:
{{- include "dynatrace-operator.csiLabels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: dynatrace-oneagent-csi-driver
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
name: dynatrace-oneagent-csi-driver
apiGroup: rbac.authorization.k8s.io
{{- end -}}

View File

@ -0,0 +1,27 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.needCSI" .) "true" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:
name: csi.oneagent.dynatrace.com
labels:
{{- include "dynatrace-operator.csiLabels" . | nindent 4 }}
spec:
attachRequired: false
podInfoOnMount: true
volumeLifecycleModes:
- Ephemeral
{{- end -}}

View File

@ -0,0 +1,293 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.needCSI" .) "true" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
{{- include "dynatrace-operator.csiLabels" . | nindent 4 }}
{{- if .Values.csidriver.labels }}
{{- toYaml .Values.csidriver.labels | nindent 4 }}
{{- end}}
name: dynatrace-oneagent-csi-driver
namespace: {{ .Release.Namespace }}
spec:
revisionHistoryLimit: 10
selector:
matchLabels:
{{- include "dynatrace-operator.csiSelectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
kubectl.kubernetes.io/default-container: provisioner
cluster-autoscaler.kubernetes.io/enable-ds-eviction: "false"
{{- if and (eq (default false .Values.apparmor) true) (ne .Values.platform "openshift") }}
container.apparmor.security.beta.kubernetes.io/driver: runtime/default
container.apparmor.security.beta.kubernetes.io/registrar: runtime/default
container.apparmor.security.beta.kubernetes.io/liveness-probe: runtime/default
{{- end}}
{{- if .Values.csidriver.annotations }}
{{- toYaml .Values.csidriver.annotations | nindent 8 }}
{{- end }}
labels:
{{- include "dynatrace-operator.csiLabels" . | nindent 8 }}
{{- include "dynatrace-operator.csiSelectorLabels" . | nindent 8 }}
{{- if .Values.csidriver.labels }}
{{- toYaml .Values.csidriver.labels | nindent 8 }}
{{- end }}
spec:
containers:
# Used to receive/execute gRPC requests (NodePublishVolume/NodeUnpublishVolume) from kubelet to mount/unmount volumes for a pod
# - Needs access to the csi socket, needs to read/write to it, needs root permissions to do so.
# - Needs access to the filesystem of pods on the node, and mount stuff to it,needs to read/write to it, needs root permissions to do so
# - Needs access to a dedicated folder on the node to persist data, needs to read/write to it.
- name: server
image: {{ include "dynatrace-operator.image" . }}
imagePullPolicy: Always
args:
- csi-server
- --endpoint=unix://csi/csi.sock
- --node-id=$(KUBE_NODE_NAME)
- --health-probe-bind-address=:10080
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: KUBE_NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
livenessProbe:
failureThreshold: 3
httpGet:
path: /livez
port: livez
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
ports:
- containerPort: 10080
name: livez
protocol: TCP
resources:
{{- if .Values.csidriver.server.resources }}
{{- toYaml .Values.csidriver.server.resources | nindent 10 }}
{{- end }}
securityContext:
runAsUser: 0
privileged: true # Needed for mountPropagation
allowPrivilegeEscalation: true # Needed for privileged
readOnlyRootFilesystem: true
runAsNonRoot: false
seccompProfile:
type: RuntimeDefault
seLinuxOptions:
level: s0
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /csi
name: plugin-dir
- mountPath: {{ include "dynatrace-operator.CSIMountPointDir" . }}
mountPropagation: Bidirectional
name: mountpoint-dir
- mountPath: /data
name: plugin-dir
subPath: data
mountPropagation: Bidirectional
- name: tmp-dir
mountPath: /tmp
- name: provisioner
image: {{ include "dynatrace-operator.image" . }}
imagePullPolicy: Always
args:
- csi-provisioner
- --health-probe-bind-address=:10090
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
livenessProbe:
failureThreshold: 3
httpGet:
path: /livez
port: livez
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
ports:
- containerPort: 10090
name: livez
protocol: TCP
resources:
{{- if .Values.csidriver.provisioner.resources }}
{{- toYaml .Values.csidriver.provisioner.resources | nindent 10 }}
{{- end }}
securityContext:
runAsUser: 0
privileged: true # Needed for mountPropagation
allowPrivilegeEscalation: true # Needed for privileged
readOnlyRootFilesystem: true
runAsNonRoot: false
seccompProfile:
type: RuntimeDefault
seLinuxOptions:
level: s0
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data
name: plugin-dir
subPath: data
mountPropagation: Bidirectional
- mountPath: /tmp
name: tmp-dir
# Used to make a gRPC request (GetPluginInfo()) to the driver to get driver name and driver contain
# - Needs access to the csi socket, needs to read/write to it, needs root permissions to do so.
# Used for registering the driver with kubelet
# - Needs access to the registration socket, needs to read/write to it, needs root permissions to do so.
- name: registrar
image: {{ include "dynatrace-operator.image" . }}
imagePullPolicy: Always
env:
- name: DRIVER_REG_SOCK_PATH
value: {{ include "dynatrace-operator.CSISocketPath" . }}
args:
- --csi-address=/csi/csi.sock
- --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)
command:
- csi-node-driver-registrar
livenessProbe:
exec:
command:
- csi-node-driver-registrar
- --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)
- --mode=kubelet-registration-probe
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 15
resources:
{{- if .Values.csidriver.registrar.resources }}
{{- toYaml .Values.csidriver.registrar.resources | nindent 10 }}
{{- end }}
securityContext:
runAsUser: 0
privileged: false
readOnlyRootFilesystem: true
runAsNonRoot: false
seccompProfile:
type: RuntimeDefault
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /csi
name: plugin-dir
- mountPath: /registration
name: registration-dir
- mountPath: {{ include "dynatrace-operator.CSIPluginDir" . }}
name: lockfile-dir
# Used to make a gRPC request (Probe()) to the driver to check if its running
# - Needs access to the csi socket, needs to read/write to it, needs root permissions to do so.
- name: liveness-probe
image: {{ include "dynatrace-operator.image" . }}
imagePullPolicy: Always
args:
- --csi-address=/csi/csi.sock
- --health-port=9898
command:
- livenessprobe
resources:
{{- if .Values.csidriver.livenessprobe.resources }}
{{- toYaml .Values.csidriver.livenessprobe.resources | nindent 10 }}
{{- end }}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
securityContext:
runAsUser: 0
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: false
seccompProfile:
type: RuntimeDefault
volumeMounts:
- mountPath: /csi
name: plugin-dir
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccountName: dynatrace-oneagent-csi-driver
terminationGracePeriodSeconds: 30
priorityClassName: dynatrace-high-priority
volumes:
# This volume is where the registrar registers the plugin with kubelet
- name: registration-dir
hostPath:
path: {{ include "dynatrace-operator.CSIRegistrationDir" . }}
type: Directory
# This volume is where the socket for kubelet->driver communication is done
- name: plugin-dir
hostPath:
path: {{ include "dynatrace-operator.CSIPluginDir" . }}
type: DirectoryOrCreate
# This volume is where the driver mounts volumes
- name: mountpoint-dir
hostPath:
path: {{ include "dynatrace-operator.CSIMountPointDir" . }}
type: DirectoryOrCreate
# Used by the registrar to create its lockfile
- name: lockfile-dir
emptyDir: {}
# A volume for the driver to write temporary files to
- name: tmp-dir
emptyDir: {}
{{- if .Values.customPullSecret }}
imagePullSecrets:
- name: {{ .Values.customPullSecret }}
{{- end }}
{{- if .Values.csidriver.nodeSelector }}
nodeSelector: {{- toYaml .Values.csidriver.nodeSelector | nindent 8 }}
{{- end }}
tolerations:
{{- if .Values.csidriver.tolerations }}
{{- toYaml .Values.csidriver.tolerations | nindent 8 }}
{{- end }}
- key: kubernetes.io/arch
value: arm64
effect: NoSchedule
- key: kubernetes.io/arch
value: amd64
effect: NoSchedule
- key: ToBeDeletedByClusterAutoscaler
operator: Exists
effect: NoSchedule
updateStrategy:
rollingUpdate:
maxUnavailable: 1
type: RollingUpdate
{{- end -}}

View File

@ -0,0 +1,24 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.needCSI" .) "true" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
kind: PriorityClass
apiVersion: scheduling.k8s.io/v1
metadata:
name: dynatrace-high-priority
value: {{ default 1000000 (int (.Values.csidriver).priorityClassValue) }}
globalDefault: false
description: "This priority class is used for Dynatrace Components in order to make sure they are not evicted in favor of other pods"
{{- end -}}

View File

@ -0,0 +1,70 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.needCSI" .) "true" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dynatrace-oneagent-csi-driver
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.csiLabels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
- watch
- list
- delete
- update
- create
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- watch
- list
- delete
- update
- create
- apiGroups:
- dynatrace.com
resources:
- dynakubes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
{{- end -}}

View File

@ -0,0 +1,31 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.needCSI" .) "true" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dynatrace-oneagent-csi-driver
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.csiLabels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: dynatrace-oneagent-csi-driver
namespace: {{ .Release.Namespace }}
roleRef:
kind: Role
name: dynatrace-oneagent-csi-driver
apiGroup: rbac.authorization.k8s.io
{{- end -}}

View File

@ -0,0 +1,23 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.needCSI" .) "true" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
name: dynatrace-oneagent-csi-driver
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.csiLabels" . | nindent 4 }}
{{- end -}}

View File

@ -0,0 +1,94 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: dynatrace-kubernetes-monitoring
labels:
{{- include "dynatrace-operator.activegateLabels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- nodes
- pods
- namespaces
- replicationcontrollers
- events
- resourcequotas
- pods/proxy
- nodes/proxy
- nodes/metrics
- services
verbs:
- list
- watch
- get
- apiGroups:
- batch
resources:
- jobs
- cronjobs
verbs:
- list
- watch
- get
- apiGroups:
- apps
resources:
- deployments
- replicasets
- statefulsets
- daemonsets
verbs:
- list
- watch
- get
- apiGroups:
- apps.openshift.io
resources:
- deploymentconfigs
verbs:
- list
- watch
- get
- apiGroups:
- config.openshift.io
resources:
- clusterversions
verbs:
- list
- watch
- get
- nonResourceURLs:
- /metrics
- /version
- /readyz
- /livez
verbs:
- get
{{- if eq (default false .Values.olm) true}}
- apiGroups:
- security.openshift.io
resourceNames:
- host
- privileged
resources:
- securitycontextconstraints
verbs:
- use
{{ end }}
{{ end }}

View File

@ -0,0 +1,30 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dynatrace-kubernetes-monitoring
labels:
{{- include "dynatrace-operator.activegateLabels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: dynatrace-kubernetes-monitoring
subjects:
- kind: ServiceAccount
name: dynatrace-kubernetes-monitoring
namespace: {{ .Release.Namespace }}
{{ end }}

View File

@ -0,0 +1,23 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
name: dynatrace-kubernetes-monitoring
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.activegateLabels" . | nindent 4 }}
{{ end }}

View File

@ -0,0 +1,32 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if (eq (include "dynatrace-operator.openshiftOrOlm" .) "true") }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: dynatrace-dynakube-oneagent-privileged
labels:
{{- include "dynatrace-operator.oneagentLabels" . | nindent 4 }}
rules:
- apiGroups:
- security.openshift.io
resourceNames:
- host
- privileged
resources:
- securitycontextconstraints
verbs:
- use
{{ end }}

View File

@ -0,0 +1,32 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if (eq (include "dynatrace-operator.openshiftOrOlm" .) "true") }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: dynatrace-dynakube-oneagent-unprivileged
labels:
{{- include "dynatrace-operator.oneagentLabels" . | nindent 4 }}
rules:
- apiGroups:
- security.openshift.io
resourceNames:
- host
- privileged
resources:
- securitycontextconstraints
verbs:
- use
{{ end }}

View File

@ -0,0 +1,30 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if (eq (include "dynatrace-operator.openshiftOrOlm" .) "true") }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dynatrace-dynakube-oneagent-privileged
labels:
{{- include "dynatrace-operator.oneagentLabels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: "dynatrace-dynakube-oneagent-privileged"
namespace: {{ .Release.Namespace }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: "dynatrace-dynakube-oneagent-privileged"
{{ end }}

View File

@ -0,0 +1,30 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if (eq (include "dynatrace-operator.openshiftOrOlm" .) "true") }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dynatrace-dynakube-oneagent-unprivileged
labels:
{{- include "dynatrace-operator.oneagentLabels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: dynatrace-dynakube-oneagent-unprivileged
namespace: {{ .Release.Namespace }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: dynatrace-dynakube-oneagent-unprivileged
{{ end }}

View File

@ -0,0 +1,29 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
name: dynatrace-dynakube-oneagent-privileged
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.oneagentLabels" . | nindent 4 }}
automountServiceAccountToken: false
{{- if eq .Values.platform "openshift"}}
imagePullSecrets:
- name: redhat-connect
- name: redhat-connect-sso
{{- end }}
{{ end }}

View File

@ -0,0 +1,29 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
name: dynatrace-dynakube-oneagent-unprivileged
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.oneagentLabels" . | nindent 4 }}
automountServiceAccountToken: false
{{- if eq .Values.platform "openshift"}}
imagePullSecrets:
- name: redhat-connect
- name: redhat-connect-sso
{{- end }}
{{ end }}

View File

@ -0,0 +1,103 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ .Release.Name }}
labels:
{{- include "dynatrace-operator.operatorLabels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- update
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- apiGroups:
- ""
resources:
- secrets
resourceNames:
- dynatrace-dynakube-config
- dynatrace-data-ingest-endpoint
- dynatrace-activegate-internal-proxy
verbs:
- get
- update
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- admissionregistration.k8s.io
resources:
- mutatingwebhookconfigurations
resourceNames:
- dynatrace-webhook
verbs:
- get
- update
- apiGroups:
- admissionregistration.k8s.io
resources:
- validatingwebhookconfigurations
resourceNames:
- dynatrace-webhook
verbs:
- get
- update
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
resourceNames:
- dynakubes.dynatrace.com
verbs:
- get
- update
{{- if eq (default false .Values.olm) true}}
- apiGroups:
- security.openshift.io
resourceNames:
- host
- privileged
resources:
- securitycontextconstraints
verbs:
- use
{{ end }}
{{ end }}

View File

@ -0,0 +1,30 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ .Release.Name }}
labels:
{{- include "dynatrace-operator.operatorLabels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: {{ .Release.Name }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
name: {{ .Release.Name }}
apiGroup: rbac.authorization.k8s.io
{{ end }}

View File

@ -0,0 +1,142 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.operatorLabels" . | nindent 4 }}
{{- if .Values.operator.labels }}
{{- toYaml .Values.operator.labels | nindent 4 }}
{{- end }}
spec:
replicas: 1
revisionHistoryLimit: 1
selector:
matchLabels:
{{- include "dynatrace-operator.operatorSelectorLabels" . | nindent 6 }}
strategy:
type: RollingUpdate
template:
metadata:
{{- if or (.Values.operator).apparmor .Values.operator.annotations }}
annotations:
{{- if (.Values.operator).apparmor}}
container.apparmor.security.beta.kubernetes.io/{{ .Release.Name }}: runtime/default
{{- end }}
{{- if .Values.operator.annotations }}
{{- toYaml .Values.operator.annotations | nindent 8 }}
{{- end }}
{{- end }}
labels:
{{- include "dynatrace-operator.operatorLabels" . | nindent 8 }}
{{- include "dynatrace-operator.operatorSelectorLabels" . | nindent 8 }}
{{- if .Values.operator.labels }}
{{- toYaml .Values.operator.labels | nindent 8 }}
{{- end }}
spec:
containers:
- name: {{ .Release.Name }}
args:
- operator
# Replace this with the built image name
image: {{ include "dynatrace-operator.image" . }}
imagePullPolicy: Always
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- containerPort: 10080
name: server-port
resources:
requests:
{{- toYaml (.Values.operator).requests | nindent 14 }}
limits:
{{- toYaml (.Values.operator).limits | nindent 14 }}
volumeMounts:
- name: tmp-cert-dir
mountPath: /tmp/dynatrace-operator
readinessProbe:
httpGet:
path: /livez
port: server-port
scheme: HTTP
initialDelaySeconds: 15
periodSeconds: 10
livenessProbe:
httpGet:
path: /livez
port: server-port
scheme: HTTP
initialDelaySeconds: 15
periodSeconds: 10
securityContext:
seccompProfile:
type: RuntimeDefault
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001
runAsGroup: 1001
capabilities:
drop:
- ALL
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
{{- if ne .Values.platform "gke-autopilot"}}
- key: kubernetes.io/arch
operator: In
values:
- amd64
- arm64
{{- end }}
- key: kubernetes.io/os
operator: In
values:
- linux
volumes:
- emptyDir: { }
name: tmp-cert-dir
serviceAccountName: {{ .Release.Name }}
{{- if .Values.customPullSecret }}
imagePullSecrets:
- name: {{ .Values.customPullSecret }}
{{- end }}
{{- if .Values.operator.nodeSelector }}
nodeSelector: {{- toYaml .Values.operator.nodeSelector | nindent 8 }}
{{- end }}
tolerations:
{{- if .Values.operator.tolerations }}
{{- toYaml .Values.operator.tolerations | nindent 8 }}
{{- end }}
- key: kubernetes.io/arch
value: arm64
effect: NoSchedule
- key: kubernetes.io/arch
value: amd64
effect: NoSchedule
{{ end }}

View File

@ -0,0 +1,159 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ .Release.Name }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.operatorLabels" . | nindent 4 }}
rules:
- apiGroups:
- dynatrace.com
resources:
- dynakubes
verbs:
- get
- list
- watch
- update
- create
- apiGroups:
- dynatrace.com
resources:
- dynakubes/finalizers
- dynakubes/status
verbs:
- update
- apiGroups:
- apps
resources:
- statefulsets
verbs:
- get
- list
- watch
- create
- update
- delete
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
- list
- watch
- create
- update
- delete
- apiGroups:
- apps
resources:
- replicasets
- deployments
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- deployments/finalizers
verbs:
- update
- apiGroups:
- "" # "" indicates the core API group
resources:
- configmaps
verbs:
- get
- list
- watch
- create
- update
- delete
- apiGroups:
- "" # "" indicates the core API group
resources:
- pods
verbs:
- get
- list
- watch
- delete
- create
- apiGroups:
- "" # "" indicates the core API group
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- list
- create
- apiGroups:
- ""
resources:
- services
verbs:
- create
- update
- delete
- get
- list
- watch
- apiGroups:
- monitoring.coreos.com
resources:
- servicemonitors
verbs:
- get
- create
- apiGroups:
- networking.istio.io
resources:
- serviceentries
- virtualservices
verbs:
- get
- list
- create
- update
- delete
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- update
- create
{{ end }}

View File

@ -0,0 +1,30 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ .Release.Name }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.operatorLabels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: {{ .Release.Name }}
roleRef:
kind: Role
name: {{ .Release.Name }}
apiGroup: rbac.authorization.k8s.io
{{ end }}

View File

@ -0,0 +1,29 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Release.Name }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.operatorLabels" . | nindent 4 }}
{{ if eq .Values.platform "openshift" }}
imagePullSecrets:
- name: redhat-connect
- name: redhat-connect-sso
{{ end }}
{{ end }}

View File

@ -0,0 +1,97 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: dynatrace-webhook
labels:
{{- include "dynatrace-operator.webhookLabels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- update
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- apiGroups:
- ""
resources:
- secrets
resourceNames:
- dynatrace-dynakube-config
- dynatrace-data-ingest-endpoint
verbs:
- get
- list
- watch
- update
# data-ingest workload owner lookup
- apiGroups:
- ""
resources:
- replicationcontrollers
verbs:
- get
- apiGroups:
- apps
resources:
- replicasets
- statefulsets
- daemonsets
- deployments
verbs:
- get
- apiGroups:
- batch
resources:
- jobs
- cronjobs
verbs:
- get
- apiGroups:
- apps.openshift.io
resources:
- deploymentconfigs
verbs:
- get
{{- if eq (default false .Values.olm) true}}
- apiGroups:
- security.openshift.io
resourceNames:
- host
- privileged
resources:
- securitycontextconstraints
verbs:
- use
{{ end }}
{{ end }}

View File

@ -0,0 +1,30 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dynatrace-webhook
labels:
{{- include "dynatrace-operator.webhookLabels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: dynatrace-webhook
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
name: dynatrace-webhook
apiGroup: rbac.authorization.k8s.io
{{ end }}

View File

@ -0,0 +1,153 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: Deployment
metadata:
name: dynatrace-webhook
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.webhookLabels" . | nindent 4 }}
{{- if .Values.webhook.labels }}
{{- toYaml .Values.webhook.labels | nindent 4 }}
{{- end }}
spec:
replicas: {{ (default false (.Values.webhook).highAvailability) | ternary 2 1 }}
revisionHistoryLimit: 1
selector:
matchLabels:
{{- include "dynatrace-operator.webhookSelectorLabels" . | nindent 6 }}
strategy:
type: RollingUpdate
template:
metadata:
annotations:
kubectl.kubernetes.io/default-container: webhook
{{- if (.Values.webhook).apparmor}}
container.apparmor.security.beta.kubernetes.io/webhook: runtime/default
{{- end }}
{{- if .Values.webhook.annotations}}
{{- toYaml .Values.webhook.annotations | nindent 8 }}
{{- end }}
labels:
{{- include "dynatrace-operator.webhookLabels" . | nindent 8 }}
{{- include "dynatrace-operator.webhookSelectorLabels" . | nindent 8 }}
{{- if .Values.webhook.labels }}
{{- toYaml .Values.webhook.labels | nindent 8 }}
{{- end }}
spec:
{{- if (.Values.webhook).highAvailability }}
topologySpreadConstraints:
- maxSkew: 1
topologyKey: "topology.kubernetes.io/zone"
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/component: webhook
app.kubernetes.io/name: dynatrace-operator
- maxSkew: 1
topologyKey: "kubernetes.io/hostname"
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/component: webhook
app.kubernetes.io/name: dynatrace-operator
{{- end }}
volumes:
- emptyDir: {}
name: certs-dir
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
{{- if ne .Values.platform "gke-autopilot"}}
- key: kubernetes.io/arch
operator: In
values:
- amd64
- arm64
{{- end }}
- key: kubernetes.io/os
operator: In
values:
- linux
containers:
- name: webhook
args:
- webhook-server
# OLM mounts the certificates here, so we reuse it for simplicity
- --certs-dir=/tmp/k8s-webhook-server/serving-certs/
image: {{ include "dynatrace-operator.image" . }}
imagePullPolicy: Always
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
readinessProbe:
httpGet:
path: /livez
port: server-port
scheme: HTTPS
ports:
- name: server-port
containerPort: 8443
resources:
requests:
{{- toYaml (.Values.webhook).requests | nindent 14 }}
limits:
{{- toYaml (.Values.webhook).limits | nindent 14 }}
volumeMounts:
- name: certs-dir
mountPath: /tmp/k8s-webhook-server/serving-certs/
securityContext:
seccompProfile:
type: RuntimeDefault
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001
runAsGroup: 1001
capabilities:
drop:
- ALL
serviceAccountName: dynatrace-webhook
{{- if (.Values.webhook).hostNetwork }}
hostNetwork: true
{{- end }}
{{- if .Values.customPullSecret }}
imagePullSecrets:
- name: {{ .Values.customPullSecret }}
{{- end }}
{{- if .Values.webhook.nodeSelector }}
nodeSelector: {{- toYaml .Values.webhook.nodeSelector | nindent 8 }}
{{- end }}
tolerations:
{{- if .Values.webhook.tolerations }}
{{- toYaml .Values.webhook.tolerations | nindent 8 }}
{{- end }}
- key: kubernetes.io/arch
value: arm64
effect: NoSchedule
- key: kubernetes.io/arch
value: amd64
effect: NoSchedule
{{ end }}

View File

@ -0,0 +1,61 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: dynatrace-webhook
labels:
{{- include "dynatrace-operator.webhookLabels" . | nindent 4 }}
webhooks:
- name: webhook.pod.dynatrace.com
reinvocationPolicy: IfNeeded
failurePolicy: Ignore
timeoutSeconds: 2
rules:
- apiGroups: [ "" ]
apiVersions: [ "v1" ]
operations: [ "CREATE" ]
resources: [ "pods" ]
scope: Namespaced
namespaceSelector:
matchExpressions:
- key: dynakube.internal.dynatrace.com/instance
operator: Exists
clientConfig:
service:
name: dynatrace-webhook
namespace: {{ .Release.Namespace }}
path: /inject
admissionReviewVersions: [ "v1beta1", "v1" ]
sideEffects: None
- name: webhook.ns.dynatrace.com
reinvocationPolicy: IfNeeded
failurePolicy: Ignore
timeoutSeconds: 2
rules:
- apiGroups: [ "" ]
apiVersions: [ "v1" ]
operations: [ "CREATE", "UPDATE"]
resources: [ "namespaces" ]
scope: Cluster
clientConfig:
service:
name: dynatrace-webhook
namespace: {{ .Release.Namespace }}
path: /label-ns
admissionReviewVersions: [ "v1beta1", "v1" ]
sideEffects: None
{{ end }}

View File

@ -0,0 +1,13 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if and (.Values.webhook).highAvailability (eq (include "dynatrace-operator.partial" .) "false") }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: dynatrace-webhook
namespace: {{ .Release.Namespace }}
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/component: webhook
{{ end }}

View File

@ -0,0 +1,74 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dynatrace-webhook
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.webhookLabels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- services
- configmaps
- secrets
verbs:
- get
- list
- watch
- create
- update
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- apiGroups:
- dynatrace.com
resources:
- dynakubes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- list
- create
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- update
- create
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- list
- watch
{{ end }}

View File

@ -0,0 +1,31 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dynatrace-webhook
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.webhookLabels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: dynatrace-webhook
namespace: {{ .Release.Namespace }}
roleRef:
kind: Role
name: dynatrace-webhook
apiGroup: rbac.authorization.k8s.io
{{ end }}

View File

@ -0,0 +1,30 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Service
metadata:
name: dynatrace-webhook
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.webhookLabels" . | nindent 4 }}
spec:
selector:
{{- include "dynatrace-operator.webhookLabels" . | nindent 4 }}
ports:
- port: 443
protocol: TCP
targetPort: server-port
{{ end }}

View File

@ -0,0 +1,29 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
name: dynatrace-webhook
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.webhookLabels" . | nindent 4 }}
{{- if eq .Values.platform "openshift" }}
imagePullSecrets:
- name: redhat-connect
- name: redhat-connect-sso
{{- end }}
{{ end }}

View File

@ -0,0 +1,45 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{ if eq (include "dynatrace-operator.partial" .) "false" }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: dynatrace-webhook
labels:
{{- include "dynatrace-operator.webhookLabels" . | nindent 4 }}
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
- v1alpha1
clientConfig:
service:
name: dynatrace-webhook
namespace: {{ .Release.Namespace }}
path: /validate
rules:
- operations:
- CREATE
- UPDATE
apiGroups:
- dynatrace.com
apiVersions:
- v1beta1
resources:
- dynakubes
name: webhook.dynatrace.com
timeoutSeconds: 2
sideEffects: None
{{ end }}

View File

@ -0,0 +1,10 @@
Thank you for installing {{ .Chart.Name }}.
Your release is named {{ .Release.Name }}.
To find more information about the Dynatrace Operator, try:
https://github.com/Dynatrace/dynatrace-operator
To verify the current state of the deployments, try:
$ kubectl get pods -n {{ .Release.Namespace }}
$ kubectl logs -f deployment/{{ .Release.Name }} -n {{ .Release.Namespace }}

View File

@ -0,0 +1,52 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if and (eq .Values.platform "openshift") ((.Values.securityContextConstraints).enabled) (eq (include "dynatrace-operator.partial" .) "false")}}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: dynatrace-activegate
allowPrivilegedContainer: false
fsGroup:
type: RunAsAny
priority: 1
{{- if (.Values.activeGate).readOnlyFs }}
readOnlyRootFilesystem: true
{{ else }}
readOnlyRootFilesystem: false
{{ end }}
requiredDropCapabilities:
- ALL
runAsUser:
type: MustRunAsNonRoot
seLinuxContext:
type: RunAsAny
seccompProfiles:
- "*"
supplementalGroups:
type: RunAsAny
users:
- system:serviceaccount:{{ .Release.Namespace }}:dynatrace-activegate
- system:serviceaccount:{{ .Release.Namespace }}:dynatrace-kubernetes-monitoring
volumes:
- "*"
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowedFlexVolumes: null
defaultAddCapabilities: []
{{ end }}

View File

@ -0,0 +1,49 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if and (eq .Values.platform "openshift") ((.Values.securityContextConstraints).enabled) (eq (include "dynatrace-operator.needCSI" .) "true") }}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: dynatrace-oneagent-csi-driver
labels:
{{- include "dynatrace-operator.csiLabels" . | nindent 4 }}
allowHostDirVolumePlugin: true
allowHostIPC: true
allowHostNetwork: true
allowHostPID: true
allowHostPorts: true
allowPrivilegedContainer: true
allowedCapabilities:
- "*"
allowedFlexVolumes: null
defaultAddCapabilities: null
fsGroup:
type: RunAsAny
priority: 1
readOnlyRootFilesystem: false
requiredDropCapabilities: null
runAsUser:
type: RunAsAny
seLinuxContext:
type: RunAsAny
seccompProfiles:
- "*"
supplementalGroups:
type: RunAsAny
users:
- system:serviceaccount:dynatrace:dynatrace-oneagent-csi-driver
volumes:
- "*"
{{ end }}

View File

@ -0,0 +1,66 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if and (eq .Values.platform "openshift") ((.Values.securityContextConstraints).enabled) (eq (include "dynatrace-operator.partial" .) "false")}}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
annotations:
kubernetes.io/description: "dynatrace-dynakube-oneagent-privileged allows access to all privileged and host features and the ability to run as any user, any group, any fsGroup, and with any SELinux context."
name: dynatrace-dynakube-oneagent-privileged
labels:
{{- include "dynatrace-operator.oneagentLabels" . | nindent 4 }}
allowHostDirVolumePlugin: true
allowHostIPC: false
allowHostNetwork: true
allowHostPID: true
allowHostPorts: true
allowPrivilegedContainer: true
allowedCapabilities:
- CHOWN
- DAC_OVERRIDE
- DAC_READ_SEARCH
- FOWNER
- FSETID
- KILL
- NET_ADMIN
- NET_RAW
- SETFCAP
- SETGID
- SETUID
- SYS_ADMIN
- SYS_CHROOT
- SYS_PTRACE
- SYS_RESOURCE
allowedFlexVolumes: null
defaultAddCapabilities: []
fsGroup:
type: RunAsAny
priority: 1
readOnlyRootFilesystem: false
requiredDropCapabilities:
- ALL
runAsUser:
type: RunAsAny
seLinuxContext:
type: RunAsAny
seccompProfiles:
- "*"
supplementalGroups:
type: RunAsAny
users:
- system:serviceaccount:{{ .Release.Namespace }}:dynatrace-dynakube-oneagent-privileged
volumes:
- "*"
{{ end }}

View File

@ -0,0 +1,66 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if and (eq .Values.platform "openshift") ((.Values.securityContextConstraints).enabled) (eq (include "dynatrace-operator.partial" .) "false")}}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
annotations:
kubernetes.io/description: "dynatrace-dynakube-oneagent-unprivileged allows access to all privileged and host features and the ability to run as any user, any group, any fsGroup, and with any SELinux context. This is a copy of privileged scc."
name: dynatrace-dynakube-oneagent-unprivileged
labels:
{{- include "dynatrace-operator.oneagentLabels" . | nindent 4 }}
allowHostDirVolumePlugin: true
allowHostIPC: false
allowHostNetwork: true
allowHostPID: true
allowHostPorts: true
allowPrivilegedContainer: false
allowedCapabilities:
- CHOWN
- DAC_OVERRIDE
- DAC_READ_SEARCH
- FOWNER
- FSETID
- KILL
- NET_ADMIN
- NET_RAW
- SETFCAP
- SETGID
- SETUID
- SYS_ADMIN
- SYS_CHROOT
- SYS_PTRACE
- SYS_RESOURCE
allowedFlexVolumes: null
defaultAddCapabilities: []
fsGroup:
type: RunAsAny
priority: 1
readOnlyRootFilesystem: false
requiredDropCapabilities:
- ALL
runAsUser:
type: RunAsAny
seLinuxContext:
type: RunAsAny
seccompProfiles:
- "*"
supplementalGroups:
type: RunAsAny
users:
- system:serviceaccount:{{ .Release.Namespace }}:dynatrace-dynakube-oneagent-unprivileged
volumes:
- "*"
{{ end }}

View File

@ -0,0 +1,49 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if and (eq .Values.platform "openshift") ((.Values.securityContextConstraints).enabled) (eq (include "dynatrace-operator.partial" .) "false")}}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: {{ .Release.Name }}
labels:
{{- include "dynatrace-operator.operatorLabels" . | nindent 4 }}
allowPrivilegedContainer: false
fsGroup:
type: RunAsAny
priority: 1
readOnlyRootFilesystem: true
requiredDropCapabilities:
- ALL
runAsUser:
type: MustRunAsNonRoot
seLinuxContext:
type: RunAsAny
seccompProfiles:
- "*"
supplementalGroups:
type: RunAsAny
users:
- system:serviceaccount:{{ .Release.Namespace }}:{{ .Release.Name }}
volumes:
- "*"
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowedFlexVolumes: null
defaultAddCapabilities: []
{{ end }}

View File

@ -0,0 +1,49 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if and (eq .Values.platform "openshift") ((.Values.securityContextConstraints).enabled) (eq (include "dynatrace-operator.partial" .) "false")}}
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: dynatrace-webhook
labels:
{{- include "dynatrace-operator.operatorLabels" . | nindent 4 }}
allowPrivilegedContainer: false
fsGroup:
type: RunAsAny
priority: 1
readOnlyRootFilesystem: true
requiredDropCapabilities:
- ALL
runAsUser:
type: MustRunAsNonRoot
seLinuxContext:
type: RunAsAny
seccompProfiles:
- "*"
supplementalGroups:
type: RunAsAny
users:
- system:serviceaccount:{{ .Release.Namespace }}:dynatrace-webhook
volumes:
- "*"
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: true
allowHostPID: false
allowHostPorts: false
allowedFlexVolumes: null
defaultAddCapabilities: []
{{ end }}

View File

@ -0,0 +1,50 @@
// Copyright 2020 Dynatrace LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{{/*
Check if we need the csi driver.
*/}}
{{- define "dynatrace-operator.needCSI" -}}
{{- if or (.Values.csidriver.enabled) (eq (include "dynatrace-operator.partial" .) "csi") -}}
{{- printf "true" -}}
{{- end -}}
{{- end -}}
{{/*
CSI plugin-dir path
*/}}
{{- define "dynatrace-operator.CSIPluginDir" -}}
{{ printf "%s/plugins/csi.oneagent.dynatrace.com/" (trimSuffix "/" (default "/var/lib/kubelet" .Values.csidriver.kubeletPath)) }}
{{- end -}}
{{/*
CSI socket path
*/}}
{{- define "dynatrace-operator.CSISocketPath" -}}
{{ printf "%s/csi.sock" (trimSuffix "/" (include "dynatrace-operator.CSIPluginDir" .)) }}
{{- end -}}
{{/*
CSI mountpoint-dir path
*/}}
{{- define "dynatrace-operator.CSIMountPointDir" -}}
{{ printf "%s/pods/" (trimSuffix "/" (default "/var/lib/kubelet" .Values.csidriver.kubeletPath)) }}
{{- end -}}
{{/*
CSI registration-dir path
*/}}
{{- define "dynatrace-operator.CSIRegistrationDir" -}}
{{ printf "%s/plugins_registry/" (trimSuffix "/" (default "/var/lib/kubelet" .Values.csidriver.kubeletPath)) }}
{{- end -}}

View File

@ -0,0 +1,73 @@
// Copyright 2020 Dynatrace LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "dynatrace-operator.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Check if default image is used
*/}}
{{- define "dynatrace-operator.image" -}}
{{- if .Values.image -}}
{{- printf "%s" .Values.image -}}
{{- else -}}
{{- if eq .Values.platform "google-marketplace" -}}
{{- printf "%s:%s" "gcr.io/dynatrace-marketplace-prod/dynatrace-operator" "{{ .Chart.AppVersion }}" }}
{{- else -}}
{{- printf "%s:v%s" "docker.io/dynatrace/dynatrace-operator" .Chart.AppVersion }}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Check if we are generating only a part of the yamls
*/}}
{{- define "dynatrace-operator.partial" -}}
{{- if (default false .Values.partial) -}}
{{- printf "%s" .Values.partial -}}
{{- else -}}
{{- printf "false" -}}
{{- end -}}
{{- end -}}
{{/*
Check if platform is set
*/}}
{{- define "dynatrace-operator.platformSet" -}}
{{- if or (eq .Values.platform "kubernetes") (eq .Values.platform "openshift") (eq .Values.platform "google-marketplace") (eq .Values.platform "gke-autopilot") -}}
{{ default "set" }}
{{- end -}}
{{- end -}}
{{/*
Exclude Kubernetes manifest not running on OLM
*/}}
{{- define "dynatrace-operator.openshiftOrOlm" -}}
{{- if and (or (eq .Values.platform "openshift") (.Values.olm)) (eq (include "dynatrace-operator.partial" .) "false") -}}
{{ default "true" }}
{{- end -}}
{{- end -}}
{{/*
Check if the platform is set
*/}}
{{- define "dynatrace-operator.platformRequired" -}}
{{- $platformIsSet := printf "%s" (required "Platform needs to be set to kubernetes, openshift, google-marketplace, or gke-autopilot" (include "dynatrace-operator.platformSet" .))}}
{{- end -}}

View File

@ -0,0 +1,99 @@
// Copyright 2020 Dynatrace LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{{/*
Selector labels
*/}}
{{- define "dynatrace-operator.futureSelectorLabels" -}}
app.kubernetes.io/name: {{ .Release.Name }}
{{- if not (.Values).manifests }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "dynatrace-operator.commonLabels" -}}
{{ include "dynatrace-operator.futureSelectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
{{- if not (.Values).manifests }}
helm.sh/chart: {{ include "dynatrace-operator.chart" . }}
{{- end -}}
{{- end -}}
{{/*
Operator labels
*/}}
{{- define "dynatrace-operator.operatorLabels" -}}
{{ include "dynatrace-operator.commonLabels" . }}
app.kubernetes.io/component: operator
{{- end -}}
{{/*
Operator selector labels
*/}}
{{- define "dynatrace-operator.operatorSelectorLabels" -}}
name: {{ .Release.Name }}
{{- end -}}
{{/*
Webhook labels
*/}}
{{- define "dynatrace-operator.webhookLabels" -}}
{{ include "dynatrace-operator.commonLabels" . }}
app.kubernetes.io/component: webhook
{{- end -}}
{{/*
Webhook selector labels
*/}}
{{- define "dynatrace-operator.webhookSelectorLabels" -}}
internal.dynatrace.com/component: webhook
internal.dynatrace.com/app: webhook
{{- end -}}
{{/*
CSI labels
*/}}
{{- define "dynatrace-operator.csiLabels" -}}
{{ include "dynatrace-operator.commonLabels" . }}
app.kubernetes.io/component: csi-driver
{{- end -}}
{{/*
CSI selector labels
*/}}
{{- define "dynatrace-operator.csiSelectorLabels" -}}
internal.oneagent.dynatrace.com/app: csi-driver
internal.oneagent.dynatrace.com/component: csi-driver
{{- end -}}
{{/*
ActiveGate labels
*/}}
{{- define "dynatrace-operator.activegateLabels" -}}
{{ include "dynatrace-operator.commonLabels" . }}
app.kubernetes.io/component: activegate
{{- end -}}
{{/*
OneAgent labels
*/}}
{{- define "dynatrace-operator.oneagentLabels" -}}
{{ include "dynatrace-operator.commonLabels" . }}
app.kubernetes.io/component: oneagent
{{- end -}}

View File

@ -0,0 +1,99 @@
{{- include "dynatrace-operator.platformRequired" . }}
{{- if eq .Values.platform "google-marketplace" }}
# Copyright 2020 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: app.k8s.io/v1beta1
kind: Application
metadata:
name: {{ .Release.Name }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "dynatrace-operator.operatorLabels" . | nindent 4 }}
annotations:
kubernetes-engine.cloud.google.com/icon: data:image/png;base64,{{ .Files.Get "logo.png" | b64enc }}
marketplace.cloud.google.com/deploy-info: '{"partner_id": "dynatrace-marketplace-prod", "product_id": "dynatrace-operator", "partner_name": "Dynatrace LLC"}'
spec:
descriptor:
type: "Dynatrace Operator"
version: "0.6.0"
maintainers:
- name: Dynatrace LLC
url: https://www.dynatrace.com/
keywords:
- "dynatrace"
- "operator"
- "activegate"
- "k8s"
- "monitoring"
- "apm"
description: |
# Dynatrace Operator
The Dynatrace Operator supports rollout and lifecycle management of various Dynatrace components in Kubernetes and OpenShift.
* OneAgent
* `classicFullStack` rolls out a OneAgent pod per node to monitor pods on it and the node itself
* `applicationMonitoring` is a webhook based injection mechanism for automatic app-only injection
* CSI Driver can be enabled to cache OneAgent downloads per node
* `hostMonitoring` is only monitoring the hosts (i.e. nodes) in the cluster without app-only injection
* `cloudNativeFullStack` is a combination of `applicationMonitoring` with CSI driver and `hostMonitoring`
* ActiveGate
* `routing` routes OneAgent traffic through the ActiveGate
* `kubernetes-monitoring` allows monitoring of the Kubernetes API
* `metrics-ingest` routes enriched metrics through ActiveGate
For more information please have a look at [our DynaKube Custom Resource examples](config/samples) and
our [official help page](https://www.dynatrace.com/support/help/setup-and-configuration/setup-on-container-platforms/kubernetes/).
links:
- description: Dynatrace Website
url: https://www.dynatrace.com/
- description: Operator Deploy Guide
url: ToDo
- description: Kubernetes Monitoring Info
url: https://www.dynatrace.com/technologies/kubernetes-monitoring
selector:
matchLabels:
app.kubernetes.io/name: "{{ .Release.Name }}"
componentKinds:
- group: apps/v1
kind: DaemonSet
- group: v1
kind: Pod
- group: v1
kind: ConfigMap
- group: apps/v1
kind: Deployment
- group: v1
kind: Secret
- group: batch/v1
kind: Job
- group: v1
kind: Service
- group: v1
kind: ServiceAccount
- group: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
- group: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
- group: apps/v1
kind: StatefulSet
- group: storage.k8s.io/v1
kind: CSIDriver
- group: rbac.authorization.k8s.io/v1
kind: ClusterRole
- group: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
- group: rbac.authorization.k8s.io/v1
kind: Role
- group: rbac.authorization.k8s.io/v1
kind: RoleBinding
{{ end }}

View File

@ -0,0 +1,98 @@
# Copyright 2021 Dynatrace LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# may be set to "kubernetes", "openshift", or "gke-autopilot"
platform: "kubernetes"
image: ""
customPullSecret: ""
installCRD: false
operator:
nodeSelector: {}
tolerations: []
labels: []
annotations: []
apparmor: false
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 100m
memory: 128Mi
webhook:
hostNetwork: false
nodeSelector: {}
tolerations: []
labels: []
annotations: []
apparmor: false
requests:
cpu: 300m
memory: 128Mi
limits:
cpu: 300m
memory: 128Mi
highAvailability: true
csidriver:
enabled: false
nodeSelector: {}
kubeletPath: "/var/lib/kubelet"
priorityClassValue: "1000000"
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
operator: Exists
- effect: NoSchedule
key: node-role.kubernetes.io/control-plane
operator: Exists
labels: []
annotations: []
server:
resources:
requests:
cpu: 50m
memory: 100Mi
limits:
cpu: 50m
memory: 100Mi
provisioner:
resources:
requests:
cpu: 300m
memory: 100Mi
limits:
cpu: 300m
memory: 100Mi
registrar:
resources:
requests:
cpu: 20m
memory: 30Mi
limits:
cpu: 20m
memory: 30Mi
livenessprobe:
resources:
requests:
cpu: 20m
memory: 30Mi
limits:
cpu: 20m
memory: 30Mi
securityContextConstraints:
enabled: true # Only applicable for Openshift

View File

@ -0,0 +1,15 @@
annotations:
catalog.cattle.io/certified: partner
catalog.cattle.io/display-name: K10
catalog.cattle.io/release-name: k10
apiVersion: v2
appVersion: 5.0.9
description: Kastens K10 Data Management Platform
home: https://kasten.io/
icon: https://docs.kasten.io/_static/logo-kasten-k10-blue-white.png
kubeVersion: '>= 1.17.0-0'
maintainers:
- email: contact@kasten.io
name: kastenIO
name: k10
version: 5.0.900

View File

@ -0,0 +1,231 @@
# Kasten's K10 Helm chart.
[Kasten's k10](https://docs.kasten.io/) is a data lifecycle management system for all your persistence.enabled container-based applications.
## TL;DR;
```console
$ helm install kasten/k10 --name=k10 --namespace=kasten-io
```
## Introduction
This chart bootstraps Kasten's K10 platform on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
## Prerequisites
- Kubernetes 1.7+ with Beta APIs enabled
## Installing the Chart
To install the chart on a [GKE](https://cloud.google.com/container-engine/) cluster
```console
$ helm install kasten/k10 --name=k10 --namespace=kasten-io
```
To install the chart on an [AWS](https://aws.amazon.com/) [kops](https://github.com/kubernetes/kops)-created cluster
```console
$ helm install kasten/k10 --name=k10 --namespace=kasten-io --set secrets.awsAccessKeyId="${AWS_ACCESS_KEY_ID}" \
--set secrets.awsSecretAccessKey="${AWS_SECRET_ACCESS_KEY}"
```
> **Tip**: List all releases using `helm list`
## Uninstalling the Chart
To uninstall/delete the `k10` application:
```console
$ helm delete k10 --purge
```
## Configuration
The following table lists the configurable parameters of the K10
chart and their default values.
Parameter | Description | Default
--- | --- | ---
`eula.accept`| Whether to enable accept EULA before installation | `false`
`eula.company` | Company name. Required field if EULA is accepted | `None`
`eula.email` | Contact email. Required field if EULA is accepted | `None`
`license` | License string obtained from Kasten | `None`
`rbac.create` | Whether to enable RBAC with a specific cluster role and binding for K10 | `true`
`scc.create` | Whether to create a SecurityContextConstraints for K10 ServiceAccounts | `false`
`services.dashboardbff.hostNetwork` | Whether the dashboardbff pods may use the node network | `false`
`services.executor.hostNetwork` | Whether the executor pods may use the node network | `false`
`services.executor.workerCount` | Specifies count of running executor workers | 8
`services.aggregatedapis.hostNetwork` | Whether the aggregatedapis pods may use the node network | `false`
`serviceAccount.create`| Specifies whether a ServiceAccount should be created | `true`
`serviceAccount.name` | The name of the ServiceAccount to use. If not set, a name is derived using the release and chart names. | `None`
`ingress.create` | Specifies whether the K10 dashboard should be exposed via ingress | `false`
`ingress.class` | Cluster ingress controller class: `nginx`, `GCE` | `None`
`ingress.host` | FQDN (e.g., `k10.example.com`) for name-based virtual host | `None`
`ingress.urlPath` | URL path for K10 Dashboard (e.g., `/k10`) | `Release.Name`
`ingress.annotations` | Additional Ingress object annotations | `{}`
`ingress.tls.enabled` | Configures a TLS use for `ingress.host` | `false`
`ingress.tls.secretName` | Specifies a name of TLS secret | `None`
`ingress.pathType` | Specifies the path type for the ingress resource | `ImplementationSpecific`
`global.persistence.size` | Default global size of volumes for K10 persistent services | `20Gi`
`global.persistence.catalog.size` | Size of a volume for catalog service | `global.persistence.size`
`global.persistence.jobs.size` | Size of a volume for jobs service | `global.persistence.size`
`global.persistence.logging.size` | Size of a volume for logging service | `global.persistence.size`
`global.persistence.metering.size` | Size of a volume for metering service | `global.persistence.size`
`global.persistence.storageClass` | Specified StorageClassName will be used for PVCs | `None`
`global.airgapped.repository` | Specify the helm repository for offline (airgapped) installation | `''`
`global.imagePullSecret` | Provide secret which contains docker config for private repository. Use `k10-ecr` when secrets.dockerConfigPath is used. | `''`
`global.prometheus.external.host` | Provide external prometheus host name | `''`
`global.prometheus.external.port` | Provide external prometheus port number | `''`
`global.prometheus.external.baseURL` | Provide Base URL of external prometheus | `''`
`global.network.enable_ipv6` | Enable `IPv6` support for K10 | `false`
`secrets.awsAccessKeyId` | AWS access key ID (required for AWS deployment) | `None`
`secrets.awsSecretAccessKey` | AWS access key secret | `None`
`secrets.awsIamRole` | ARN of the AWS IAM role assumed by K10 to perform any AWS operation. | `None`
`secrets.googleApiKey` | Non-default base64 encoded GCP Service Account key file | `None`
`secrets.azureTenantId` | Azure tenant ID (required for Azure deployment) | `None`
`secrets.azureClientId` | Azure Service App ID | `None`
`secrets.azureClientSecret` | Azure Service APP secret | `None`
`secrets.azureResourceGroup` | Resource Group name that was created for the Kubernetes cluster | `None`
`secrets.azureSubscriptionID` | Subscription ID in your Azure tenant | `None`
`secrets.azureResourceMgrEndpoint` | Resource management endpoint for the Azure Stack instance | `None`
`secrets.azureADEndpoint` | Azure Active Directory login endpoint | `None`
`secrets.azureADResourceID` | Azure Active Directory resource ID to obtain AD tokens | `None`
`secrets.azureCloudEnvID` | Azure Cloud Environment ID | `None`
`secrets.vsphereEndpoint` | vSphere endpoint for login | `None`
`secrets.vsphereUsername` | vSphere username for login | `None`
`secrets.vspherePassword` | vSphere password for login | `None`
`secrets.dockerConfigPath` | Use --set-file secrets.dockerConfigPath=path_to_docker_config.yaml to specify docker config for image pull | `None`
`cacertconfigmap.name` | Name of the ConfigMap that contains a certificate for a trusted root certificate authority | `None`
`clusterName` | Cluster name for better logs visibility | `None`
`metering.awsRegion` | Sets AWS_REGION for metering service | `None`
`metering.mode` | Control license reporting (set to `airgap` for private-network installs) | `None`
`metering.reportCollectionPeriod` | Sets metric report collection period (in seconds) | `1800`
`metering.reportPushPeriod` | Sets metric report push period (in seconds) | `3600`
`metering.promoID` | Sets K10 promotion ID from marketing campaigns | `None`
`metering.awsMarketplace` | Sets AWS cloud metering license mode | `false`
`metering.awsManagedLicense` | Sets AWS managed license mode | `false`
`metering.redhatMarketplacePayg` | Sets Red Hat cloud metering license mode | `false`
`metering.licenseConfigSecretName` | Sets AWS managed license config secret | `None`
`externalGateway.create` | Configures an external gateway for K10 API services | `false`
`externalGateway.annotations` | Standard annotations for the services | `None`
`externalGateway.fqdn.name` | Domain name for the K10 API services | `None`
`externalGateway.fqdn.type` | Supported gateway type: `route53-mapper` or `external-dns` | `None`
`externalGateway.awsSSLCertARN` | ARN for the AWS ACM SSL certificate used in the K10 API server | `None`
`auth.basicAuth.enabled` | Configures basic authentication for the K10 dashboard | `false`
`auth.basicAuth.htpasswd` | A username and password pair separated by a colon character | `None`
`auth.basicAuth.secretName` | Name of an existing Secret that contains a file generated with htpasswd | `None`
`auth.k10AdminGroups` | A list of groups whose members are granted admin level access to K10's dashboard | `None`
`auth.k10AdminUsers` | A list of users who are granted admin level access to K10's dashboard | `None`
`auth.tokenAuth.enabled` | Configures token based authentication for the K10 dashboard | `false`
`auth.oidcAuth.enabled` | Configures Open ID Connect based authentication for the K10 dashboard | `false`
`auth.oidcAuth.providerURL` | URL for the OIDC Provider | `None`
`auth.oidcAuth.redirectURL` | URL to the K10 gateway service | `None`
`auth.oidcAuth.scopes` | Space separated OIDC scopes required for userinfo. Example: "profile email" | `None`
`auth.oidcAuth.prompt` | The type of prompt to be used during authentication (none, consent, login or select_account) | `select_account`
`auth.oidcAuth.clientID` | Client ID given by the OIDC provider for K10 | `None`
`auth.oidcAuth.clientSecret` | Client secret given by the OIDC provider for K10 | `None`
`auth.oidcAuth.usernameClaim` | The claim to be used as the username | `sub`
`auth.oidcAuth.usernamePrefix` | Prefix that has to be used with the username obtained from the username claim | `None`
`auth.oidcAuth.groupClaim` | Name of a custom OpenID Connect claim for specifying user groups | `None`
`auth.oidcAuth.groupPrefix` | All groups will be prefixed with this value to prevent conflicts | `None`
`auth.openshift.enabled` | Enables access to the K10 dashboard by authenticating with the OpenShift OAuth server | `false`
`auth.openshift.serviceAccount` | Name of the service account that represents an OAuth client | `None`
`auth.openshift.clientSecret` | The token corresponding to the service account | `None`
`auth.openshift.dashboardURL` | The URL used for accessing K10's dashboard | `None`
`auth.openshift.openshiftURL` | The URL for accessing OpenShift's API server | `None`
`auth.openshift.insecureCA` | To turn off SSL verification of connections to OpenShift | `false`
`auth.openshift.useServiceAccountCA` | Set this to true to use the CA certificate corresponding to the Service Account ``auth.openshift.serviceAccount`` usually found at ``/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`` | `false`
`auth.ldap.enabled` | Configures Active Directory/LDAP based authentication for the K10 dashboard | `false`
`auth.ldap.restartPod` | To force a restart of the authentication service pod (useful when updating authentication config) | `false`
`auth.ldap.dashboardURL` | The URL used for accessing K10's dashboard | `None`
`auth.ldap.host` | Host and optional port of the AD/LDAP server in the form `host:port` | `None`
`auth.ldap.insecureNoSSL` | Required if the AD/LDAP host is not using TLS | `false`
`auth.ldap.insecureSkipVerifySSL` | To turn off SSL verification of connections to the AD/LDAP host | `false`
`auth.ldap.startTLS` | When set to true, ldap:// is used to connect to the server followed by creation of a TLS session. When set to false, ldaps:// is used. | `false`
`auth.ldap.bindDN` | The Distinguished Name(username) used for connecting to the AD/LDAP host | `None`
`auth.ldap.bindPW` | The password corresponding to the `bindDN` for connecting to the AD/LDAP host | `None`
`auth.ldap.bindPWSecretName` | The name of the secret that contains the password corresponding to the `bindDN` for connecting to the AD/LDAP host | `None`
`auth.ldap.userSearch.baseDN` | The base Distinguished Name to start the AD/LDAP search from | `None`
`auth.ldap.userSearch.filter` | Optional filter to apply when searching the directory | `None`
`auth.ldap.userSearch.username` | Attribute used for comparing user entries when searching the directory | `None`
`auth.ldap.userSearch.idAttr` | AD/LDAP attribute in a user's entry that should map to the user ID field in a token | `None`
`auth.ldap.userSearch.emailAttr` | AD/LDAP attribute in a user's entry that should map to the email field in a token | `None`
`auth.ldap.userSearch.nameAttr` | AD/LDAP attribute in a user's entry that should map to the name field in a token | `None`
`auth.ldap.userSearch.preferredUsernameAttr` | AD/LDAP attribute in a user's entry that should map to the preferred_username field in a token | `None`
`auth.ldap.groupSearch.baseDN` | The base Distinguished Name to start the AD/LDAP group search from | `None`
`auth.ldap.groupSearch.filter` | Optional filter to apply when searching the directory for groups | `None`
`auth.ldap.groupSearch.nameAttr` | The AD/LDAP attribute that represents a group's name in the directory | `None`
`auth.ldap.groupSearch.userMatchers` | List of field pairs that are used to match a user to a group. | `None`
`auth.ldap.groupSearch.userMatchers.userAttr` | Attribute in the user's entry that must match with the `groupAttr` while searching for groups | `None`
`auth.ldap.groupSearch.userMatchers.groupAttr` | Attribute in the group's entry that must match with the `userAttr` while searching for groups | `None`
`auth.groupAllowList` | A list of groups whose members are allowed access to K10's dashboard | `None`
`services.securityContext` | Custom [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for K10 service containers | `{"runAsUser" : 1000, "fsGroup": 1000}`
`services.securityContext.runAsUser` | User ID K10 service containers run as| `1000`
`services.securityContext.runAsGroup` | Group ID K10 service containers run as| `1000`
`services.securityContext.fsGroup` | FSGroup that owns K10 service container volumes | `1000`
`injectKanisterSidecar.enabled` | Enable Kanister sidecar injection for workload pods | `false`
`injectKanisterSidecar.namespaceSelector.matchLabels` | Set of labels to select namespaces in which sidecar injection is enabled for workloads | `{}`
`injectKanisterSidecar.objectSelector.matchLabels` | Set of labels to filter workload objects in which the sidecar is injected | `{}`
`injectKanisterSidecar.webhookServer.port` | Port number on which the mutating webhook server accepts request | `8080`
`gateway.insecureDisableSSLVerify` | Specifies whether to disable SSL verification for gateway pods | `false`
`gateway.exposeAdminPort` | Specifies whether to expose Admin port for gateway service | `true`
`genericVolumeSnapshot.resources.[requests\|limits].[cpu\|memory]` | Resource requests and limits for Generic Volume Snapshot restore pods | `{}`
`prometheus.server.enabled` | If false, K10's Prometheus server will not be created, reducing the dashboard's functionality. | `true`
`prometheus.server.persistentVolume.enabled` | If true, K10 Prometheus server will create a Persistent Volume Claim | `true`
`prometheus.server.persistentVolume.size` | K10 Prometheus server data Persistent Volume size | `30Gi`
`prometheus.server.persistentVolume.storageClass` | StorageClassName used to create Prometheus PVC. Setting this option overwrites global StorageClass value | `""`
`prometheus.server.retention` | (optional) K10 Prometheus data retention | `"30d"`
`prometheus.server.baseURL` | (optional) K10 Prometheus external url path at which the server can be accessed | `/k10/prometheus/`
`prometheus.server.prefixURL` | (optional) K10 Prometheus prefix slug at which the server can be accessed | `/k10/prometheus/`
`grafana.enabled` | (optional) If false Grafana will not be available | `true`
`grafana.prometheusPrefixURL` | (optional) URL for Prometheus datasource in Grafana (must match `prometheus.server.prefixURL`) | `/k10/prometheus/`
`resources.<podName>.<containerName>.[requests\|limits].[cpu\|memory]` | Overwrite default K10 [container resource requests and limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) | varies by container
`route.enabled` | Specifies whether the K10 dashboard should be exposed via route | `false`
`route.host` | FQDN (e.g., `.k10.example.com`) for name-based virtual host | `""`
`route.path` | URL path for K10 Dashboard (e.g., `/k10`) | `/`
`route.annotations` | Additional Route object annotations | `{}`
`route.labels` | Additional Route object labels | `{}`
`route.tls.enabled` | Configures a TLS use for `route.host` | `false`
`route.tls.insecureEdgeTerminationPolicy` | Specifies behavior for insecure scheme traffic | `Redirect`
`route.tls.termination` | Specifies the TLS termination of the route | `edge`
`apigateway.serviceResolver` | Specifies the resolver used for service discovery in the API gateway (`dns` or `endpoint`) | `dns`
`limiter.genericVolumeSnapshots` | Limit of concurrent generic volume snapshot create operations | `10`
`limiter.genericVolumeCopies` | Limit of concurrent generic volume snapshot copy operations | `10`
`limiter.genericVolumeRestores` | Limit of concurrent generic volume snapshot restore operations | `10`
`limiter.csiSnapshots` | Limit of concurrent CSI snapshot create operations | `10`
`limiter.providerSnapshots` | Limit of concurrent cloud provider create operations | `10`
`cluster.domainName` | Specifies the domain name of the cluster | `cluster.local`
`kanister.backupTimeout` | Specifies timeout to set on Kanister backup operations | `45`
`kanister.restoreTimeout` | Specifies timeout to set on Kanister restore operations | `600`
`kanister.deleteTimeout` | Specifies timeout to set on Kanister delete operations | `45`
`kanister.hookTimeout` | Specifies timeout to set on Kanister pre-hook and post-hook operations | `20`
`kanister.checkRepoTimeout` | Specifies timeout to set on Kanister checkRepo operations | `20`
`kanister.statsTimeout` | Specifies timeout to set on Kanister stats operations | `20`
`kanister.efsPostRestoreTimeout` | Specifies timeout to set on Kanister efsPostRestore operations | `45`
`awsConfig.assumeRoleDuration` | Duration of a session token generated by AWS for an IAM role. The minimum value is 15 minutes and the maximum value is the maximum duration setting for that IAM role. For documentation about how to view and edit the maximum session duration for an IAM role see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session. The value accepts a number along with a single character ``m``(for minutes) or ``h`` (for hours) Examples: 60m or 2h | `''`
`awsConfig.efsBackupVaultName` | Specifies the AWS EFS backup vault name | `k10vault`
`vmWare.taskTimeoutMin` | Specifies the timeout for VMWare operations | `60`
`encryption.primaryKey.awsCmkKeyId` | Specifies the AWS CMK key ID for encrypting K10 Primary Key | `None`
## Helm tips and tricks
There is a way of setting values via a yaml file instead of using `--set`.
You can copy/paste values into a file (e.g., my_values.yaml):
```yaml
secrets:
awsAccessKeyId: ${AWS_ACCESS_KEY_ID}
awsSecretAccessKey: ${AWS_SECRET_ACCESS_KEY}
```
and then run:
```bash
envsubst < my_values.yaml > my_values_out.yaml && helm install helm/k10 -f my_values_out.yaml
```
To use non-default GCP ServiceAccount (SA) credentials, the credentials JSON file needs to be encoded into a base64 string.
```bash
sa_key=$(base64 -w0 sa-key.json)
helm install kasten/k10 --name=k10 --namespace=kasten-io --set secrets.googleApiKey=$sa_key
```

View File

@ -0,0 +1,5 @@
The K10 data management platform, purpose-built for Kubernetes, provides enterprise operations teams an easy-to-use, scalable, and secure system for backup/restore, disaster recovery, and mobility of Kubernetes applications.
K10s application-centric approach and deep integrations with relational and NoSQL databases, Kubernetes distributions, and all clouds provide teams the freedom of infrastructure choice without sacrificing operational simplicity. Policy-driven and extensible, K10 provides a native Kubernetes API and includes features such as full-spectrum consistency, database integrations, automatic application discovery, multi-cloud mobility, and a powerful web-based user interface.
For more information, refer to the docs [https://docs.kasten.io/](https://docs.kasten.io/)

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.vscode
.project
.idea/
*.tmproj
OWNERS

View File

@ -0,0 +1,22 @@
apiVersion: v2
appVersion: 9.0.4
description: The leading tool for querying and visualizing time series and metrics.
home: https://grafana.net
icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png
kubeVersion: ^1.8.0-0
maintainers:
- email: zanhsieh@gmail.com
name: zanhsieh
- email: rluckie@cisco.com
name: rtluckie
- email: maor.friedman@redhat.com
name: maorfr
- email: miroslav.hadzhiev@gmail.com
name: Xtigyro
- email: mail@torstenwalter.de
name: torstenwalter
name: grafana
sources:
- https://github.com/grafana/grafana
type: application
version: 6.32.9

View File

@ -0,0 +1,571 @@
# Grafana Helm Chart
* Installs the web dashboarding system [Grafana](http://grafana.org/)
## Get Repo Info
```console
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
```
_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._
## Installing the Chart
To install the chart with the release name `my-release`:
```console
helm install my-release grafana/grafana
```
## Uninstalling the Chart
To uninstall/delete the my-release deployment:
```console
helm delete my-release
```
The command removes all the Kubernetes components associated with the chart and deletes the release.
## Upgrading an existing Release to a new major version
A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an
incompatible breaking change needing manual actions.
### To 4.0.0 (And 3.12.1)
This version requires Helm >= 2.12.0.
### To 5.0.0
You have to add --force to your helm upgrade command as the labels of the chart have changed.
### To 6.0.0
This version requires Helm >= 3.1.0.
## Configuration
| Parameter | Description | Default |
|-------------------------------------------|-----------------------------------------------|---------------------------------------------------------|
| `replicas` | Number of nodes | `1` |
| `podDisruptionBudget.minAvailable` | Pod disruption minimum available | `nil` |
| `podDisruptionBudget.maxUnavailable` | Pod disruption maximum unavailable | `nil` |
| `deploymentStrategy` | Deployment strategy | `{ "type": "RollingUpdate" }` |
| `livenessProbe` | Liveness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10 }` |
| `readinessProbe` | Readiness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } }`|
| `securityContext` | Deployment securityContext | `{"runAsUser": 472, "runAsGroup": 472, "fsGroup": 472}` |
| `priorityClassName` | Name of Priority Class to assign pods | `nil` |
| `image.repository` | Image repository | `grafana/grafana` |
| `image.tag` | Overrides the Grafana image tag whose default is the chart appVersion (`Must be >= 5.0.0`) | `` |
| `image.sha` | Image sha (optional) | `` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `image.pullSecrets` | Image pull secrets (can be templated) | `[]` |
| `service.enabled` | Enable grafana service | `true` |
| `service.type` | Kubernetes service type | `ClusterIP` |
| `service.port` | Kubernetes port where service is exposed | `80` |
| `service.portName` | Name of the port on the service | `service` |
| `service.targetPort` | Internal service is port | `3000` |
| `service.nodePort` | Kubernetes service nodePort | `nil` |
| `service.annotations` | Service annotations (can be templated) | `{}` |
| `service.labels` | Custom labels | `{}` |
| `service.clusterIP` | internal cluster service IP | `nil` |
| `service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `nil` |
| `service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to lb (if supported) | `[]` |
| `service.externalIPs` | service external IP addresses | `[]` |
| `headlessService` | Create a headless service | `false` |
| `extraExposePorts` | Additional service ports for sidecar containers| `[]` |
| `hostAliases` | adds rules to the pod's /etc/hosts | `[]` |
| `ingress.enabled` | Enables Ingress | `false` |
| `ingress.annotations` | Ingress annotations (values are templated) | `{}` |
| `ingress.labels` | Custom labels | `{}` |
| `ingress.path` | Ingress accepted path | `/` |
| `ingress.pathType` | Ingress type of path | `Prefix` |
| `ingress.hosts` | Ingress accepted hostnames | `["chart-example.local"]` |
| `ingress.extraPaths` | Ingress extra paths to prepend to every host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions). Requires `ingress.hosts` to have one or more host entries. | `[]` |
| `ingress.tls` | Ingress TLS configuration | `[]` |
| `resources` | CPU/Memory resource requests/limits | `{}` |
| `nodeSelector` | Node labels for pod assignment | `{}` |
| `tolerations` | Toleration labels for pod assignment | `[]` |
| `affinity` | Affinity settings for pod assignment | `{}` |
| `extraInitContainers` | Init containers to add to the grafana pod | `{}` |
| `extraContainers` | Sidecar containers to add to the grafana pod | `""` |
| `extraContainerVolumes` | Volumes that can be mounted in sidecar containers | `[]` |
| `extraLabels` | Custom labels for all manifests | `{}` |
| `schedulerName` | Name of the k8s scheduler (other than default) | `nil` |
| `global.persistence.enabled` | Use persistent volume to store data | `false` |
| `persistence.type` | Type of persistence (`pvc` or `statefulset`) | `pvc` |
| `global.persistence.size` | Size of persistent volume claim | `20Gi` |
| `persistence.existingClaim` | Use an existing PVC to persist data (can be templated) | `nil` |
| `global.persistence.storageClass` | Type of persistent volume claim | `nil` |
| `global.persistence.accessModes` | Persistence access modes | `[ReadWriteOnce]` |
| `persistence.annotations` | PersistentVolumeClaim annotations | `{}` |
| `persistence.finalizers` | PersistentVolumeClaim finalizers | `[ "kubernetes.io/pvc-protection" ]` |
| `persistence.subPath` | Mount a sub dir of the persistent volume (can be templated) | `nil` |
| `persistence.inMemory.enabled` | If persistence is not enabled, whether to mount the local storage in-memory to improve performance | `false` |
| `persistence.inMemory.sizeLimit` | SizeLimit for the in-memory local storage | `nil` |
| `initChownData.enabled` | If false, don't reset data ownership at startup | true |
| `initChownData.image.repository` | init-chown-data container image repository | `busybox` |
| `initChownData.image.tag` | init-chown-data container image tag | `1.31.1` |
| `initChownData.image.sha` | init-chown-data container image sha (optional)| `""` |
| `initChownData.image.pullPolicy` | init-chown-data container image pull policy | `IfNotPresent` |
| `initChownData.resources` | init-chown-data pod resource requests & limits | `{}` |
| `schedulerName` | Alternate scheduler name | `nil` |
| `env` | Extra environment variables passed to pods | `{}` |
| `envValueFrom` | Environment variables from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. Can be templated | `{}` |
| `envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` |
| `envFromSecrets` | List of Kubernetes secrets (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` |
| `envFromConfigMaps` | List of Kubernetes ConfigMaps (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` |
| `envRenderSecret` | Sensible environment variables passed to pods and stored as secret | `{}` |
| `enableServiceLinks` | Inject Kubernetes services as environment variables. | `true` |
| `extraSecretMounts` | Additional grafana server secret mounts | `[]` |
| `extraVolumeMounts` | Additional grafana server volume mounts | `[]` |
| `createConfigmap` | Enable creating the grafana configmap | `true` |
| `extraConfigmapMounts` | Additional grafana server configMap volume mounts (values are templated) | `[]` |
| `extraEmptyDirMounts` | Additional grafana server emptyDir volume mounts | `[]` |
| `plugins` | Plugins to be loaded along with Grafana | `[]` |
| `datasources` | Configure grafana datasources (passed through tpl) | `{}` |
| `notifiers` | Configure grafana notifiers | `{}` |
| `dashboardProviders` | Configure grafana dashboard providers | `{}` |
| `dashboards` | Dashboards to import | `{}` |
| `dashboardsConfigMaps` | ConfigMaps reference that contains dashboards | `{}` |
| `grafana.ini` | Grafana's primary configuration | `{}` |
| `ldap.enabled` | Enable LDAP authentication | `false` |
| `ldap.existingSecret` | The name of an existing secret containing the `ldap.toml` file, this must have the key `ldap-toml`. | `""` |
| `ldap.config` | Grafana's LDAP configuration | `""` |
| `annotations` | Deployment annotations | `{}` |
| `labels` | Deployment labels | `{}` |
| `podAnnotations` | Pod annotations | `{}` |
| `podLabels` | Pod labels | `{}` |
| `podPortName` | Name of the grafana port on the pod | `grafana` |
| `lifecycleHooks` | Lifecycle hooks for podStart and preStop [Example](https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/#define-poststart-and-prestop-handlers) | `{}` |
| `sidecar.image.repository` | Sidecar image repository | `quay.io/kiwigrid/k8s-sidecar` |
| `sidecar.image.tag` | Sidecar image tag | `1.19.2` |
| `sidecar.image.sha` | Sidecar image sha (optional) | `""` |
| `sidecar.imagePullPolicy` | Sidecar image pull policy | `IfNotPresent` |
| `sidecar.resources` | Sidecar resources | `{}` |
| `sidecar.securityContext` | Sidecar securityContext | `{}` |
| `sidecar.enableUniqueFilenames` | Sets the kiwigrid/k8s-sidecar UNIQUE_FILENAMES environment variable. If set to `true` the sidecar will create unique filenames where duplicate data keys exist between ConfigMaps and/or Secrets within the same or multiple Namespaces. | `false` |
| `sidecar.dashboards.enabled` | Enables the cluster wide search for dashboards and adds/updates/deletes them in grafana | `false` |
| `sidecar.dashboards.SCProvider` | Enables creation of sidecar provider | `true` |
| `sidecar.dashboards.provider.name` | Unique name of the grafana provider | `sidecarProvider` |
| `sidecar.dashboards.provider.orgid` | Id of the organisation, to which the dashboards should be added | `1` |
| `sidecar.dashboards.provider.folder` | Logical folder in which grafana groups dashboards | `""` |
| `sidecar.dashboards.provider.disableDelete` | Activate to avoid the deletion of imported dashboards | `false` |
| `sidecar.dashboards.provider.allowUiUpdates` | Allow updating provisioned dashboards from the UI | `false` |
| `sidecar.dashboards.provider.type` | Provider type | `file` |
| `sidecar.dashboards.provider.foldersFromFilesStructure` | Allow Grafana to replicate dashboard structure from filesystem. | `false` |
| `sidecar.dashboards.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` |
| `sidecar.skipTlsVerify` | Set to true to skip tls verification for kube api calls | `nil` |
| `sidecar.dashboards.label` | Label that config maps with dashboards should have to be added | `grafana_dashboard` |
| `sidecar.dashboards.labelValue` | Label value that config maps with dashboards should have to be added | `""` |
| `sidecar.dashboards.folder` | Folder in the pod that should hold the collected dashboards (unless `sidecar.dashboards.defaultFolderName` is set). This path will be mounted. | `/tmp/dashboards` |
| `sidecar.dashboards.folderAnnotation` | The annotation the sidecar will look for in configmaps to override the destination folder for files | `nil` |
| `sidecar.dashboards.defaultFolderName` | The default folder name, it will create a subfolder under the `sidecar.dashboards.folder` and put dashboards in there instead | `nil` |
| `sidecar.dashboards.searchNamespace` | Namespaces list. If specified, the sidecar will search for dashboards config-maps inside these namespaces.Otherwise the namespace in which the sidecar is running will be used.It's also possible to specify ALL to search in all namespaces. | `nil` |
| `sidecar.dashboards.script` | Absolute path to shell script to execute after a configmap got reloaded. | `nil` |
| `sidecar.dashboards.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` |
| `sidecar.dashboards.extraMounts` | Additional dashboard sidecar volume mounts. | `[]` |
| `sidecar.datasources.enabled` | Enables the cluster wide search for datasources and adds/updates/deletes them in grafana |`false` |
| `sidecar.datasources.label` | Label that config maps with datasources should have to be added | `grafana_datasource` |
| `sidecar.datasources.labelValue` | Label value that config maps with datasources should have to be added | `""` |
| `sidecar.datasources.searchNamespace` | Namespaces list. If specified, the sidecar will search for datasources config-maps inside these namespaces.Otherwise the namespace in which the sidecar is running will be used.It's also possible to specify ALL to search in all namespaces. | `nil` |
| `sidecar.datasources.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` |
| `sidecar.datasources.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/datasources/reload"` |
| `sidecar.datasources.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` |
| `sidecar.notifiers.enabled` | Enables the cluster wide search for notifiers and adds/updates/deletes them in grafana | `false` |
| `sidecar.notifiers.label` | Label that config maps with notifiers should have to be added | `grafana_notifier` |
| `sidecar.notifiers.searchNamespace` | Namespaces list. If specified, the sidecar will search for notifiers config-maps (or secrets) inside these namespaces.Otherwise the namespace in which the sidecar is running will be used.It's also possible to specify ALL to search in all namespaces. | `nil` |
| `sidecar.notifiers.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` |
| `smtp.existingSecret` | The name of an existing secret containing the SMTP credentials. | `""` |
| `smtp.userKey` | The key in the existing SMTP secret containing the username. | `"user"` |
| `smtp.passwordKey` | The key in the existing SMTP secret containing the password. | `"password"` |
| `admin.existingSecret` | The name of an existing secret containing the admin credentials (can be templated). | `""` |
| `admin.userKey` | The key in the existing admin secret containing the username. | `"admin-user"` |
| `admin.passwordKey` | The key in the existing admin secret containing the password. | `"admin-password"` |
| `serviceAccount.autoMount` | Automount the service account token in the pod| `true` |
| `serviceAccount.annotations` | ServiceAccount annotations | |
| `serviceAccount.create` | Create service account | `true` |
| `serviceAccount.name` | Service account name to use, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `` |
| `serviceAccount.nameTest` | Service account name to use for test, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `nil` |
| `rbac.create` | Create and use RBAC resources | `true` |
| `rbac.namespaced` | Creates Role and Rolebinding instead of the default ClusterRole and ClusteRoleBindings for the grafana instance | `false` |
| `rbac.useExistingRole` | Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to the rolename set here. | `nil` |
| `rbac.pspEnabled` | Create PodSecurityPolicy (with `rbac.create`, grant roles permissions as well) | `true` |
| `rbac.pspUseAppArmor` | Enforce AppArmor in created PodSecurityPolicy (requires `rbac.pspEnabled`) | `true` |
| `rbac.extraRoleRules` | Additional rules to add to the Role | [] |
| `rbac.extraClusterRoleRules` | Additional rules to add to the ClusterRole | [] |
| `command` | Define command to be executed by grafana container at startup | `nil` |
| `testFramework.enabled` | Whether to create test-related resources | `true` |
| `testFramework.image` | `test-framework` image repository. | `bats/bats` |
| `testFramework.tag` | `test-framework` image tag. | `v1.4.1` |
| `testFramework.imagePullPolicy` | `test-framework` image pull policy. | `IfNotPresent` |
| `testFramework.securityContext` | `test-framework` securityContext | `{}` |
| `downloadDashboards.env` | Environment variables to be passed to the `download-dashboards` container | `{}` |
| `downloadDashboards.envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` |
| `downloadDashboards.resources` | Resources of `download-dashboards` container | `{}` |
| `downloadDashboardsImage.repository` | Curl docker image repo | `curlimages/curl` |
| `downloadDashboardsImage.tag` | Curl docker image tag | `7.73.0` |
| `downloadDashboardsImage.sha` | Curl docker image sha (optional) | `""` |
| `downloadDashboardsImage.pullPolicy` | Curl docker image pull policy | `IfNotPresent` |
| `namespaceOverride` | Override the deployment namespace | `""` (`Release.Namespace`) |
| `serviceMonitor.enabled` | Use servicemonitor from prometheus operator | `false` |
| `serviceMonitor.namespace` | Namespace this servicemonitor is installed in | |
| `serviceMonitor.interval` | How frequently Prometheus should scrape | `1m` |
| `serviceMonitor.path` | Path to scrape | `/metrics` |
| `serviceMonitor.scheme` | Scheme to use for metrics scraping | `http` |
| `serviceMonitor.tlsConfig` | TLS configuration block for the endpoint | `{}` |
| `serviceMonitor.labels` | Labels for the servicemonitor passed to Prometheus Operator | `{}` |
| `serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `30s` |
| `serviceMonitor.relabelings` | MetricRelabelConfigs to apply to samples before ingestion. | `[]` |
| `revisionHistoryLimit` | Number of old ReplicaSets to retain | `10` |
| `imageRenderer.enabled` | Enable the image-renderer deployment & service | `false` |
| `imageRenderer.image.repository` | image-renderer Image repository | `grafana/grafana-image-renderer` |
| `imageRenderer.image.tag` | image-renderer Image tag | `latest` |
| `imageRenderer.image.sha` | image-renderer Image sha (optional) | `""` |
| `imageRenderer.image.pullPolicy` | image-renderer ImagePullPolicy | `Always` |
| `imageRenderer.env` | extra env-vars for image-renderer | `{}` |
| `imageRenderer.serviceAccountName` | image-renderer deployment serviceAccountName | `""` |
| `imageRenderer.securityContext` | image-renderer deployment securityContext | `{}` |
| `imageRenderer.hostAliases` | image-renderer deployment Host Aliases | `[]` |
| `imageRenderer.priorityClassName` | image-renderer deployment priority class | `''` |
| `imageRenderer.service.enabled` | Enable the image-renderer service | `true` |
| `imageRenderer.service.portName` | image-renderer service port name | `http` |
| `imageRenderer.service.port` | image-renderer service port used by both service and deployment | `8081` |
| `imageRenderer.grafanaProtocol` | Protocol to use for image renderer callback url | `http` |
| `imageRenderer.grafanaSubPath` | Grafana sub path to use for image renderer callback url | `''` |
| `imageRenderer.podPortName` | name of the image-renderer port on the pod | `http` |
| `imageRenderer.revisionHistoryLimit` | number of image-renderer replica sets to keep | `10` |
| `imageRenderer.networkPolicy.limitIngress` | Enable a NetworkPolicy to limit inbound traffic from only the created grafana pods | `true` |
| `imageRenderer.networkPolicy.limitEgress` | Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods | `false` |
| `imageRenderer.resources` | Set resource limits for image-renderer pdos | `{}` |
| `imageRenderer.nodeSelector` | Node labels for pod assignment | `{}` |
| `imageRenderer.tolerations` | Toleration labels for pod assignment | `[]` |
| `imageRenderer.affinity` | Affinity settings for pod assignment | `{}` |
| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources. | `false` |
| `networkPolicy.allowExternal` | Don't require client label for connections | `true` |
| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed | `{}` |
| `networkPolicy.ingress` | Enable the creation of an ingress network policy | `true` |
| `networkPolicy.egress.enabled` | Enable the creation of an egress network policy | `false` |
| `networkPolicy.egress.ports` | An array of ports to allow for the egress | `[]` |
| `enableKubeBackwardCompatibility` | Enable backward compatibility of kubernetes where pod's defintion version below 1.13 doesn't have the enableServiceLinks option | `false` |
### Example ingress with path
With grafana 6.3 and above
```yaml
grafana.ini:
server:
domain: monitoring.example.com
root_url: "%(protocol)s://%(domain)s/grafana"
serve_from_sub_path: true
ingress:
enabled: true
hosts:
- "monitoring.example.com"
path: "/grafana"
```
### Example of extraVolumeMounts
Volume can be type persistentVolumeClaim or hostPath but not both at same time.
If none existingClaim or hostPath argument is givent then type is emptyDir.
```yaml
- extraVolumeMounts:
- name: plugins
mountPath: /var/lib/grafana/plugins
subPath: configs/grafana/plugins
existingClaim: existing-grafana-claim
readOnly: false
- name: dashboards
mountPath: /var/lib/grafana/dashboards
hostPath: /usr/shared/grafana/dashboards
readOnly: false
```
## Import dashboards
There are a few methods to import dashboards to Grafana. Below are some examples and explanations as to how to use each method:
```yaml
dashboards:
default:
some-dashboard:
json: |
{
"annotations":
...
# Complete json file here
...
"title": "Some Dashboard",
"uid": "abcd1234",
"version": 1
}
custom-dashboard:
# This is a path to a file inside the dashboards directory inside the chart directory
file: dashboards/custom-dashboard.json
prometheus-stats:
# Ref: https://grafana.com/dashboards/2
gnetId: 2
revision: 2
datasource: Prometheus
local-dashboard:
url: https://raw.githubusercontent.com/user/repository/master/dashboards/dashboard.json
```
## BASE64 dashboards
Dashboards could be stored on a server that does not return JSON directly and instead of it returns a Base64 encoded file (e.g. Gerrit)
A new parameter has been added to the url use case so if you specify a b64content value equals to true after the url entry a Base64 decoding is applied before save the file to disk.
If this entry is not set or is equals to false not decoding is applied to the file before saving it to disk.
### Gerrit use case
Gerrit API for download files has the following schema: <https://yourgerritserver/a/{project-name}/branches/{branch-id}/files/{file-id}/content> where {project-name} and
{file-id} usually has '/' in their values and so they MUST be replaced by %2F so if project-name is user/repo, branch-id is master and file-id is equals to dir1/dir2/dashboard
the url value is <https://yourgerritserver/a/user%2Frepo/branches/master/files/dir1%2Fdir2%2Fdashboard/content>
## Sidecar for dashboards
If the parameter `sidecar.dashboards.enabled` is set, a sidecar container is deployed in the grafana
pod. This container watches all configmaps (or secrets) in the cluster and filters out the ones with
a label as defined in `sidecar.dashboards.label`. The files defined in those configmaps are written
to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported
dashboards are deleted/updated.
A recommendation is to use one configmap per dashboard, as a reduction of multiple dashboards inside
one configmap is currently not properly mirrored in grafana.
Example dashboard config:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: sample-grafana-dashboard
labels:
grafana_dashboard: "1"
data:
k8s-dashboard.json: |-
[...]
```
## Sidecar for datasources
If the parameter `sidecar.datasources.enabled` is set, an init container is deployed in the grafana
pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and
filters out the ones with a label as defined in `sidecar.datasources.label`. The files defined in
those secrets are written to a folder and accessed by grafana on startup. Using these yaml files,
the data sources in grafana can be imported.
Secrets are recommended over configmaps for this usecase because datasources usually contain private
data like usernames and passwords. Secrets are the more appropriate cluster resource to manage those.
Example values to add a datasource adapted from [Grafana](http://docs.grafana.org/administration/provisioning/#example-datasource-config-file):
```yaml
datasources:
datasources.yaml:
apiVersion: 1
datasources:
# <string, required> name of the datasource. Required
- name: Graphite
# <string, required> datasource type. Required
type: graphite
# <string, required> access mode. proxy or direct (Server or Browser in the UI). Required
access: proxy
# <int> org id. will default to orgId 1 if not specified
orgId: 1
# <string> url
url: http://localhost:8080
# <string> database password, if used
password:
# <string> database user, if used
user:
# <string> database name, if used
database:
# <bool> enable/disable basic auth
basicAuth:
# <string> basic auth username
basicAuthUser:
# <string> basic auth password
basicAuthPassword:
# <bool> enable/disable with credentials headers
withCredentials:
# <bool> mark as default datasource. Max one per org
isDefault:
# <map> fields that will be converted to json and stored in json_data
jsonData:
graphiteVersion: "1.1"
tlsAuth: true
tlsAuthWithCACert: true
# <string> json object of data that will be encrypted.
secureJsonData:
tlsCACert: "..."
tlsClientCert: "..."
tlsClientKey: "..."
version: 1
# <bool> allow users to edit datasources from the UI.
editable: false
```
## Sidecar for notifiers
If the parameter `sidecar.notifiers.enabled` is set, an init container is deployed in the grafana
pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and
filters out the ones with a label as defined in `sidecar.notifiers.label`. The files defined in
those secrets are written to a folder and accessed by grafana on startup. Using these yaml files,
the notification channels in grafana can be imported. The secrets must be created before
`helm install` so that the notifiers init container can list the secrets.
Secrets are recommended over configmaps for this usecase because alert notification channels usually contain
private data like SMTP usernames and passwords. Secrets are the more appropriate cluster resource to manage those.
Example datasource config adapted from [Grafana](https://grafana.com/docs/grafana/latest/administration/provisioning/#alert-notification-channels):
```yaml
notifiers:
- name: notification-channel-1
type: slack
uid: notifier1
# either
org_id: 2
# or
org_name: Main Org.
is_default: true
send_reminder: true
frequency: 1h
disable_resolve_message: false
# See `Supported Settings` section for settings supporter for each
# alert notification type.
settings:
recipient: 'XXX'
token: 'xoxb'
uploadImage: true
url: https://slack.com
delete_notifiers:
- name: notification-channel-1
uid: notifier1
org_id: 2
- name: notification-channel-2
# default org_id: 1
```
## How to serve Grafana with a path prefix (/grafana)
In order to serve Grafana with a prefix (e.g., <http://example.com/grafana>), add the following to your values.yaml.
```yaml
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/use-regex: "true"
path: /grafana/?(.*)
hosts:
- k8s.example.dev
grafana.ini:
server:
root_url: http://localhost:3000/grafana # this host can be localhost
```
## How to securely reference secrets in grafana.ini
This example uses Grafana uses [file providers](https://grafana.com/docs/grafana/latest/administration/configuration/#file-provider) for secret values and the `extraSecretMounts` configuration flag (Additional grafana server secret mounts) to mount the secrets.
In grafana.ini:
```yaml
grafana.ini:
[auth.generic_oauth]
enabled = true
client_id = $__file{/etc/secrets/auth_generic_oauth/client_id}
client_secret = $__file{/etc/secrets/auth_generic_oauth/client_secret}
```
Existing secret, or created along with helm:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: auth-generic-oauth-secret
type: Opaque
stringData:
client_id: <value>
client_secret: <value>
```
Include in the `extraSecretMounts` configuration flag:
```yaml
- extraSecretMounts:
- name: auth-generic-oauth-secret-mount
secretName: auth-generic-oauth-secret
defaultMode: 0440
mountPath: /etc/secrets/auth_generic_oauth
readOnly: true
```
### extraSecretMounts using a Container Storage Interface (CSI) provider
This example uses a CSI driver e.g. retrieving secrets using [Azure Key Vault Provider](https://github.com/Azure/secrets-store-csi-driver-provider-azure)
```yaml
- extraSecretMounts:
- name: secrets-store-inline
mountPath: /run/secrets
readOnly: true
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "my-provider"
nodePublishSecretRef:
name: akv-creds
```
## Image Renderer Plug-In
This chart supports enabling [remote image rendering](https://github.com/grafana/grafana-image-renderer/blob/master/README.md#run-in-docker)
```yaml
imageRenderer:
enabled: true
```
### Image Renderer NetworkPolicy
By default the image-renderer pods will have a network policy which only allows ingress traffic from the created grafana instance
### High Availability for unified alerting
If you want to run Grafana in a high availability cluster you need to enable
the headless service by setting `headlessService: true` in your `values.yaml`
file.
As next step you have to setup the `grafana.ini` in your `values.yaml` in a way
that it will make use of the headless service to obtain all the IPs of the
cluster. You should replace ``{{ Name }}`` with the name of your helm deployment.
```yaml
grafana.ini:
...
unified_alerting:
enabled: true
ha_peers: {{ Name }}-headless:9094
alerting:
enabled: false
```

View File

@ -0,0 +1 @@
# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml.

View File

@ -0,0 +1,16 @@
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/instance: grafana-test
app.kubernetes.io/name: grafana
topologyKey: failure-domain.beta.kubernetes.io/zone
weight: 100
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/instance: grafana-test
app.kubernetes.io/name: grafana
topologyKey: kubernetes.io/hostname

View File

@ -0,0 +1,53 @@
dashboards:
my-provider:
my-awesome-dashboard:
# An empty but valid dashboard
json: |
{
"__inputs": [],
"__requires": [
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "6.3.5"
}
],
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": null,
"links": [],
"panels": [],
"schemaVersion": 19,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s"]
},
"timezone": "",
"title": "Dummy Dashboard",
"uid": "IdcYQooWk",
"version": 1
}
datasource: Prometheus

View File

@ -0,0 +1,19 @@
dashboards:
my-provider:
my-awesome-dashboard:
gnetId: 10000
revision: 1
datasource: Prometheus
dashboardProviders:
dashboardproviders.yaml:
apiVersion: 1
providers:
- name: 'my-provider'
orgId: 1
folder: ''
type: file
updateIntervalSeconds: 10
disableDeletion: true
editable: true
options:
path: /var/lib/grafana/dashboards/my-provider

View File

@ -0,0 +1,7 @@
extraConfigmapMounts:
- name: '{{ template "grafana.fullname" . }}'
configMap: '{{ template "grafana.fullname" . }}'
mountPath: /var/lib/grafana/dashboards/test-dashboard.json
# This is not a realistic test, but for this we only care about extraConfigmapMounts not being empty and pointing to an existing ConfigMap
subPath: grafana.ini
readOnly: true

View File

@ -0,0 +1,19 @@
podLabels:
customLableA: Aaaaa
imageRenderer:
enabled: true
env:
RENDERING_ARGS: --disable-gpu,--window-size=1280x758
RENDERING_MODE: clustered
podLabels:
customLableB: Bbbbb
networkPolicy:
limitIngress: true
limitEgress: true
resources:
limits:
cpu: 1000m
memory: 1000Mi
requests:
cpu: 500m
memory: 50Mi

View File

@ -0,0 +1,3 @@
persistence:
type: pvc
enabled: true

View File

@ -0,0 +1,54 @@
1. Get your '{{ .Values.adminUser }}' user password by running:
kubectl get secret --namespace {{ template "grafana.namespace" . }} {{ template "grafana.fullname" . }} -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
2. The Grafana server can be accessed via port {{ .Values.service.port }} on the following DNS name from within your cluster:
{{ template "grafana.fullname" . }}.{{ template "grafana.namespace" . }}.svc.cluster.local
{{ if .Values.ingress.enabled }}
If you bind grafana to 80, please update values in values.yaml and reinstall:
```
securityContext:
runAsUser: 0
runAsGroup: 0
fsGroup: 0
command:
- "setcap"
- "'cap_net_bind_service=+ep'"
- "/usr/sbin/grafana-server &&"
- "sh"
- "/run.sh"
```
Details refer to https://grafana.com/docs/installation/configuration/#http-port.
Or grafana would always crash.
From outside the cluster, the server URL(s) are:
{{- range .Values.ingress.hosts }}
http://{{ . }}
{{- end }}
{{ else }}
Get the Grafana URL to visit by running these commands in the same shell:
{{ if contains "NodePort" .Values.service.type -}}
export NODE_PORT=$(kubectl get --namespace {{ template "grafana.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "grafana.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ template "grafana.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{ else if contains "LoadBalancer" .Values.service.type -}}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc --namespace {{ template "grafana.namespace" . }} -w {{ template "grafana.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ template "grafana.namespace" . }} {{ template "grafana.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
http://$SERVICE_IP:{{ .Values.service.port -}}
{{ else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ template "grafana.namespace" . }} -l "app.kubernetes.io/name={{ template "grafana.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace {{ template "grafana.namespace" . }} port-forward $POD_NAME 3000
{{- end }}
{{- end }}
3. Login with the password from step 1 and the username: {{ .Values.adminUser }}
{{- if not .Values.global.persistence.enabled }}
#################################################################################
###### WARNING: Persistence is disabled!!! You will lose your data when #####
###### the Grafana pod is terminated. #####
#################################################################################
{{- end }}

View File

@ -0,0 +1,3 @@
{{/* Autogenerated, do NOT modify */}}
{{- define "k10.grafanaImageTag" -}}9.1.5{{- end -}}
{{- define "k10.grafanaInitContainerImageTag" -}}8.6-941{{- end -}}

View File

@ -0,0 +1,274 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "grafana.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 "grafana.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 "grafana.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create the name of the service account
*/}}
{{- define "grafana.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "grafana.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
{{- define "grafana.serviceAccountNameTest" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (print (include "grafana.fullname" .) "-test") .Values.serviceAccount.nameTest }}
{{- else -}}
{{ default "default" .Values.serviceAccount.nameTest }}
{{- end -}}
{{- end -}}
{{/*
Allow the release namespace to be overridden for multi-namespace deployments in combined charts
*/}}
{{- define "grafana.namespace" -}}
{{- if .Values.namespaceOverride -}}
{{- .Values.namespaceOverride -}}
{{- else -}}
{{- .Release.Namespace -}}
{{- end -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "grafana.labels" -}}
helm.sh/chart: {{ include "grafana.chart" . }}
{{ include "grafana.selectorLabels" . }}
{{- if or .Chart.AppVersion .Values.image.tag }}
app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- if .Values.extraLabels }}
{{ toYaml .Values.extraLabels }}
{{- end }}
app.kubernetes.io/name: {{ include "grafana.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Selector labels
K10 NOTE:
The selector labels here (`app` and `release`) are divergent from the
selector labels set by the upstream chart. This is intentional since a
Deployment's `spec.selector` is immutable and K10 has already been shipped
with these values.
A change to these selector labels will mean that all customers must manually
delete the Grafana Deployment before upgrading, which is a situation we don't
want for our customers.
Instead, the `app.kubernetes.io/name` and `app.kubernetes.io/instance` labels
are included in the `grafana.labels` block above.
*/}}
{{- define "grafana.selectorLabels" -}}
app: {{ include "grafana.name" . }}
release: {{ .Release.Name }}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "grafana.imageRenderer.labels" -}}
helm.sh/chart: {{ include "grafana.chart" . }}
{{ include "grafana.imageRenderer.selectorLabels" . }}
{{- if or .Chart.AppVersion .Values.image.tag }}
app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels ImageRenderer
*/}}
{{- define "grafana.imageRenderer.selectorLabels" -}}
app.kubernetes.io/name: {{ include "grafana.name" . }}-image-renderer
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Looks if there's an existing secret and reuse its password. If not it generates
new password and use it.
*/}}
{{- define "grafana.password" -}}
{{- $secret := (lookup "v1" "Secret" (include "grafana.namespace" .) (include "grafana.fullname" .) ) -}}
{{- if $secret -}}
{{- index $secret "data" "admin-password" -}}
{{- else -}}
{{- (randAlphaNum 40) | b64enc | quote -}}
{{- end -}}
{{- end -}}
{{/*
Return the appropriate apiVersion for rbac.
*/}}
{{- define "grafana.rbac.apiVersion" -}}
{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" }}
{{- print "rbac.authorization.k8s.io/v1" -}}
{{- else -}}
{{- print "rbac.authorization.k8s.io/v1beta1" -}}
{{- end -}}
{{- end -}}
{{/*
Return the appropriate apiVersion for ingress.
*/}}
{{- define "grafana.ingress.apiVersion" -}}
{{- if and (.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" .Capabilities.KubeVersion.Version) -}}
{{- print "networking.k8s.io/v1" -}}
{{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}}
{{- print "networking.k8s.io/v1beta1" -}}
{{- else -}}
{{- print "extensions/v1beta1" -}}
{{- end -}}
{{- end -}}
{{/*
Return the appropriate apiVersion for podSecurityPolicy.
*/}}
{{- define "grafana.podSecurityPolicy.apiVersion" -}}
{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1") (semverCompare ">= 1.16-0" .Capabilities.KubeVersion.Version) -}}
{{- print "policy/v1beta1" -}}
{{- else -}}
{{- print "extensions/v1beta1" -}}
{{- end -}}
{{- end -}}
{{/*
Return the appropriate apiVersion for podDisruptionBudget.
*/}}
{{- define "grafana.podDisruptionBudget.apiVersion" -}}
{{- if and (.Capabilities.APIVersions.Has "policy/v1") (semverCompare ">= 1.21-0" .Capabilities.KubeVersion.Version) -}}
{{- print "policy/v1" -}}
{{- else -}}
{{- print "policy/v1beta1" -}}
{{- end -}}
{{- end -}}
{{/*
Return if ingress is stable.
*/}}
{{- define "grafana.ingress.isStable" -}}
{{- eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1" -}}
{{- end -}}
{{/*
Return if ingress supports ingressClassName.
*/}}
{{- define "grafana.ingress.supportsIngressClassName" -}}
{{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) -}}
{{- end -}}
{{/*
Return if ingress supports pathType.
*/}}
{{- define "grafana.ingress.supportsPathType" -}}
{{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) -}}
{{- end -}}
{{/*
Figure out the grafana image tag
based on the value of global.upstreamCertifiedImages
*/}}
{{- define "get.grafanaImageTag"}}
{{- if .Values.global.airgapped.repository }}
{{- printf "k10-%s" (include "k10.grafanaImageTag" .) }}
{{- else }}
{{- printf "%s" (include "k10.grafanaImageTag" .) }}
{{- end }}
{{- end }}
{{- define "get.grafanaImageRepo" }}
{{- if .Values.global.upstreamCertifiedImages }}
{{- printf "%s/%s/grafana" .Values.k10image.registry .Values.k10image.repository }}
{{- else }}
{{- print .Values.image.repository }}
{{- end }}
{{- end }}
{{/*
Figure out the config based on
the value of airgapped.repository
*/}}
{{- define "get.grafanaServerimage" }}
{{- if not .Values.global.rhMarketPlace }}
{{- if .Values.global.airgapped.repository }}
{{- printf "%s/grafana:%s" .Values.global.airgapped.repository (include "get.grafanaImageTag" .) }}
{{- else }}
{{- printf "%s:%s" (include "get.grafanaImageRepo" .) (include "get.grafanaImageTag" .) }}
{{- end }}
{{- else }}
{{- printf "%s" .Values.global.images.grafana }}
{{- end -}}
{{- end }}
{{/*
Figure out the grafana init container busy box image tag
based on the value of global.airgapped.repository
*/}}
{{- define "get.grafanaInitContainerImageTag"}}
{{- if .Values.global.airgapped.repository }}
{{- printf "k10-%s" (include "k10.grafanaInitContainerImageTag" .) }}
{{- else }}
{{- printf "%s" (include "k10.grafanaInitContainerImageTag" .) }}
{{- end }}
{{- end }}
{{- define "get.grafanaInitContainerImageRepo" }}
{{- if .Values.global.upstreamCertifiedImages }}
{{- printf "%s/%s/ubi-minimal" .Values.k10image.registry .Values.k10image.repository }}
{{- else }}
{{- print .Values.ubi.image.repository }}
{{- end }}
{{- end }}
{{/*
Figure out the config based on
the value of airgapped.repository
*/}}
{{- define "get.grafanaInitContainerImage" }}
{{- if not .Values.global.rhMarketPlace }}
{{- if .Values.global.airgapped.repository }}
{{- printf "%s/ubi-minimal:%s" .Values.global.airgapped.repository (include "get.grafanaInitContainerImageTag" .) }}
{{- else }}
{{- printf "%s:%s" (include "get.grafanaInitContainerImageRepo" .) (include "get.grafanaInitContainerImageTag" .) }}
{{- end }}
{{- else }}
{{- printf "%s:%s" (include "get.grafanaInitContainerImageRepo" .) (include "get.grafanaInitContainerImageTag" .) }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,754 @@
{{- define "grafana.pod" -}}
{{- if .Values.schedulerName }}
schedulerName: "{{ .Values.schedulerName }}"
{{- end }}
serviceAccountName: {{ template "grafana.serviceAccountName" . }}
automountServiceAccountToken: {{ .Values.serviceAccount.autoMount }}
{{- if .Values.securityContext }}
securityContext:
{{ toYaml .Values.securityContext | indent 2 }}
{{- end }}
{{- if .Values.hostAliases }}
hostAliases:
{{ toYaml .Values.hostAliases | indent 2 }}
{{- end }}
{{- if .Values.priorityClassName }}
priorityClassName: {{ .Values.priorityClassName }}
{{- end }}
{{- if ( or .Values.global.persistence.enabled .Values.dashboards .Values.sidecar.notifiers.enabled .Values.extraInitContainers (and .Values.sidecar.datasources.enabled .Values.sidecar.datasources.initDatasources)) }}
initContainers:
{{- end }}
{{- if ( and .Values.global.persistence.enabled .Values.initChownData.enabled ) }}
- name: init-chown-data
image: "{{ include "get.grafanaInitContainerImage" . }}"
imagePullPolicy: {{ .Values.ubi.image.pullPolicy }}
securityContext:
runAsNonRoot: false
runAsUser: 0
command: ["chown", "-R", "{{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }}", "/var/lib/grafana"]
resources:
{{ toYaml .Values.initChownData.resources | indent 6 }}
volumeMounts:
- name: storage
mountPath: "/var/lib/grafana"
{{- if .Values.persistence.subPath }}
subPath: {{ tpl .Values.persistence.subPath . }}
{{- end }}
{{- end }}
{{- if .Values.dashboards }}
- name: download-dashboards
{{- if .Values.downloadDashboardsImage.sha }}
image: "{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}@sha256:{{ .Values.downloadDashboardsImage.sha }}"
{{- else }}
image: "{{ include "get.grafanaInitContainerImage" . }}"
{{- end }}
imagePullPolicy: {{ .Values.downloadDashboardsImage.pullPolicy }}
command: ["/bin/sh"]
args: [ "-c", "mkdir -p /var/lib/grafana/dashboards/default && /bin/sh -x /etc/grafana/download_dashboards.sh" ]
resources:
{{ toYaml .Values.downloadDashboards.resources | indent 6 }}
env:
{{- range $key, $value := .Values.downloadDashboards.env }}
- name: "{{ $key }}"
value: "{{ $value }}"
{{- end }}
{{- if .Values.downloadDashboards.envFromSecret }}
envFrom:
- secretRef:
name: {{ tpl .Values.downloadDashboards.envFromSecret . }}
{{- end }}
volumeMounts:
- name: config
mountPath: "/etc/grafana/download_dashboards.sh"
subPath: download_dashboards.sh
- name: storage
mountPath: "/var/lib/grafana"
{{- if .Values.persistence.subPath }}
subPath: {{ tpl .Values.persistence.subPath . }}
{{- end }}
{{- range .Values.extraSecretMounts }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
readOnly: {{ .readOnly }}
{{- end }}
{{- end }}
{{- if and .Values.sidecar.datasources.enabled .Values.sidecar.datasources.initDatasources }}
- name: {{ template "grafana.name" . }}-init-sc-datasources
{{- if .Values.sidecar.image.sha }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}"
{{- else }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}"
{{- end }}
imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }}
env:
- name: METHOD
value: "LIST"
- name: LABEL
value: "{{ .Values.sidecar.datasources.label }}"
{{- if .Values.sidecar.datasources.labelValue }}
- name: LABEL_VALUE
value: {{ quote .Values.sidecar.datasources.labelValue }}
{{- end }}
- name: FOLDER
value: "/etc/grafana/provisioning/datasources"
- name: RESOURCE
value: {{ quote .Values.sidecar.datasources.resource }}
{{- if .Values.sidecar.enableUniqueFilenames }}
- name: UNIQUE_FILENAMES
value: "{{ .Values.sidecar.enableUniqueFilenames }}"
{{- end }}
{{- if .Values.sidecar.datasources.searchNamespace }}
- name: NAMESPACE
value: "{{ .Values.sidecar.datasources.searchNamespace | join "," }}"
{{- end }}
{{- if .Values.sidecar.skipTlsVerify }}
- name: SKIP_TLS_VERIFY
value: "{{ .Values.sidecar.skipTlsVerify }}"
{{- end }}
resources:
{{ toYaml .Values.sidecar.resources | indent 6 }}
{{- if .Values.sidecar.securityContext }}
securityContext:
{{- toYaml .Values.sidecar.securityContext | nindent 6 }}
{{- end }}
volumeMounts:
- name: sc-datasources-volume
mountPath: "/etc/grafana/provisioning/datasources"
{{- end }}
{{- if .Values.sidecar.notifiers.enabled }}
- name: {{ template "grafana.name" . }}-sc-notifiers
{{- if .Values.sidecar.image.sha }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}"
{{- else }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}"
{{- end }}
imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }}
env:
- name: METHOD
value: LIST
- name: LABEL
value: "{{ .Values.sidecar.notifiers.label }}"
- name: FOLDER
value: "/etc/grafana/provisioning/notifiers"
- name: RESOURCE
value: {{ quote .Values.sidecar.notifiers.resource }}
{{- if .Values.sidecar.enableUniqueFilenames }}
- name: UNIQUE_FILENAMES
value: "{{ .Values.sidecar.enableUniqueFilenames }}"
{{- end }}
{{- if .Values.sidecar.notifiers.searchNamespace }}
- name: NAMESPACE
value: "{{ .Values.sidecar.notifiers.searchNamespace | join "," }}"
{{- end }}
{{- if .Values.sidecar.skipTlsVerify }}
- name: SKIP_TLS_VERIFY
value: "{{ .Values.sidecar.skipTlsVerify }}"
{{- end }}
{{- if .Values.sidecar.livenessProbe }}
livenessProbe:
{{ toYaml .Values.livenessProbe | indent 6 }}
{{- end }}
{{- if .Values.sidecar.readinessProbe }}
readinessProbe:
{{ toYaml .Values.readinessProbe | indent 6 }}
{{- end }}
resources:
{{ toYaml .Values.sidecar.resources | indent 6 }}
{{- if .Values.sidecar.securityContext }}
securityContext:
{{- toYaml .Values.sidecar.securityContext | nindent 6 }}
{{- end }}
volumeMounts:
- name: sc-notifiers-volume
mountPath: "/etc/grafana/provisioning/notifiers"
{{- end}}
{{- if .Values.extraInitContainers }}
{{ tpl (toYaml .Values.extraInitContainers) . | indent 2 }}
{{- end }}
{{- if (or .Values.global.imagePullSecret .Values.image.pullSecrets) }}
imagePullSecrets:
{{- if .Values.global.imagePullSecret }}
- name: {{ .Values.global.imagePullSecret }}
{{- end }}
{{- $root := . }}
{{- range .Values.image.pullSecrets }}
- name: {{ tpl . $root }}
{{- end}}
{{- end }}
{{- if not .Values.enableKubeBackwardCompatibility }}
enableServiceLinks: {{ .Values.enableServiceLinks }}
{{- end }}
containers:
{{- if .Values.sidecar.dashboards.enabled }}
- name: {{ template "grafana.name" . }}-sc-dashboard
{{- if .Values.sidecar.image.sha }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}"
{{- else }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}"
{{- end }}
imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }}
env:
- name: METHOD
value: {{ .Values.sidecar.dashboards.watchMethod }}
- name: LABEL
value: "{{ .Values.sidecar.dashboards.label }}"
{{- if .Values.sidecar.dashboards.labelValue }}
- name: LABEL_VALUE
value: {{ quote .Values.sidecar.dashboards.labelValue }}
{{- end }}
{{- if .Values.sidecar.logLevel }}
- name: LOG_LEVEL
value: {{ quote .Values.sidecar.logLevel }}
{{- end }}
- name: FOLDER
value: "{{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }}"
- name: RESOURCE
value: {{ quote .Values.sidecar.dashboards.resource }}
{{- if .Values.sidecar.enableUniqueFilenames }}
- name: UNIQUE_FILENAMES
value: "{{ .Values.sidecar.enableUniqueFilenames }}"
{{- end }}
{{- if .Values.sidecar.dashboards.searchNamespace }}
- name: NAMESPACE
value: "{{ .Values.sidecar.dashboards.searchNamespace | join "," }}"
{{- end }}
{{- if .Values.sidecar.skipTlsVerify }}
- name: SKIP_TLS_VERIFY
value: "{{ .Values.sidecar.skipTlsVerify }}"
{{- end }}
{{- if .Values.sidecar.dashboards.folderAnnotation }}
- name: FOLDER_ANNOTATION
value: "{{ .Values.sidecar.dashboards.folderAnnotation }}"
{{- end }}
{{- if .Values.sidecar.dashboards.script }}
- name: SCRIPT
value: "{{ .Values.sidecar.dashboards.script }}"
{{- end }}
{{- if .Values.sidecar.dashboards.watchServerTimeout }}
- name: WATCH_SERVER_TIMEOUT
value: "{{ .Values.sidecar.dashboards.watchServerTimeout }}"
{{- end }}
{{- if .Values.sidecar.dashboards.watchClientTimeout }}
- name: WATCH_CLIENT_TIMEOUT
value: "{{ .Values.sidecar.dashboards.watchClientTimeout }}"
{{- end }}
{{- if .Values.sidecar.livenessProbe }}
livenessProbe:
{{ toYaml .Values.livenessProbe | indent 6 }}
{{- end }}
{{- if .Values.sidecar.readinessProbe }}
readinessProbe:
{{ toYaml .Values.readinessProbe | indent 6 }}
{{- end }}
resources:
{{ toYaml .Values.sidecar.resources | indent 6 }}
{{- if .Values.sidecar.securityContext }}
securityContext:
{{- toYaml .Values.sidecar.securityContext | nindent 6 }}
{{- end }}
volumeMounts:
- name: sc-dashboard-volume
mountPath: {{ .Values.sidecar.dashboards.folder | quote }}
{{- if .Values.sidecar.dashboards.extraMounts }}
{{- toYaml .Values.sidecar.dashboards.extraMounts | trim | nindent 6}}
{{- end }}
{{- end}}
{{- if .Values.sidecar.datasources.enabled }}
- name: {{ template "grafana.name" . }}-sc-datasources
{{- if .Values.sidecar.image.sha }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}"
{{- else }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}"
{{- end }}
imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }}
env:
- name: METHOD
value: {{ .Values.sidecar.datasources.watchMethod }}
- name: LABEL
value: "{{ .Values.sidecar.datasources.label }}"
{{- if .Values.sidecar.datasources.labelValue }}
- name: LABEL_VALUE
value: {{ quote .Values.sidecar.datasources.labelValue }}
{{- end }}
- name: FOLDER
value: "/etc/grafana/provisioning/datasources"
- name: RESOURCE
value: {{ quote .Values.sidecar.datasources.resource }}
{{- if .Values.sidecar.enableUniqueFilenames }}
- name: UNIQUE_FILENAMES
value: "{{ .Values.sidecar.enableUniqueFilenames }}"
{{- end }}
{{- if .Values.sidecar.datasources.searchNamespace }}
- name: NAMESPACE
value: "{{ .Values.sidecar.datasources.searchNamespace | join "," }}"
{{- end }}
{{- if .Values.sidecar.skipTlsVerify }}
- name: SKIP_TLS_VERIFY
value: "{{ .Values.sidecar.skipTlsVerify }}"
{{- end }}
{{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }}
- name: REQ_USERNAME
valueFrom:
secretKeyRef:
name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }}
key: {{ .Values.admin.userKey | default "admin-user" }}
{{- end }}
{{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }}
- name: REQ_PASSWORD
valueFrom:
secretKeyRef:
name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }}
key: {{ .Values.admin.passwordKey | default "admin-password" }}
{{- end }}
{{- if not .Values.sidecar.datasources.skipReload }}
- name: REQ_URL
value: {{ .Values.sidecar.datasources.reloadURL }}
- name: REQ_METHOD
value: POST
{{- end }}
{{- if .Values.sidecar.livenessProbe }}
livenessProbe:
{{ toYaml .Values.livenessProbe | indent 6 }}
{{- end }}
{{- if .Values.sidecar.readinessProbe }}
readinessProbe:
{{ toYaml .Values.readinessProbe | indent 6 }}
{{- end }}
resources:
{{ toYaml .Values.sidecar.resources | indent 6 }}
{{- if .Values.sidecar.securityContext }}
securityContext:
{{- toYaml .Values.sidecar.securityContext | nindent 6 }}
{{- end }}
volumeMounts:
- name: sc-datasources-volume
mountPath: "/etc/grafana/provisioning/datasources"
{{- end}}
{{- if .Values.sidecar.plugins.enabled }}
- name: {{ template "grafana.name" . }}-sc-plugins
{{- if .Values.sidecar.image.sha }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}"
{{- else }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}"
{{- end }}
imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }}
env:
- name: METHOD
value: {{ .Values.sidecar.plugins.watchMethod }}
- name: LABEL
value: "{{ .Values.sidecar.plugins.label }}"
{{- if .Values.sidecar.plugins.labelValue }}
- name: LABEL_VALUE
value: {{ quote .Values.sidecar.plugins.labelValue }}
{{- end }}
- name: FOLDER
value: "/etc/grafana/provisioning/plugins"
- name: RESOURCE
value: {{ quote .Values.sidecar.plugins.resource }}
{{- if .Values.sidecar.enableUniqueFilenames }}
- name: UNIQUE_FILENAMES
value: "{{ .Values.sidecar.enableUniqueFilenames }}"
{{- end }}
{{- if .Values.sidecar.plugins.searchNamespace }}
- name: NAMESPACE
value: "{{ .Values.sidecar.plugins.searchNamespace | join "," }}"
{{- end }}
{{- if .Values.sidecar.skipTlsVerify }}
- name: SKIP_TLS_VERIFY
value: "{{ .Values.sidecar.skipTlsVerify }}"
{{- end }}
{{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }}
- name: REQ_USERNAME
valueFrom:
secretKeyRef:
name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }}
key: {{ .Values.admin.userKey | default "admin-user" }}
{{- end }}
{{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }}
- name: REQ_PASSWORD
valueFrom:
secretKeyRef:
name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }}
key: {{ .Values.admin.passwordKey | default "admin-password" }}
{{- end }}
{{- if not .Values.sidecar.plugins.skipReload }}
- name: REQ_URL
value: {{ .Values.sidecar.plugins.reloadURL }}
- name: REQ_METHOD
value: POST
{{- end }}
{{- if .Values.sidecar.livenessProbe }}
livenessProbe:
{{ toYaml .Values.livenessProbe | indent 6 }}
{{- end }}
{{- if .Values.sidecar.readinessProbe }}
readinessProbe:
{{ toYaml .Values.readinessProbe | indent 6 }}
{{- end }}
resources:
{{ toYaml .Values.sidecar.resources | indent 6 }}
{{- if .Values.sidecar.securityContext }}
securityContext:
{{- toYaml .Values.sidecar.securityContext | nindent 6 }}
{{- end }}
volumeMounts:
- name: sc-plugins-volume
mountPath: "/etc/grafana/provisioning/plugins"
{{- end}}
- name: {{ .Chart.Name }}
{{- if .Values.image.sha }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.image.sha }}"
{{- else }}
image: "{{ include "get.grafanaServerimage" . }}"
{{- end }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if .Values.command }}
command:
{{- range .Values.command }}
- {{ . }}
{{- end }}
{{- end}}
{{- if .Values.containerSecurityContext }}
securityContext:
{{- toYaml .Values.containerSecurityContext | nindent 6 }}
{{- end }}
volumeMounts:
- name: config
mountPath: "/etc/grafana/grafana.ini"
subPath: grafana.ini
{{- if .Values.ldap.enabled }}
- name: ldap
mountPath: "/etc/grafana/ldap.toml"
subPath: ldap.toml
{{- end }}
{{- $root := . }}
{{- range .Values.extraConfigmapMounts }}
- name: {{ tpl .name $root }}
mountPath: {{ tpl .mountPath $root }}
subPath: {{ (tpl .subPath $root) | default "" }}
readOnly: {{ .readOnly }}
{{- end }}
- name: storage
mountPath: "/var/lib/grafana"
{{- if .Values.persistence.subPath }}
subPath: {{ tpl .Values.persistence.subPath . }}
{{- end }}
{{- if .Values.dashboards }}
{{- range $provider, $dashboards := .Values.dashboards }}
{{- range $key, $value := $dashboards }}
{{- if (or (hasKey $value "json") (hasKey $value "file")) }}
- name: dashboards-{{ $provider }}
mountPath: "/var/lib/grafana/dashboards/{{ $provider }}/{{ $key }}.json"
subPath: "{{ $key }}.json"
{{- end }}
{{- end }}
{{- end }}
{{- end -}}
{{- if .Values.dashboardsConfigMaps }}
{{- range (keys .Values.dashboardsConfigMaps | sortAlpha) }}
- name: dashboards-{{ . }}
mountPath: "/var/lib/grafana/dashboards/{{ . }}"
{{- end }}
{{- end }}
{{/* Mounting default datasources in pod as yaml */}}
- name: config
mountPath: "/etc/grafana/provisioning/datasources/datasources.yaml"
subPath: "datasources.yaml"
{{- if .Values.notifiers }}
{{- range (keys .Values.notifiers | sortAlpha) }}
- name: config
mountPath: "/etc/grafana/provisioning/notifiers/{{ . }}"
subPath: {{ . | quote }}
{{- end }}
{{- end }}
{{- if .Values.dashboardProviders }}
{{- range (keys .Values.dashboardProviders | sortAlpha) }}
- name: config
mountPath: "/etc/grafana/provisioning/dashboards/{{ . }}"
subPath: {{ . | quote }}
{{- end }}
{{- end }}
{{- if .Values.sidecar.dashboards.enabled }}
- name: sc-dashboard-volume
mountPath: {{ .Values.sidecar.dashboards.folder | quote }}
{{ if .Values.sidecar.dashboards.SCProvider }}
- name: sc-dashboard-provider
mountPath: "/etc/grafana/provisioning/dashboards/sc-dashboardproviders.yaml"
subPath: provider.yaml
{{- end}}
{{- end}}
{{- if .Values.sidecar.datasources.enabled }}
- name: sc-datasources-volume
mountPath: "/etc/grafana/provisioning/datasources"
{{- end}}
{{- if .Values.sidecar.plugins.enabled }}
- name: sc-plugins-volume
mountPath: "/etc/grafana/provisioning/plugins"
{{- end}}
{{- if .Values.sidecar.notifiers.enabled }}
- name: sc-notifiers-volume
mountPath: "/etc/grafana/provisioning/notifiers"
{{- end}}
{{- range .Values.extraSecretMounts }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
readOnly: {{ .readOnly }}
subPath: {{ .subPath | default "" }}
{{- end }}
{{- range .Values.extraVolumeMounts }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
subPath: {{ .subPath | default "" }}
readOnly: {{ .readOnly }}
{{- end }}
{{- range .Values.extraEmptyDirMounts }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
{{- end }}
ports:
- name: {{ .Values.service.portName }}
containerPort: {{ .Values.service.port }}
protocol: TCP
- name: {{ .Values.podPortName }}
containerPort: 3000
protocol: TCP
env:
{{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }}
- name: GF_SECURITY_ADMIN_USER
valueFrom:
secretKeyRef:
name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }}
key: {{ .Values.admin.userKey | default "admin-user" }}
{{- end }}
{{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }}
- name: GF_SECURITY_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }}
key: {{ .Values.admin.passwordKey | default "admin-password" }}
{{- end }}
{{- if .Values.plugins }}
- name: GF_INSTALL_PLUGINS
valueFrom:
configMapKeyRef:
name: {{ template "grafana.fullname" . }}
key: plugins
{{- end }}
{{- if .Values.smtp.existingSecret }}
- name: GF_SMTP_USER
valueFrom:
secretKeyRef:
name: {{ .Values.smtp.existingSecret }}
key: {{ .Values.smtp.userKey | default "user" }}
- name: GF_SMTP_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.smtp.existingSecret }}
key: {{ .Values.smtp.passwordKey | default "password" }}
{{- end }}
{{- if .Values.imageRenderer.enabled }}
- name: GF_RENDERING_SERVER_URL
value: http://{{ template "grafana.fullname" . }}-image-renderer.{{ template "grafana.namespace" . }}:{{ .Values.imageRenderer.service.port }}/render
- name: GF_RENDERING_CALLBACK_URL
value: {{ .Values.imageRenderer.grafanaProtocol }}://{{ template "grafana.fullname" . }}.{{ template "grafana.namespace" . }}:{{ .Values.service.port }}/{{ .Values.imageRenderer.grafanaSubPath }}
{{- end }}
- name: GF_PATHS_DATA
value: {{ (get .Values "grafana.ini").paths.data }}
- name: GF_PATHS_LOGS
value: {{ (get .Values "grafana.ini").paths.logs }}
- name: GF_PATHS_PLUGINS
value: {{ (get .Values "grafana.ini").paths.plugins }}
- name: GF_PATHS_PROVISIONING
value: {{ (get .Values "grafana.ini").paths.provisioning }}
{{- range $key, $value := .Values.envValueFrom }}
- name: {{ $key | quote }}
valueFrom:
{{ tpl (toYaml $value) $ | indent 10 }}
{{- end }}
{{- range $key, $value := .Values.env }}
- name: "{{ tpl $key $ }}"
value: "{{ tpl (print $value) $ }}"
{{- end }}
{{- if or .Values.envFromSecret (or .Values.envRenderSecret .Values.envFromSecrets) .Values.envFromConfigMaps }}
envFrom:
{{- if .Values.envFromSecret }}
- secretRef:
name: {{ tpl .Values.envFromSecret . }}
{{- end }}
{{- if .Values.envRenderSecret }}
- secretRef:
name: {{ template "grafana.fullname" . }}-env
{{- end }}
{{- range .Values.envFromSecrets }}
- secretRef:
name: {{ tpl .name $ }}
optional: {{ .optional | default false }}
{{- end }}
{{- range .Values.envFromConfigMaps }}
- configMapRef:
name: {{ tpl .name $ }}
optional: {{ .optional | default false }}
{{- end }}
{{- end }}
livenessProbe:
{{ toYaml .Values.livenessProbe | indent 6 }}
readinessProbe:
{{ toYaml .Values.readinessProbe | indent 6 }}
{{- if .Values.lifecycleHooks }}
lifecycle: {{ tpl (.Values.lifecycleHooks | toYaml) . | nindent 6 }}
{{- end }}
resources:
{{ toYaml .Values.resources | indent 6 }}
{{- with .Values.extraContainers }}
{{ tpl . $ | indent 2 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 2 }}
{{- end }}
{{- $root := . }}
{{- with .Values.affinity }}
affinity:
{{ tpl (toYaml .) $root | indent 2 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 2 }}
{{- end }}
volumes:
- name: config
configMap:
name: {{ template "grafana.fullname" . }}
{{- $root := . }}
{{- range .Values.extraConfigmapMounts }}
- name: {{ tpl .name $root }}
configMap:
name: {{ tpl .configMap $root }}
{{- if .items }}
items: {{ toYaml .items | nindent 6 }}
{{- end }}
{{- end }}
{{- if .Values.dashboards }}
{{- range (keys .Values.dashboards | sortAlpha) }}
- name: dashboards-{{ . }}
configMap:
name: {{ template "grafana.fullname" $ }}-dashboards-{{ . }}
{{- end }}
{{- end }}
{{- if .Values.dashboardsConfigMaps }}
{{ $root := . }}
{{- range $provider, $name := .Values.dashboardsConfigMaps }}
- name: dashboards-{{ $provider }}
configMap:
name: {{ tpl $name $root }}
{{- end }}
{{- end }}
{{- if .Values.ldap.enabled }}
- name: ldap
secret:
{{- if .Values.ldap.existingSecret }}
secretName: {{ .Values.ldap.existingSecret }}
{{- else }}
secretName: {{ template "grafana.fullname" . }}
{{- end }}
items:
- key: ldap-toml
path: ldap.toml
{{- end }}
{{- if and .Values.global.persistence.enabled (eq .Values.persistence.type "pvc") }}
- name: storage
persistentVolumeClaim:
claimName: {{ tpl (.Values.persistence.existingClaim | default (include "grafana.fullname" .)) . }}
{{- else if and .Values.global.persistence.enabled (eq .Values.persistence.type "statefulset") }}
# nothing
{{- else }}
- name: storage
{{- if .Values.persistence.inMemory.enabled }}
emptyDir:
medium: Memory
{{- if .Values.persistence.inMemory.sizeLimit }}
sizeLimit: {{ .Values.persistence.inMemory.sizeLimit }}
{{- end -}}
{{- else }}
emptyDir: {}
{{- end -}}
{{- end -}}
{{- if .Values.sidecar.dashboards.enabled }}
- name: sc-dashboard-volume
{{- if .Values.sidecar.dashboards.sizeLimit }}
emptyDir:
sizeLimit: {{ .Values.sidecar.dashboards.sizeLimit }}
{{- else }}
emptyDir: {}
{{- end -}}
{{- if .Values.sidecar.dashboards.SCProvider }}
- name: sc-dashboard-provider
configMap:
name: {{ template "grafana.fullname" . }}-config-dashboards
{{- end }}
{{- end }}
{{- if .Values.sidecar.datasources.enabled }}
- name: sc-datasources-volume
{{- if .Values.sidecar.datasources.sizeLimit }}
emptyDir:
sizeLimit: {{ .Values.sidecar.datasources.sizeLimit }}
{{- else }}
emptyDir: {}
{{- end -}}
{{- end -}}
{{- if .Values.sidecar.plugins.enabled }}
- name: sc-plugins-volume
{{- if .Values.sidecar.plugins.sizeLimit }}
emptyDir:
sizeLimit: {{ .Values.sidecar.plugins.sizeLimit }}
{{- else }}
emptyDir: {}
{{- end -}}
{{- end -}}
{{- if .Values.sidecar.notifiers.enabled }}
- name: sc-notifiers-volume
{{- if .Values.sidecar.notifiers.sizeLimit }}
emptyDir:
sizeLimit: {{ .Values.sidecar.notifiers.sizeLimit }}
{{- else }}
emptyDir: {}
{{- end -}}
{{- end -}}
{{- range .Values.extraSecretMounts }}
{{- if .secretName }}
- name: {{ .name }}
secret:
secretName: {{ .secretName }}
defaultMode: {{ .defaultMode }}
{{- if .items }}
items: {{ toYaml .items | nindent 6 }}
{{- end }}
{{- else if .projected }}
- name: {{ .name }}
projected: {{- toYaml .projected | nindent 6 }}
{{- else if .csi }}
- name: {{ .name }}
csi: {{- toYaml .csi | nindent 6 }}
{{- end }}
{{- end }}
{{- range .Values.extraVolumeMounts }}
- name: {{ .name }}
{{- if .existingClaim }}
persistentVolumeClaim:
claimName: {{ .existingClaim }}
{{- else if .hostPath }}
hostPath:
path: {{ .hostPath }}
{{- else }}
emptyDir: {}
{{- end }}
{{- end }}
{{- range .Values.extraEmptyDirMounts }}
- name: {{ .name }}
emptyDir: {}
{{- end -}}
{{- if .Values.extraContainerVolumes }}
{{ toYaml .Values.extraContainerVolumes | indent 2 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,27 @@
{{- if .Values.enabled }}
{{- if and .Values.rbac.create (not .Values.rbac.namespaced) (not .Values.rbac.useExistingRole) }}
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
name: {{ template "grafana.fullname" . }}-clusterrole
{{- if or .Values.sidecar.dashboards.enabled (or .Values.rbac.extraClusterRoleRules (or .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled)) }}
rules:
{{- if or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled) }}
- apiGroups: [""] # "" indicates the core API group
resources: ["configmaps", "secrets"]
verbs: ["get", "watch", "list"]
{{- end}}
{{- with .Values.rbac.extraClusterRoleRules }}
{{ toYaml . | indent 0 }}
{{- end}}
{{- else }}
rules: []
{{- end}}
{{- end}}
{{- end}}

View File

@ -0,0 +1,26 @@
{{- if .Values.enabled }}
{{- if and .Values.rbac.create (not .Values.rbac.namespaced) }}
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "grafana.fullname" . }}-clusterrolebinding
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
subjects:
- kind: ServiceAccount
name: {{ template "grafana.serviceAccountName" . }}
namespace: {{ template "grafana.namespace" . }}
roleRef:
kind: ClusterRole
{{- if (not .Values.rbac.useExistingRole) }}
name: {{ template "grafana.fullname" . }}-clusterrole
{{- else }}
name: {{ .Values.rbac.useExistingRole }}
{{- end }}
apiGroup: rbac.authorization.k8s.io
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,31 @@
{{- if .Values.enabled }}
{{- if .Values.sidecar.dashboards.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
name: {{ template "grafana.fullname" . }}-config-dashboards
namespace: {{ template "grafana.namespace" . }}
data:
provider.yaml: |-
apiVersion: 1
providers:
- name: '{{ .Values.sidecar.dashboards.provider.name }}'
orgId: {{ .Values.sidecar.dashboards.provider.orgid }}
{{- if not .Values.sidecar.dashboards.provider.foldersFromFilesStructure }}
folder: '{{ .Values.sidecar.dashboards.provider.folder }}'
{{- end}}
type: {{ .Values.sidecar.dashboards.provider.type }}
disableDeletion: {{ .Values.sidecar.dashboards.provider.disableDelete }}
allowUiUpdates: {{ .Values.sidecar.dashboards.provider.allowUiUpdates }}
updateIntervalSeconds: {{ .Values.sidecar.dashboards.provider.updateIntervalSeconds | default 30 }}
options:
foldersFromFilesStructure: {{ .Values.sidecar.dashboards.provider.foldersFromFilesStructure }}
path: {{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }}
{{- end}}
{{- end}}

View File

@ -0,0 +1,121 @@
{{- if .Values.createConfigmap }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "grafana.fullname" . }}
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
data:
# Adding default prometheus datasource for grafana
datasources.yaml: |
apiVersion: 1
datasources:
- access: proxy
editable: false
isDefault: true
name: Prometheus
type: prometheus
{{- if and .Values.global.prometheus.external.host .Values.global.prometheus.external.port }}
url: {{ printf "http://%s:%s/%s" .Values.global.prometheus.external.host .Values.global.prometheus.external.port .Values.global.prometheus.external.baseURL | trimSuffix "/" }}
{{- else }}
url: http://{{ .Values.prometheusName | trimSuffix "/" }}-exp/{{ .Values.prometheusPrefixURL | trimPrefix "/" }}
{{- end }}
jsonData:
timeInterval: '1m'
{{- if .Values.plugins }}
plugins: {{ join "," .Values.plugins }}
{{- end }}
grafana.ini: |
{{- range $elem, $elemVal := index .Values "grafana.ini" }}
{{- if not (kindIs "map" $elemVal) }}
{{- if kindIs "invalid" $elemVal }}
{{ $elem }} =
{{- else if kindIs "string" $elemVal }}
{{ $elem }} = {{ tpl $elemVal $ }}
{{- else }}
{{ $elem }} = {{ $elemVal }}
{{- end }}
{{- end }}
{{- end }}
{{- range $key, $value := index .Values "grafana.ini" }}
{{- if kindIs "map" $value }}
[{{ $key }}]
{{- range $elem, $elemVal := $value }}
{{- if kindIs "invalid" $elemVal }}
{{ $elem }} =
{{- else if kindIs "string" $elemVal }}
{{ $elem }} = {{ tpl $elemVal $ }}
{{- else }}
{{ $elem }} = {{ $elemVal }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
[server]
root_url=/{{ include "k10.ingressPath" . | trimSuffix "/"}}/grafana
serve_from_sub_path=true
{{- if .Values.datasources }}
{{ $root := . }}
{{- range $key, $value := .Values.datasources }}
{{ $key }}: |
{{ tpl (toYaml $value | indent 4) $root }}
{{- end -}}
{{- end -}}
{{- if .Values.notifiers }}
{{- range $key, $value := .Values.notifiers }}
{{ $key }}: |
{{ toYaml $value | indent 4 }}
{{- end -}}
{{- end -}}
{{- if .Values.dashboardProviders }}
{{- range $key, $value := .Values.dashboardProviders }}
{{ $key }}: |
{{ toYaml $value | indent 4 }}
{{- end -}}
{{- end -}}
{{- if .Values.dashboards }}
download_dashboards.sh: |
#!/usr/bin/env sh
set -euf
{{- if .Values.dashboardProviders }}
{{- range $key, $value := .Values.dashboardProviders }}
{{- range $value.providers }}
mkdir -p {{ .options.path }}
{{- end }}
{{- end }}
{{- end }}
{{ $dashboardProviders := .Values.dashboardProviders }}
{{- range $provider, $dashboards := .Values.dashboards }}
{{- range $key, $value := $dashboards }}
{{- if (or (hasKey $value "gnetId") (hasKey $value "url")) }}
curl -skf \
--connect-timeout 60 \
--max-time 60 \
{{- if not $value.b64content }}
-H "Accept: application/json" \
{{- if $value.token }}
-H "Authorization: token {{ $value.token }}" \
{{- end }}
-H "Content-Type: application/json;charset=UTF-8" \
{{ end }}
{{- $dpPath := "" -}}
{{- range $kd := (index $dashboardProviders "dashboardproviders.yaml").providers -}}
{{- if eq $kd.name $provider -}}
{{- $dpPath = $kd.options.path -}}
{{- end -}}
{{- end -}}
{{- if $value.url -}}"{{ $value.url }}"{{- else -}}"https://grafana.com/api/dashboards/{{ $value.gnetId }}/revisions/{{- if $value.revision -}}{{ $value.revision }}{{- else -}}1{{- end -}}/download"{{- end -}}{{ if $value.datasource }} | sed '/-- .* --/! s/"datasource":.*,/"datasource": "{{ $value.datasource }}",/g'{{ end }}{{- if $value.b64content -}} | base64 -d {{- end -}} \
> "{{- if $dpPath -}}{{ $dpPath }}{{- else -}}/var/lib/grafana/dashboards/{{ $provider }}{{- end -}}/{{ $key }}.json"
{{- end }}
{{- end -}}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,37 @@
{{- if .Values.enabled }}
{{- if .Values.dashboards }}
{{ $files := .Files }}
{{- range $provider, $dashboards := .Values.dashboards }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "grafana.fullname" $ }}-dashboards-{{ $provider }}
namespace: {{ template "grafana.namespace" $ }}
labels:
{{- include "grafana.labels" $ | nindent 4 }}
dashboard-provider: {{ $provider }}
{{- if $dashboards }}
data:
{{- $dashboardFound := false }}
{{- range $key, $value := $dashboards }}
{{- if (or (hasKey $value "json") (hasKey $value "file")) }}
{{- $dashboardFound = true }}
{{ print $key | indent 2 }}.json:
{{- if hasKey $value "json" }}
|-
{{ $value.json | indent 6 }}
{{- end }}
{{- if hasKey $value "file" }}
{{ toYaml ( $files.Get $value.file ) | indent 4}}
{{- end }}
{{- end }}
{{- end }}
{{- if not $dashboardFound }}
{}
{{- end }}
{{- end }}
---
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,52 @@
{{- if .Values.enabled }}
{{ if (and (not .Values.useStatefulSet) (or (not .Values.global.persistence.enabled) (eq .Values.persistence.type "pvc"))) }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "grafana.fullname" . }}
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- if .Values.labels }}
{{ toYaml .Values.labels | indent 4 }}
{{- end }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
{{- if and (not .Values.autoscaling.enabled) (.Values.replicas) }}
replicas: {{ .Values.replicas }}
{{- end }}
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
selector:
matchLabels:
{{- include "grafana.selectorLabels" . | nindent 6 }}
{{- with .Values.deploymentStrategy }}
strategy:
{{ toYaml . | trim | indent 4 }}
{{- end }}
template:
metadata:
labels:
{{- include "grafana.selectorLabels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{ toYaml . | indent 8 }}
{{- end }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/dashboards-json-config: {{ include (print $.Template.BasePath "/dashboards-json-configmap.yaml") . | sha256sum }}
checksum/sc-dashboard-provider-config: {{ include (print $.Template.BasePath "/configmap-dashboard-provider.yaml") . | sha256sum }}
{{- if and (or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret))) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- end }}
{{- if .Values.envRenderSecret }}
checksum/secret-env: {{ include (print $.Template.BasePath "/secret-env.yaml") . | sha256sum }}
{{- end }}
{{- with .Values.podAnnotations }}
{{ toYaml . | indent 8 }}
{{- end }}
spec:
{{- include "grafana.pod" . | nindent 6 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,4 @@
{{ range .Values.extraObjects }}
---
{{ tpl (toYaml .) $ }}
{{ end }}

View File

@ -0,0 +1,24 @@
{{- if .Values.enabled }}
{{- if or .Values.headlessService (and .Values.global.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "statefulset"))}}
apiVersion: v1
kind: Service
metadata:
name: {{ template "grafana.fullname" . }}-headless
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
clusterIP: None
selector:
{{- include "grafana.selectorLabels" . | nindent 4 }}
type: ClusterIP
ports:
- protocol: TCP
port: 3000
targetPort: 3000
{{- end }}
{{- end }}

View File

@ -0,0 +1,22 @@
{{- if .Values.enabled }}
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: {{ template "grafana.fullname" . }}
labels:
app.kubernetes.io/name: {{ template "grafana.name" . }}
helm.sh/chart: {{ template "grafana.chart" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ template "grafana.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{ toYaml .Values.autoscaling.metrics | indent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,123 @@
{{- if .Values.enabled }}
{{ if .Values.imageRenderer.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "grafana.fullname" . }}-image-renderer
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.imageRenderer.labels" . | nindent 4 }}
{{- if .Values.imageRenderer.labels }}
{{ toYaml .Values.imageRenderer.labels | indent 4 }}
{{- end }}
{{- with .Values.imageRenderer.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
replicas: {{ .Values.imageRenderer.replicas }}
revisionHistoryLimit: {{ .Values.imageRenderer.revisionHistoryLimit }}
selector:
matchLabels:
{{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }}
{{- with .Values.imageRenderer.deploymentStrategy }}
strategy:
{{ toYaml . | trim | indent 4 }}
{{- end }}
template:
metadata:
labels:
{{- include "grafana.imageRenderer.selectorLabels" . | nindent 8 }}
{{- with .Values.imageRenderer.podLabels }}
{{ toYaml . | indent 8 }}
{{- end }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
{{- with .Values.imageRenderer.podAnnotations }}
{{ toYaml . | indent 8 }}
{{- end }}
spec:
{{- if .Values.imageRenderer.schedulerName }}
schedulerName: "{{ .Values.imageRenderer.schedulerName }}"
{{- end }}
{{- if .Values.imageRenderer.serviceAccountName }}
serviceAccountName: "{{ .Values.imageRenderer.serviceAccountName }}"
{{- end }}
{{- if .Values.imageRenderer.securityContext }}
securityContext:
{{- toYaml .Values.imageRenderer.securityContext | nindent 8 }}
{{- end }}
{{- if .Values.imageRenderer.hostAliases }}
hostAliases:
{{- toYaml .Values.imageRenderer.hostAliases | nindent 8 }}
{{- end }}
{{- if .Values.imageRenderer.priorityClassName }}
priorityClassName: {{ .Values.imageRenderer.priorityClassName }}
{{- end }}
{{- if .Values.imageRenderer.image.pullSecrets }}
imagePullSecrets:
{{- $root := . }}
{{- range .Values.imageRenderer.image.pullSecrets }}
- name: {{ tpl . $root }}
{{- end}}
{{- end }}
containers:
- name: {{ .Chart.Name }}-image-renderer
{{- if .Values.imageRenderer.image.sha }}
image: "{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}@sha256:{{ .Values.imageRenderer.image.sha }}"
{{- else }}
image: "{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}"
{{- end }}
imagePullPolicy: {{ .Values.imageRenderer.image.pullPolicy }}
{{- if .Values.imageRenderer.command }}
command:
{{- range .Values.imageRenderer.command }}
- {{ . }}
{{- end }}
{{- end}}
ports:
- name: {{ .Values.imageRenderer.service.portName }}
containerPort: {{ .Values.imageRenderer.service.port }}
protocol: TCP
livenessProbe:
httpGet:
path: /
port: {{ .Values.imageRenderer.service.portName }}
env:
- name: HTTP_PORT
value: {{ .Values.imageRenderer.service.port | quote }}
{{- range $key, $value := .Values.imageRenderer.env }}
- name: {{ $key | quote }}
value: {{ $value | quote }}
{{- end }}
securityContext:
capabilities:
drop: ['all']
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /tmp
name: image-renderer-tmpfs
{{- with .Values.imageRenderer.resources }}
resources:
{{ toYaml . | indent 12 }}
{{- end }}
{{- with .Values.imageRenderer.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- $root := . }}
{{- with .Values.imageRenderer.affinity }}
affinity:
{{ tpl (toYaml .) $root | indent 8 }}
{{- end }}
{{- with .Values.imageRenderer.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
volumes:
- name: image-renderer-tmpfs
emptyDir: {}
{{- end }}
{{- end }}

View File

@ -0,0 +1,78 @@
{{- if .Values.enabled }}
{{- if and (.Values.imageRenderer.enabled) (.Values.imageRenderer.networkPolicy.limitIngress) }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ template "grafana.fullname" . }}-image-renderer-ingress
namespace: {{ template "grafana.namespace" . }}
annotations:
comment: Limit image-renderer ingress traffic from grafana
spec:
podSelector:
matchLabels:
{{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }}
{{- if .Values.imageRenderer.podLabels }}
{{ toYaml .Values.imageRenderer.podLabels | nindent 6 }}
{{- end }}
policyTypes:
- Ingress
ingress:
- ports:
- port: {{ .Values.imageRenderer.service.port }}
protocol: TCP
from:
- namespaceSelector:
matchLabels:
name: {{ template "grafana.namespace" . }}
podSelector:
matchLabels:
{{- include "grafana.selectorLabels" . | nindent 14 }}
{{- if .Values.podLabels }}
{{ toYaml .Values.podLabels | nindent 14 }}
{{- end }}
{{ end }}
{{- if and (.Values.imageRenderer.enabled) (.Values.imageRenderer.networkPolicy.limitEgress) }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ template "grafana.fullname" . }}-image-renderer-egress
namespace: {{ template "grafana.namespace" . }}
annotations:
comment: Limit image-renderer egress traffic to grafana
spec:
podSelector:
matchLabels:
{{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }}
{{- if .Values.imageRenderer.podLabels }}
{{ toYaml .Values.imageRenderer.podLabels | nindent 6 }}
{{- end }}
policyTypes:
- Egress
egress:
# allow dns resolution
- ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
# talk only to grafana
- ports:
- port: {{ .Values.service.port }}
protocol: TCP
to:
- namespaceSelector:
matchLabels:
name: {{ template "grafana.namespace" . }}
podSelector:
matchLabels:
{{- include "grafana.selectorLabels" . | nindent 14 }}
{{- if .Values.podLabels }}
{{ toYaml .Values.podLabels | nindent 14 }}
{{- end }}
{{ end }}
{{- end}}

View File

@ -0,0 +1,32 @@
{{- if .Values.enabled }}
{{ if .Values.imageRenderer.enabled }}
{{ if .Values.imageRenderer.service.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "grafana.fullname" . }}-image-renderer
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.imageRenderer.labels" . | nindent 4 }}
{{- if .Values.imageRenderer.service.labels }}
{{ toYaml .Values.imageRenderer.service.labels | indent 4 }}
{{- end }}
{{- with .Values.imageRenderer.service.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
type: ClusterIP
{{- if .Values.imageRenderer.service.clusterIP }}
clusterIP: {{ .Values.imageRenderer.service.clusterIP }}
{{end}}
ports:
- name: {{ .Values.imageRenderer.service.portName }}
port: {{ .Values.imageRenderer.service.port }}
protocol: TCP
targetPort: {{ .Values.imageRenderer.service.targetPort }}
selector:
{{- include "grafana.imageRenderer.selectorLabels" . | nindent 4 }}
{{ end }}
{{ end }}
{{- end}}

View File

@ -0,0 +1,80 @@
{{- if .Values.enabled }}
{{- if .Values.ingress.enabled -}}
{{- $ingressApiIsStable := eq (include "grafana.ingress.isStable" .) "true" -}}
{{- $ingressSupportsIngressClassName := eq (include "grafana.ingress.supportsIngressClassName" .) "true" -}}
{{- $ingressSupportsPathType := eq (include "grafana.ingress.supportsPathType" .) "true" -}}
{{- $fullName := include "grafana.fullname" . -}}
{{- $servicePort := .Values.service.port -}}
{{- $ingressPath := .Values.ingress.path -}}
{{- $ingressPathType := .Values.ingress.pathType -}}
{{- $extraPaths := .Values.ingress.extraPaths -}}
apiVersion: {{ include "grafana.ingress.apiVersion" . }}
kind: Ingress
metadata:
name: {{ $fullName }}
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- if .Values.ingress.labels }}
{{ toYaml .Values.ingress.labels | indent 4 }}
{{- end }}
{{- if .Values.ingress.annotations }}
annotations:
{{- range $key, $value := .Values.ingress.annotations }}
{{ $key }}: {{ tpl $value $ | quote }}
{{- end }}
{{- end }}
spec:
{{- if and $ingressSupportsIngressClassName .Values.ingress.ingressClassName }}
ingressClassName: {{ .Values.ingress.ingressClassName }}
{{- end -}}
{{- if .Values.ingress.tls }}
tls:
{{ tpl (toYaml .Values.ingress.tls) $ | indent 4 }}
{{- end }}
rules:
{{- if .Values.ingress.hosts }}
{{- range .Values.ingress.hosts }}
- host: {{ tpl . $}}
http:
paths:
{{- if $extraPaths }}
{{ toYaml $extraPaths | indent 10 }}
{{- end }}
- path: {{ $ingressPath }}
{{- if $ingressSupportsPathType }}
pathType: {{ $ingressPathType }}
{{- end }}
backend:
{{- if $ingressApiIsStable }}
service:
name: {{ $fullName }}
port:
number: {{ $servicePort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $servicePort }}
{{- end }}
{{- end }}
{{- else }}
- http:
paths:
- backend:
{{- if $ingressApiIsStable }}
service:
name: {{ $fullName }}
port:
number: {{ $servicePort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $servicePort }}
{{- end }}
{{- if $ingressPath }}
path: {{ $ingressPath }}
{{- end }}
{{- if $ingressSupportsPathType }}
pathType: {{ $ingressPathType }}
{{- end }}
{{- end -}}
{{- end }}
{{- end }}

View File

@ -0,0 +1,17 @@
{{- if .Values.enabled }}
{{ if .Values.service.enabled}}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ template "grafana.name" . }}-network-policy
namespace: {{ template "grafana.namespace" . }}
spec:
podSelector:
matchLabels:
{{- include "grafana.selectorLabels" . | nindent 6 }}
ingress:
- { }
egress:
- { }
{{- end }}
{{- end }}

View File

@ -0,0 +1,24 @@
{{- if .Values.enabled }}
{{- if .Values.podDisruptionBudget }}
apiVersion: {{ include "grafana.podDisruptionBudget.apiVersion" . }}
kind: PodDisruptionBudget
metadata:
name: {{ template "grafana.fullname" . }}
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- if .Values.labels }}
{{ toYaml .Values.labels | indent 4 }}
{{- end }}
spec:
{{- if .Values.podDisruptionBudget.minAvailable }}
minAvailable: {{ .Values.podDisruptionBudget.minAvailable }}
{{- end }}
{{- if .Values.podDisruptionBudget.maxUnavailable }}
maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }}
{{- end }}
selector:
matchLabels:
{{- include "grafana.selectorLabels" . | nindent 6 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,49 @@
{{- if .Values.rbac.pspEnabled }}
apiVersion: {{ include "grafana.podSecurityPolicy.apiVersion" . }}
kind: PodSecurityPolicy
metadata:
name: {{ template "grafana.fullname" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default'
seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'
{{- if .Values.rbac.pspUseAppArmor }}
apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
{{- end }}
spec:
privileged: false
allowPrivilegeEscalation: false
requiredDropCapabilities:
# Default set from Docker, with DAC_OVERRIDE and CHOWN
- ALL
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'csi'
- 'secret'
- 'downwardAPI'
- 'persistentVolumeClaim'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
fsGroup:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
readOnlyRootFilesystem: false
{{- end }}

View File

@ -0,0 +1,33 @@
{{- if .Values.enabled }}
{{- if and .Values.global.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "pvc")}}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ template "grafana.fullname" . }}
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- with .Values.persistence.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
{{- with .Values.persistence.finalizers }}
finalizers:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
accessModes:
- {{ .Values.global.persistence.accessMode }}
resources:
requests:
storage: {{ default .Values.global.persistence.size .Values.global.persistence.grafana.size | quote }}
{{- if .Values.global.persistence.storageClass }}
storageClassName: {{ .Values.global.persistence.storageClass }}
{{- end -}}
{{- with .Values.persistence.selectorLabels }}
selector:
matchLabels:
{{ toYaml . | indent 6 }}
{{- end }}
{{- end }}
{{- end}}

View File

@ -0,0 +1,34 @@
{{- if .Values.enabled }}
{{- if and .Values.rbac.create (not .Values.rbac.useExistingRole) -}}
apiVersion: {{ template "grafana.rbac.apiVersion" . }}
kind: Role
metadata:
name: {{ template "grafana.fullname" . }}
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
{{- if or .Values.rbac.pspEnabled (and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled (or .Values.sidecar.plugins.enabled .Values.rbac.extraRoleRules)))) }}
rules:
{{- if .Values.rbac.pspEnabled }}
- apiGroups: ['extensions']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames: [{{ template "grafana.fullname" . }}]
{{- end }}
{{- if and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled)) }}
- apiGroups: [""] # "" indicates the core API group
resources: ["configmaps", "secrets"]
verbs: ["get", "watch", "list"]
{{- end }}
{{- with .Values.rbac.extraRoleRules }}
{{ toYaml . | indent 0 }}
{{- end}}
{{- else }}
rules: []
{{- end }}
{{- end }}
{{- end}}

View File

@ -0,0 +1,27 @@
{{- if .Values.enabled }}
{{- if .Values.rbac.create -}}
apiVersion: {{ template "grafana.rbac.apiVersion" . }}
kind: RoleBinding
metadata:
name: {{ template "grafana.fullname" . }}
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
{{- if (not .Values.rbac.useExistingRole) }}
name: {{ template "grafana.fullname" . }}
{{- else }}
name: {{ .Values.rbac.useExistingRole }}
{{- end }}
subjects:
- kind: ServiceAccount
name: {{ template "grafana.serviceAccountName" . }}
namespace: {{ template "grafana.namespace" . }}
{{- end -}}
{{- end}}

View File

@ -0,0 +1,16 @@
{{- if .Values.enabled }}
{{- if .Values.envRenderSecret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "grafana.fullname" . }}-env
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
type: Opaque
data:
{{- range $key, $val := .Values.envRenderSecret }}
{{ $key }}: {{ $val | b64enc | quote }}
{{- end -}}
{{- end }}
{{- end}}

View File

@ -0,0 +1,28 @@
{{- if .Values.enabled }}
{{- if or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret)) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "grafana.fullname" . }}
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
type: Opaque
data:
{{- if and (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) }}
admin-user: {{ .Values.adminUser | b64enc | quote }}
{{- if .Values.adminPassword }}
admin-password: {{ .Values.adminPassword | b64enc | quote }}
{{- else }}
admin-password: {{ template "grafana.password" . }}
{{- end }}
{{- end }}
{{- if not .Values.ldap.existingSecret }}
ldap-toml: {{ tpl .Values.ldap.config $ | b64enc | quote }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,62 @@
{{- if .Values.enabled }}
{{ if .Values.service.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "grafana.fullname" . }}
namespace: {{ template "grafana.namespace" . }}
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- if .Values.service.labels }}
{{ toYaml .Values.service.labels | indent 4 }}
{{- end }}
annotations:
getambassador.io/config: |
---
apiVersion: getambassador.io/v3alpha1
kind: Mapping
name: grafana-server-mapping
prefix: /{{- include "k10.ingressPath" . | trimSuffix "/" }}/grafana/
rewrite: /
service: {{ template "grafana.fullname" .}}:{{ .Values.service.port }}
timeout_ms: 15000
hostname: "*"
ambassador_id: [ {{ include "k10.ambassadorId" . }} ]
spec:
{{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }}
type: ClusterIP
{{- if .Values.service.clusterIP }}
clusterIP: {{ .Values.service.clusterIP }}
{{end}}
{{- else if eq .Values.service.type "LoadBalancer" }}
type: {{ .Values.service.type }}
{{- if .Values.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
{{- end }}
{{- if .Values.service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }}
{{- end -}}
{{- else }}
type: {{ .Values.service.type }}
{{- end }}
{{- if .Values.service.externalIPs }}
externalIPs:
{{ toYaml .Values.service.externalIPs | indent 4 }}
{{- 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 }}
{{- if .Values.extraExposePorts }}
{{- tpl (toYaml .Values.extraExposePorts) . | indent 4 }}
{{- end }}
selector:
{{- include "grafana.selectorLabels" . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,16 @@
{{- if .Values.enabled }}
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
{{- include "grafana.labels" . | nindent 4 }}
{{- $root := . }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{ tpl (toYaml . | indent 4) $root }}
{{- end }}
name: {{ template "grafana.serviceAccountName" . }}
namespace: {{ template "grafana.namespace" . }}
{{- end }}
{{- end}}

Some files were not shown because too many files have changed in this diff Show More