Commit e727fa7d authored by konfiot's avatar konfiot

Merge branch 'master' of gitlab.binets.fr:br/kubernetes-helm-state

parents 10fdca71 0109350c
Pipeline #4403 passed with stage
in 13 seconds
image: linkyard/docker-helm
stages:
- lint
script:
stage: lint
script:
- cd charts
- helm lint sites-binets/ -f sites-binets/test_values.yaml
- helm lint prometheus/
- helm lint grafana/
- echo "Producing template files, check if they're right..."
- helm template sites-binets/ -f sites-binets/test_values.yaml -n creneaux --namespace creneaux-site
\ No newline at end of file
# Kubernetes-helm-state
Dépôt pour l'ensemble des chartes Helm déployées sur le cluster.
\ No newline at end of file
Dépôt pour l'ensemble des chartes Helm déployées sur le cluster.
## Notes : chartes à remplacer
* stash (appscode) a maintenant une charte officielle, celle de helm/charts/stable est deprecated
* kubedb idem
\ No newline at end of file
# 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
.project
.idea/
*.tmproj
apiVersion: v1
description: A Helm chart for ELK
home: https://www.elastic.co/products
icon: https://www.elastic.co/assets/bltb35193323e8f1770/logo-elastic-stack-lt.svg
name: elastic-stack
version: 0.9.0
appVersion: 6.0
maintainers:
- name: rendhalver
email: pete.brown@powerhrg.com
- name: jar361
email: jrodgers@powerhrg.com
- name: christian-roggia
email: christian.roggia@gmail.com
approvers:
- christian-roggia
- rendhalver
reviewers:
- christian-roggia
- rendhalver
# Elastic-stack Helm Chart
This chart installs an elasticsearch cluster with kibana and logstash by default.
You can optionally disable logstash and install Fluentd if you prefer. It also optionally installs nginx-ldapauth-proxy and elasticsearch-curator.
## Prerequisites Details
* Kubernetes 1.8+
* PV dynamic provisioning support on the underlying infrastructure
## Chart Details
This chart will do the following:
* Implemented a dynamically scalable elasticsearch cluster using Kubernetes StatefulSets/Deployments
* Multi-role deployment: master, client (coordinating) and data nodes
* Statefulset Supports scaling down without degrading the cluster
## Installing the Chart
To install the chart with the release name `my-release`:
```bash
$ helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator
$ helm install --name my-release incubator/elastic-stack
```
## Deleting the Charts
Delete the Helm deployment as normal
```
$ helm delete my-release
```
Deletion of the StatefulSet doesn't cascade to deleting associated PVCs. To delete them:
```
$ kubectl delete pvc -l release=my-release,component=data
```
## Configuration
Each requirement is configured with the options provided by that Chart.
Please consult the relevant charts for their configuration options.
dependencies:
- name: elasticsearch
repository: https://kubernetes-charts-incubator.storage.googleapis.com/
version: 1.2.0
- name: kibana
repository: https://kubernetes-charts.storage.googleapis.com/
version: 0.6.0
- name: logstash
repository: https://kubernetes-charts-incubator.storage.googleapis.com/
version: 0.6.3
- name: fluentd
repository: https://kubernetes-charts-incubator.storage.googleapis.com/
version: 0.1.4
- name: fluent-bit
repository: https://kubernetes-charts.storage.googleapis.com/
version: 0.6.0
- name: nginx-ldapauth-proxy
repository: https://kubernetes-charts.storage.googleapis.com/
version: 0.1.2
- name: elasticsearch-curator
repository: https://kubernetes-charts-incubator.storage.googleapis.com/
version: 0.2.4
digest: sha256:5a93301ce089e04837d2cd7ef0a547735388460186d9b0de2f62d982831df02b
generated: 2018-07-09T13:53:58.299283141-04:00
dependencies:
- name: elasticsearch
version: ^1.0.0
repository: https://kubernetes-charts-incubator.storage.googleapis.com/
- name: kibana
version: ^0.6.0
repository: https://kubernetes-charts.storage.googleapis.com/
- name: logstash
version: ^0.6.0
repository: https://kubernetes-charts-incubator.storage.googleapis.com/
condition: logstash.enabled
- name: fluentd
version: ^0.1.0
repository: https://kubernetes-charts-incubator.storage.googleapis.com/
condition: fluentd.enabled
- name: fluent-bit
version: ^0.6.0
repository: https://kubernetes-charts.storage.googleapis.com/
condition: fluent-bit.enabled
- name: nginx-ldapauth-proxy
version: ^0.1.0
repository: https://kubernetes-charts.storage.googleapis.com/
condition: nginx-ldapauth-proxy.enabled
- name: elasticsearch-curator
version: ^0.2.0
repository: https://kubernetes-charts-incubator.storage.googleapis.com/
condition: elasticsearch-curator.enabled
The elasticsearch cluster and associated extras have been installed.
Kibana can be accessed:
* Within your cluster, at the following DNS name at port 9200:
{{ template "kibana.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
* From outside the cluster, run these commands in the same shell:
{{- if contains "NodePort" .Values.kibana.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "kibana.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.kibana.service.type }}
WARNING: You have likely exposed your Elasticsearch cluster direct to the internet.
Elasticsearch does not implement any security for public facing clusters by default.
As a minimum level of security; switch to ClusterIP/NodePort and place an Nginx gateway infront of the cluster in order to lock down access to dangerous HTTP endpoints and verbs.
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 -w {{ template "kibana.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "kibana.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:9200
{{- else if contains "ClusterIP" .Values.kibana.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "kibana.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:5601 to use Kibana"
kubectl port-forward --namespace {{ .Release.Namespace }} $POD_NAME 5601:5601
{{- end }}
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "elastic-stack.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 "elastic-stack.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 "elastic-stack.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
# Default values for elk.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
kibana:
env:
ELASTICSEARCH_URL: http://http.default.svc.cluster.local:9200
logstash:
enabled: true
fluentd:
enabled: false
fluent-bit:
enabled: false
nginx-ldapauth-proxy:
enabled: false
# Example config to get it working with ELK. Adjust as you need to.
# proxy:
# port: 5601
# # This is the internal hostname for the kibana service
# host: "elk-kibana.default.svc.cluster.local"
# authName: "ELK:Infrastructure:LDAP"
# ldapHost: "ldap.example.com"
# ldapDN: "dc=example,dc=com"
# ldapFilter: "objectClass=organizationalPerson"
# ldapBindDN: "cn=reader,dc=example,dc=com"
# requires:
# - name: "ELK-USER"
# filter: "cn=elkuser,ou=groups,dc=example,dc=com"
# ingress:
# enabled: true
# hosts:
# - "elk.example.com"
# annotations:
# kubernetes.io/ingress.class: nginx
# tls:
# - hosts:
# - elk.example.com
# secretName: example-elk-tls
# secrets:
# ldapBindPassword: PASSWORD
elasticsearch-curator:
enabled: false
name: grafana
version: 1.12.0
appVersion: 5.1.3
kubeVersion: "^1.8.0-0"
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
sources:
- https://github.com/grafana/grafana
maintainers:
- name: zanhsieh
email: zanhsieh@gmail.com
- name: rtluckie
email: rluckie@cisco.com
engine: gotpl
# Grafana Helm Chart
* Installs the web dashboarding system [Grafana](http://grafana.org/)
## TL;DR;
```console
$ helm install stable/grafana
```
## Installing the Chart
To install the chart with the release name `my-release`:
```console
$ helm install --name my-release stable/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.
## Configuration
| Parameter | Description | Default |
|----------------------------|-------------------------------------|---------------------------------------------------------|
| `replicas` | Number of nodes | `1` |
| `deploymentStrategy` | Deployment strategy | `RollingUpdate` |
| `image.repository` | Image repository | `grafana/grafana` |
| `image.tag` | Image tag. (`Must be >= 5.0.0`) Possible values listed [here](https://hub.docker.com/r/grafana/grafana/tags/).| `5.0.4`|
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `service.type` | Kubernetes service type | `ClusterIP` |
| `service.port` | Kubernetes port where service is exposed| `9000` |
| `service.annotations` | Service annotations | `80` |
| `service.labels` | Custom labels | `{}`
| `ingress.enabled` | Enables Ingress | `false` |
| `ingress.annotations` | Ingress annotations | `{}` |
| `ingress.labels` | Custom labels | `{}`
| `ingress.hosts` | Ingress accepted hostnames | `[]` |
| `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 | `{}` |
| `persistence.enabled` | Use persistent volume to store data | `false` |
| `persistence.size` | Size of persistent volume claim | `10Gi` |
| `persistence.existingClaim`| Use an existing PVC to persist data | `nil` |
| `persistence.storageClassName` | Type of persistent volume claim | `nil` |
| `persistence.accessModes` | Persistence access modes | `[]` |
| `persistence.subPath` | Mount a sub directory of the persistent volume if set | `""` |
| `schedulerName` | Alternate scheduler name | `nil` |
| `env` | Extra environment variables passed to pods | `{}` |
| `envFromSecret` | The name of a Kubenretes secret (must be manually created in the same namespace) containing values to be added to the environment | `""` |
| `extraSecretMounts` | Additional grafana server secret mounts | `[]` |
| `datasources` | Configure grafana datasources | `{}` |
| `dashboardProviders` | Configure grafana dashboard providers | `{}` |
| `dashboards` | Dashboards to import | `{}` |
| `dashboardsConfigMaps` | ConfigMaps reference that contains dashboards | `{}` |
| `grafana.ini` | Grafana's primary configuration | `{}` |
| `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 | `{}` |
| `podAnnotations` | Pod annotations | `{}` |
| `sidecar.dashboards.enabled` | Enabled the cluster wide search for dashboards and adds/updates/deletes them in grafana | false |
| `sidecar.dashboards.label` | Label that config maps with dashboards should have to be added | false |
| `sidecar.datasources.enabled` | Enabled 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 | false |
| `smtp.existingSecret` | The name of an existing secret containing the SMTP credentials, this must have the keys `user` and `password`. | `""` |
## Sidecar for dashboards
If the parameter `sidecar.dashboards.enabled` is set, a sidecar container is deployed in the grafana pod. This container watches all config maps 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 an reduction of multiple dashboards inside one configmap is currently not properly mirrored in grafana.
Example dashboard config:
```
apiVersion: v1
kind: ConfigMap
metadata:
name: sample-grafana-dashboard
labels:
grafana_dashboard: 1
data:
k8s-dashboard.json: |-
[...]
```
## Sidecar for datasources
If the parameter `sidecar.datasource.enabled` is set, a sidecar container is deployed in the grafana pod. This container watches all config maps in the cluster and filters out the ones with a label as defined in `sidecar.datasources.label`. The files defined in those configmaps are written to a folder and accessed by grafana on startup. Using these yaml files, the data sources in grafana can be modified.
Example datasource config adapted from [Grafana](http://docs.grafana.org/administration/provisioning/#example-datasource-config-file):
```
apiVersion: v1
kind: ConfigMap
metadata:
name: sample-grafana-datasource
labels:
grafana_datasource: 1
data:
datasource.yaml: |-
# config file version
apiVersion: 1
# list of datasources that should be deleted from the database
deleteDatasources:
- name: Graphite
orgId: 1
# list of datasources to insert/update depending
# whats available in the database
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
```
1. Get your '{{ .Values.adminUser }}' user password by running:
kubectl get secret --namespace {{ .Release.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" . }}.{{ .Release.Namespace }}.svc.cluster.local
{{ if .Values.ingress.enabled }}
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 {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "grafana.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.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 {{ .Release.Namespace }} -w {{ template "grafana.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.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 {{ .Release.Namespace }} -l "app={{ template "grafana.fullname" . }},component={{ .Values.name }}" -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 3000
{{- end }}
{{- end }}
3. Login with the password from step 1 and the username: {{ .Values.adminUser }}
{{- if not .Values.persistence.enabled }}
#################################################################################
###### WARNING: Persistence is disabled!!! You will lose your data when #####
###### the Grafana pod is terminated. #####
#################################################################################
{{- end }}
{{/* 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 -}}
{{- if .Values.rbac.create }}
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
app: {{ template "grafana.name" . }}
chart: {{ template "grafana.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
name: {{ template "grafana.fullname" . }}-clusterrole
{{- if or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled }}
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["configmaps"]
verbs: ["get", "watch", "list"]
{{- else }}
rules: []
{{- end}}
{{- end}}
{{- if .Values.rbac.create }}
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "grafana.fullname" . }}-clusterrolebinding
labels:
app: {{ template "grafana.name" . }}
chart: {{ template "grafana.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
subjects:
- kind: ServiceAccount
name: {{ template "grafana.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
name: {{ template "grafana.fullname" . }}-clusterrole
apiGroup: rbac.authorization.k8s.io
{{- end}}
{{- if .Values.sidecar.dashboards.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app: {{ template "grafana.name" . }}
chart: {{ template "grafana.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
name: {{ template "grafana.fullname" . }}-config-dashboards
data:
provider.yaml: |-
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: ''
type: file
disableDeletion: false
options:
path: {{ .Values.sidecar.dashboards.folder }}
{{- end}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "grafana.fullname" . }}
labels:
app: {{ template "grafana.name" . }}
chart: {{ template "grafana.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
data:
{{- with .Values.plugins }}
plugins: {{ . | quote }}
{{- end }}
grafana.ini: |
{{- range $key, $value := index .Values "grafana.ini" }}
[{{ $key }}]
{{- range $elem, $elemVal := $value }}
{{ $elem }} = {{ $elemVal }}
{{- end }}
{{- end }}
{{- if .Values.datasources }}
{{- range $key, $value := .Values.datasources }}
{{ $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 }}
{{- range $provider, $dashboards := .Values.dashboards }}
{{- range $key, $value := $dashboards }}
{{- if (or (hasKey $value "gnetId") (hasKey $value "url")) }}
curl -sk \
--connect-timeout 60 \
--max-time 60 \
-H "Accept: application/json" \
-H "Content-Type: application/json;charset=UTF-8" \
{{- 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 }} \
> /var/lib/grafana/dashboards/{{ $provider }}/{{ $key }}.json
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.dashboards }}
{{- range $provider, $dashboards := .Values.dashboards }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "grafana.fullname" $ }}-dashboards-{{ $provider }}
labels:
app: {{ template "grafana.name" $ }}
chart: {{ template "grafana.chart" $ }}
release: {{ $.Release.Name }}
heritage: {{ $.Release.Service }}
dashboard-provider: {{ $provider }}
data:
{{- range $key, $value := $dashboards }}
{{- if hasKey $value "json" }}
{{ $key }}.json: |
{{ $value.json | indent 4 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}