From cc1e6d7eed0a35baa427c62348c57e4a53609134 Mon Sep 17 00:00:00 2001
From: Keshav Prasad <keshavprasadms@gmail.com>
Date: Thu, 18 Feb 2021 19:25:17 +0530
Subject: [PATCH] feat: adding ES curator chart to auto clear indices (#2264)

* feat: adding es curator chart

* fix: updating jenkins job

* fix: retain last 2 days indices

* fix: removed deprecated text
---
 .../jobs/Kubernetes/jobs/Logging/config.xml   |   5 +-
 .../templates/elasticsearch-curator.yaml      |  37 ++++
 .../logging/elasticsearch-curator/.helmignore |  21 +++
 .../logging/elasticsearch-curator/Chart.yaml  |  14 ++
 .../logging/elasticsearch-curator/README.md   |  88 ++++++++++
 .../elasticsearch-curator/templates/NOTES.txt |   6 +
 .../templates/_helpers.tpl                    |  66 ++++++++
 .../templates/configmap.yaml                  |  12 ++
 .../templates/cronjob.yaml                    | 127 ++++++++++++++
 .../templates/hooks/job.install.yaml          |  72 ++++++++
 .../elasticsearch-curator/templates/psp.yml   |  35 ++++
 .../elasticsearch-curator/templates/role.yaml |  23 +++
 .../templates/rolebinding.yaml                |  21 +++
 .../templates/serviceaccount.yaml             |  12 ++
 .../logging/elasticsearch-curator/values.yaml | 160 ++++++++++++++++++
 15 files changed, 697 insertions(+), 2 deletions(-)
 create mode 100644 kubernetes/ansible/roles/logging/templates/elasticsearch-curator.yaml
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/.helmignore
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/Chart.yaml
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/README.md
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/templates/NOTES.txt
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/templates/_helpers.tpl
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/templates/configmap.yaml
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/templates/cronjob.yaml
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/templates/hooks/job.install.yaml
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/templates/psp.yml
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/templates/role.yaml
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/templates/rolebinding.yaml
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/templates/serviceaccount.yaml
 create mode 100644 kubernetes/helm_charts/logging/elasticsearch-curator/values.yaml

diff --git a/deploy/jenkins/jobs/Deploy/jobs/dev/jobs/Kubernetes/jobs/Logging/config.xml b/deploy/jenkins/jobs/Deploy/jobs/dev/jobs/Kubernetes/jobs/Logging/config.xml
index f123de45a..3d57b5f39 100644
--- a/deploy/jenkins/jobs/Deploy/jobs/dev/jobs/Kubernetes/jobs/Logging/config.xml
+++ b/deploy/jenkins/jobs/Deploy/jobs/dev/jobs/Kubernetes/jobs/Logging/config.xml
@@ -87,7 +87,8 @@ return """&lt;b&gt;This parameter is not used&lt;/b&gt;"""</script>
               <string>fluent-bit</string>
               <string>kibana</string>
               <string>oauth2-proxy</string>
-              <string>fluentd-elasticsearch</string>
+	      <string>fluentd-elasticsearch</string>
+	      <string>elasticsearch-curator</string>
             </a>
           </choices>
         </hudson.model.ChoiceParameterDefinition>
@@ -146,4 +147,4 @@ return """&lt;b&gt;This parameter is not used&lt;/b&gt;"""</script>
   </definition>
   <triggers/>
   <disabled>false</disabled>
-</flow-definition>
\ No newline at end of file
+</flow-definition>
diff --git a/kubernetes/ansible/roles/logging/templates/elasticsearch-curator.yaml b/kubernetes/ansible/roles/logging/templates/elasticsearch-curator.yaml
new file mode 100644
index 000000000..8405912d0
--- /dev/null
+++ b/kubernetes/ansible/roles/logging/templates/elasticsearch-curator.yaml
@@ -0,0 +1,37 @@
+---
+cronjob:
+  # At mid night every day of system time
+  schedule: "00 00 * * *"
+  jobRestartPolicy: Never
+
+image:
+  repository: untergeek/curator
+  tag: 5.8.1
+  pullPolicy: IfNotPresent
+
+configMaps:
+  # Delete indices older than 2 days
+  action_file_yml: |-
+    ---
+    actions:
+      1:
+        action: delete_indices
+        description: "Clean up ES by deleting old indices"
+        options:
+          timeout_override:
+          continue_if_exception: False
+          disable_action: False
+          ignore_empty_list: True
+        filters:
+        - filtertype: age
+          source: name
+          direction: older
+          timestring: '%Y.%m.%d'
+          unit: days
+          unit_count: 2
+  config_yml: |-
+    ---
+    client:
+      hosts:
+        - {{ groups['log-es'][0] }}
+      port: 9200
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/.helmignore b/kubernetes/helm_charts/logging/elasticsearch-curator/.helmignore
new file mode 100644
index 000000000..f0c131944
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/.helmignore
@@ -0,0 +1,21 @@
+# 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
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/Chart.yaml b/kubernetes/helm_charts/logging/elasticsearch-curator/Chart.yaml
new file mode 100644
index 000000000..fbe9d7486
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/Chart.yaml
@@ -0,0 +1,14 @@
+apiVersion: v1
+appVersion: "5.7.6"
+description: A Helm chart for Elasticsearch Curator
+name: elasticsearch-curator
+version: 2.2.3
+home: https://github.com/elastic/curator
+keywords:
+- curator
+- elasticsearch
+- elasticsearch-curator
+sources:
+- https://github.com/kubernetes/charts/elasticsearch-curator
+- https://github.com/pires/docker-elasticsearch-curator
+deprecated: true
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/README.md b/kubernetes/helm_charts/logging/elasticsearch-curator/README.md
new file mode 100644
index 000000000..ac3979807
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/README.md
@@ -0,0 +1,88 @@
+# ⚠️ Repo Archive Notice
+
+As of Nov 13, 2020, charts in this repo will no longer be updated.
+For more information, see the Helm Charts [Deprecation and Archive Notice](https://github.com/helm/charts#%EF%B8%8F-deprecation-and-archive-notice), and [Update](https://helm.sh/blog/charts-repo-deprecation/).
+
+# Elasticsearch Curator Helm Chart
+
+This directory contains a Kubernetes chart to deploy the [Elasticsearch Curator](https://github.com/elastic/curator).
+
+## DEPRECATION NOTICE
+
+This chart is deprecated and no longer supported.
+
+## Prerequisites Details
+
+* Elasticsearch
+
+* The `elasticsearch-curator` cron job requires [K8s CronJob](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) support:
+    > You need a working Kubernetes cluster at version >= 1.8 (for CronJob). For previous versions of cluster (< 1.8) you need to explicitly enable `batch/v2alpha1` API by passing `--runtime-config=batch/v2alpha1=true` to the API server ([see Turn on or off an API version for your cluster for more](https://kubernetes.io/docs/admin/cluster-management/#turn-on-or-off-an-api-version-for-your-cluster)).
+
+## Chart Details
+
+This chart will do the following:
+
+* Create a CronJob which runs the Curator
+
+## Installing the Chart
+
+To install the chart, use the following:
+
+```console
+$ helm install stable/elasticsearch-curator
+```
+
+## 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 2.0.0
+
+v2.0.0 uses docker image from `elasticsearch-curator` author, which differs in its way to install curator.
+
+If you have a hardcoded `command` value, please update it to follow the new `curator` executable path: `/curator/curator` (which is not in PATH).
+
+## Configuration
+
+The following table lists the configurable parameters of the docker-registry chart and
+their default values.
+
+|          Parameter                   |                         Description                         |                   Default                    |
+| :----------------------------------- | :---------------------------------------------------------- | :------------------------------------------- |
+| `image.pullPolicy`                   | Container pull policy                                       | `IfNotPresent`                               |
+| `image.repository`                   | Container image to use                                      | `untergeek/curator`                          |
+| `image.tag`                          | Container image tag to deploy                               | `5.7.6`                                      |
+| `hooks`                              | Whether to run job on selected hooks                        | `{ "install": false, "upgrade": false }`     |
+| `cronjob.schedule`                   | Schedule for the CronJob                                    | `0 1 * * *`                                  |
+| `cronjob.annotations`                | Annotations to add to the cronjob                           | {}                                           |
+| `cronjob.labels`                     | Labels to add to the cronjob                                | {}                                           |
+| `cronjob.concurrencyPolicy`          | `Allow\|Forbid\|Replace` concurrent jobs                    | `nil`                                        |
+| `cronjob.failedJobsHistoryLimit`     | Specify the number of failed Jobs to keep                   | `nil`                                        |
+| `cronjob.successfulJobsHistoryLimit` | Specify the number of completed Jobs to keep                | `nil`                                        |
+| `cronjob.jobRestartPolicy`           | Control the Job restartPolicy                               | `Never`                                      |
+| `cronjob.startingDeadlineSeconds`    | Amount of time to try reschedule job if we can't run on time| `nil`                                         |
+| `pod.annotations`                    | Annotations to add to the pod                               | {}                                           |
+| `pod.labels`                         | Labels to add to the pod                                    | {}                                           |
+| `dryrun`                             | Run Curator in dry-run mode                                 | `false`                                      |
+| `env`                                | Environment variables to add to the cronjob container       | {}                                           |
+| `envFromSecrets`                     | Environment variables from secrets to the cronjob container | {}                                           |
+| `envFromSecrets.*.from.secret`       | - `secretKeyRef.name` used for environment variable         |                                              |
+| `envFromSecrets.*.from.key`          | - `secretKeyRef.key` used for environment variable          |                                              |
+| `command`                            | Command to execute                                          | ["/curator/curator"]                         |
+| `configMaps.action_file_yml`         | Contents of the Curator action_file.yml                     | See values.yaml                              |
+| `configMaps.config_yml`              | Contents of the Curator config.yml (overrides config)       | See values.yaml                              |
+| `resources`                          | Resource requests and limits                                | {}                                           |
+| `priorityClassName`                  | priorityClassName                                           | `nil`                                        |
+| `extraVolumeMounts`                  | Mount extra volume(s),                                      |                                              |
+| `extraVolumes`                       | Extra volumes                                               |                                              |
+| `extraInitContainers`                | Init containers to add to the cronjob container             | {}                                           |
+| `securityContext`                    | Configure PodSecurityContext                                | `false`                                      |
+| `rbac.enabled`                       | Enable RBAC resources                                       | `false`                                      |
+| `psp.create`                         | Create pod security policy resources                        | `false`                                      |
+| `serviceAccount.create`              | Create a default serviceaccount for elasticsearch curator   | `true`                                       |
+| `serviceAccount.name`                | Name for elasticsearch curator serviceaccount               | `""`                                         |
+
+
+Specify each parameter using the `--set key=value[,key=value]` argument to
+`helm install`.
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/templates/NOTES.txt b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/NOTES.txt
new file mode 100644
index 000000000..0b4fe0251
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/NOTES.txt
@@ -0,0 +1,6 @@
+A CronJob will run with schedule {{ .Values.cronjob.schedule }}.
+
+The Jobs will not be removed automagically when deleting this Helm chart.
+To remove these jobs, run the following :
+
+    kubectl -n {{ .Release.Namespace }} delete job -l app={{ template "elasticsearch-curator.name" . }},release={{ .Release.Name }}
\ No newline at end of file
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/templates/_helpers.tpl b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/_helpers.tpl
new file mode 100644
index 000000000..8018c5d9c
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/_helpers.tpl
@@ -0,0 +1,66 @@
+{{/* vim: set filetype=mustache: */}}
+
+{{/*
+Return the appropriate apiVersion for cronjob APIs.
+*/}}
+{{- define "cronjob.apiVersion" -}}
+{{- if semverCompare "< 1.8-0" .Capabilities.KubeVersion.GitVersion -}}
+{{- print "batch/v2alpha1" }}
+{{- else if semverCompare ">=1.8-0" .Capabilities.KubeVersion.GitVersion -}}
+{{- print "batch/v1beta1" }}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Return the appropriate apiVersion for podsecuritypolicy.
+*/}}
+{{- define "podsecuritypolicy.apiVersion" -}}
+{{- if semverCompare "<1.10-0" .Capabilities.KubeVersion.GitVersion -}}
+{{- print "extensions/v1beta1" -}}
+{{- else -}}
+{{- print "policy/v1beta1" -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "elasticsearch-curator.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 "elasticsearch-curator.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 "elasticsearch-curator.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "elasticsearch-curator.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "elasticsearch-curator.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/templates/configmap.yaml b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/configmap.yaml
new file mode 100644
index 000000000..3bfc7fc38
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/configmap.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: {{ template "elasticsearch-curator.fullname" . }}-config
+  labels:
+    app: {{ template "elasticsearch-curator.name" . }}
+    chart: {{ template "elasticsearch-curator.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+data:
+  action_file.yml: {{ required "A valid .Values.configMaps.action_file_yml entry is required!" (toYaml .Values.configMaps.action_file_yml | indent 2) }}
+  config.yml: {{ required "A valid .Values.configMaps.config_yml entry is required!" (toYaml .Values.configMaps.config_yml | indent 2) }}
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/templates/cronjob.yaml b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/cronjob.yaml
new file mode 100644
index 000000000..97a790f05
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/cronjob.yaml
@@ -0,0 +1,127 @@
+apiVersion: {{ template "cronjob.apiVersion" . }}
+kind: CronJob
+metadata:
+  name: {{ template "elasticsearch-curator.fullname" . }}
+  labels:
+    app: {{ template "elasticsearch-curator.name" . }}
+    chart: {{ template "elasticsearch-curator.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+{{- if .Values.cronjob.labels }}
+{{ toYaml .Values.cronjob.labels | indent 4 }}
+{{- end }}
+{{- if .Values.cronjob.annotations }}
+  annotations:
+{{ toYaml .Values.cronjob.annotations | indent 4 }}
+{{- end }}
+spec:
+  schedule: "{{ .Values.cronjob.schedule }}"
+  {{- with .Values.cronjob.concurrencyPolicy }}
+  concurrencyPolicy: {{ . }}
+  {{- end }}
+  {{- with .Values.cronjob.failedJobsHistoryLimit }}
+  failedJobsHistoryLimit: {{ . }}
+  {{- end }}
+  {{- with .Values.cronjob.successfulJobsHistoryLimit }}
+  successfulJobsHistoryLimit: {{ . }}
+  {{- end }}
+  {{- with .Values.cronjob.startingDeadlineSeconds }}
+  startingDeadlineSeconds: {{ . }}
+  {{- end }}
+  jobTemplate:
+    metadata:
+      labels:
+        app: {{ template "elasticsearch-curator.name" . }}
+        release: {{ .Release.Name }}
+    spec:
+      template:
+        metadata:
+          labels:
+            app: {{ template "elasticsearch-curator.name" . }}
+            release: {{ .Release.Name }}
+{{- if .Values.pod.labels }}
+{{ toYaml .Values.pod.labels | indent 12 }}
+{{- end }}
+{{- if .Values.pod.annotations }}
+          annotations:
+{{ toYaml .Values.pod.annotations | indent 12 }}
+{{- end }}
+        spec:
+          volumes:
+            - name: config-volume
+              configMap:
+                name: {{ template "elasticsearch-curator.fullname" . }}-config
+{{- if .Values.extraVolumes }}
+{{ toYaml .Values.extraVolumes | indent 12 }}
+{{- end }}
+          restartPolicy: {{ .Values.cronjob.jobRestartPolicy }}
+{{- if .Values.priorityClassName }}
+          priorityClassName: "{{ .Values.priorityClassName }}"
+{{- end }}
+{{- if .Values.image.pullSecret }}
+          imagePullSecrets:
+            - name: {{ .Values.image.pullSecret }}
+{{- end }}
+{{- if .Values.extraInitContainers }}
+          initContainers:
+{{- range $key, $value := .Values.extraInitContainers }}
+          - name: "{{ $key }}"
+{{ toYaml $value | indent 12 }}
+{{- end }}
+{{- end }}
+        {{- if .Values.rbac.enabled }}
+          serviceAccountName: {{ template "elasticsearch-curator.serviceAccountName" .}}
+        {{- end }}
+          containers:
+            - name: {{ .Chart.Name }}
+              image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+              imagePullPolicy: {{ .Values.image.pullPolicy }}
+              volumeMounts:
+                - name: config-volume
+                  mountPath: /etc/es-curator
+{{- if .Values.extraVolumeMounts }}
+{{ toYaml .Values.extraVolumeMounts | indent 16 }}
+{{ end }}
+{{ if .Values.command }}
+              command:
+{{ toYaml .Values.command | indent 16 }}
+{{- end }}
+{{- if .Values.dryrun }}
+              args: [ "--dry-run", "--config", "/etc/es-curator/config.yml", "/etc/es-curator/action_file.yml" ]
+{{- else }}
+              args: [ "--config", "/etc/es-curator/config.yml", "/etc/es-curator/action_file.yml" ]
+{{- end }}
+              env:
+{{- if .Values.envFromSecrets }}
+{{- range $key,$value := .Values.envFromSecrets }}
+              - name: {{ $key | upper | quote}}
+                valueFrom:
+                  secretKeyRef:
+                    name: {{ $value.from.secret | quote}}
+                    key: {{ $value.from.key | quote}}
+{{- end }}
+{{- end }}
+{{- if .Values.env }}
+{{- range $key,$value := .Values.env }}
+              - name: {{ $key | upper | quote}}
+                value: {{ $value | quote}}
+{{- end }}
+{{- end }}
+              resources:
+{{ toYaml .Values.resources | indent 16 }}
+    {{- with .Values.nodeSelector }}
+          nodeSelector:
+{{ toYaml . | indent 12 }}
+    {{- end }}
+    {{- with .Values.affinity }}
+          affinity:
+{{ toYaml . | indent 12 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+          tolerations:
+{{ toYaml . | indent 12 }}
+    {{- end }}
+    {{- with .Values.securityContext }}
+          securityContext:
+{{ toYaml . | indent 12 }}
+    {{- end }}
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/templates/hooks/job.install.yaml b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/hooks/job.install.yaml
new file mode 100644
index 000000000..4695d265c
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/hooks/job.install.yaml
@@ -0,0 +1,72 @@
+{{- range $kind, $enabled := .Values.hooks }}
+{{ if $enabled }}
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ template "elasticsearch-curator.fullname" $ }}-on-{{ $kind }}
+  labels:
+    app: {{ template "elasticsearch-curator.name" $ }}
+    chart: {{ template "elasticsearch-curator.chart" $ }}
+    release: {{ $.Release.Name }}
+    heritage: {{ $.Release.Service }}
+  annotations:
+    "helm.sh/hook": post-{{ $kind }}
+    "helm.sh/hook-weight": "1"
+    "helm.sh/hook-delete-policy": before-hook-creation
+{{- if $.Values.cronjob.annotations }}
+{{ toYaml $.Values.cronjob.annotations | indent 4 }}
+{{- end }}
+spec:
+ template:
+    metadata:
+      labels:
+        app: {{ template "elasticsearch-curator.name" $ }}
+        release: {{ $.Release.Name }}
+{{- if $.Values.pod.annotations }}
+      annotations:
+{{ toYaml $.Values.pod.annotations | indent 8 }}
+{{- end }}
+    spec:
+      volumes:
+        - name: config-volume
+          configMap:
+            name: {{ template "elasticsearch-curator.fullname" $ }}-config
+{{- if $.Values.extraVolumes }}
+{{ toYaml $.Values.extraVolumes | indent 8 }}
+{{- end }}
+      restartPolicy: Never
+{{- if $.Values.priorityClassName }}
+      priorityClassName: "{{ $.Values.priorityClassName }}"
+{{- end }}
+      containers:
+        - name: {{ $.Chart.Name }}
+          image: "{{ $.Values.image.repository }}:{{ $.Values.image.tag }}"
+          imagePullPolicy: {{ $.Values.image.pullPolicy }}
+          volumeMounts:
+            - name: config-volume
+              mountPath: /etc/es-curator
+    {{- if $.Values.extraVolumeMounts }}
+{{ toYaml $.Values.extraVolumeMounts | indent 12 }}
+    {{- end }}
+{{ if $.Values.command }}
+          command:
+{{ toYaml $.Values.command | indent 12 }}
+{{- end }}
+          args: [ "--config", "/etc/es-curator/config.yml", "/etc/es-curator/action_file.yml" ]
+          resources:
+{{ toYaml $.Values.resources | indent 12 }}
+    {{- with $.Values.nodeSelector }}
+      nodeSelector:
+{{ toYaml . | indent 8 }}
+    {{- end }}
+    {{- with $.Values.affinity }}
+      affinity:
+{{ toYaml . | indent 8 }}
+    {{- end }}
+    {{- with $.Values.tolerations }}
+      tolerations:
+{{ toYaml . | indent 8 }}
+    {{- end }}
+{{- end -}}
+{{ end }}
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/templates/psp.yml b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/psp.yml
new file mode 100644
index 000000000..5f6298587
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/psp.yml
@@ -0,0 +1,35 @@
+{{- if .Values.psp.create }}
+apiVersion: {{ template "podsecuritypolicy.apiVersion" . }}
+kind: PodSecurityPolicy
+metadata:
+  labels:
+    app: {{ template "elasticsearch-curator.name" . }}
+    chart: {{ template "elasticsearch-curator.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+  name: {{ template "elasticsearch-curator.fullname" . }}-psp
+spec:
+  privileged: true
+  #requiredDropCapabilities:
+  volumes:
+    - 'configMap'
+    - 'secret'
+  hostNetwork: false
+  hostIPC: false
+  hostPID: false
+  runAsUser:
+    rule: 'RunAsAny'
+  seLinux:
+    rule: 'RunAsAny'
+  supplementalGroups:
+    rule: 'MustRunAs'
+    ranges:
+      - min: 1
+        max: 65535
+  fsGroup:
+    rule: 'MustRunAs'
+    ranges:
+      - min: 1
+        max: 65535
+  readOnlyRootFilesystem: false
+{{- end }}
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/templates/role.yaml b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/role.yaml
new file mode 100644
index 000000000..8867f6791
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/role.yaml
@@ -0,0 +1,23 @@
+{{- if .Values.rbac.enabled  }}
+kind: Role
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  labels:
+    app: {{ template "elasticsearch-curator.name" . }}
+    chart: {{ template "elasticsearch-curator.chart" . }}
+    heritage: {{ .Release.Service }}
+    release: {{ .Release.Name }}
+    component: elasticsearch-curator-configmap
+  name: {{ template "elasticsearch-curator.name" . }}-role
+rules:
+- apiGroups: [""]
+  resources: ["configmaps"]
+  verbs: ["update", "patch"]
+{{- if .Values.psp.create }}
+- apiGroups: ["extensions"]
+  resources: ["podsecuritypolicies"]
+  verbs: ["use"]
+  resourceNames:
+  - {{ template "elasticsearch-curator.fullname" . }}-psp
+{{- end -}}
+{{- end -}}
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/templates/rolebinding.yaml b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/rolebinding.yaml
new file mode 100644
index 000000000..d25d2e142
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/rolebinding.yaml
@@ -0,0 +1,21 @@
+{{- if .Values.rbac.enabled -}}
+kind: RoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  labels:
+    app: {{ template "elasticsearch-curator.name" . }}
+    chart: {{ template "elasticsearch-curator.chart" . }}
+    heritage: {{ .Release.Service }}
+    release: {{ .Release.Name }}
+    component: elasticsearch-curator-configmap
+  name: {{ template "elasticsearch-curator.name" . }}-rolebinding
+roleRef:
+  kind: Role
+  name: {{ template "elasticsearch-curator.name" . }}-role
+  apiGroup: rbac.authorization.k8s.io
+subjects:
+  - kind: ServiceAccount
+    name: {{ template "elasticsearch-curator.serviceAccountName" . }}
+    namespace: {{ .Release.Namespace }}
+{{- end -}}
+
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/templates/serviceaccount.yaml b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/serviceaccount.yaml
new file mode 100644
index 000000000..ad9c5c9ac
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/templates/serviceaccount.yaml
@@ -0,0 +1,12 @@
+{{- if and .Values.serviceAccount.create .Values.rbac.enabled }}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "elasticsearch-curator.serviceAccountName" .}}
+  labels:
+    app: {{ template "elasticsearch-curator.fullname" . }}
+    chart: {{ template "elasticsearch-curator.chart" . }}
+    release: "{{ .Release.Name }}"
+    heritage: "{{ .Release.Service }}"
+{{- end }}
+
diff --git a/kubernetes/helm_charts/logging/elasticsearch-curator/values.yaml b/kubernetes/helm_charts/logging/elasticsearch-curator/values.yaml
new file mode 100644
index 000000000..511d8a9a7
--- /dev/null
+++ b/kubernetes/helm_charts/logging/elasticsearch-curator/values.yaml
@@ -0,0 +1,160 @@
+# Default values for elasticsearch-curator.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+cronjob:
+  # At 01:00 every day
+  schedule: "0 1 * * *"
+  annotations: {}
+  labels: {}
+  concurrencyPolicy: ""
+  failedJobsHistoryLimit: ""
+  successfulJobsHistoryLimit: ""
+  jobRestartPolicy: Never
+  startingDeadlineSeconds: ""
+
+pod:
+  annotations: {}
+  labels: {}
+
+rbac:
+  # Specifies whether RBAC should be enabled
+  enabled: false
+
+serviceAccount:
+  # Specifies whether a ServiceAccount should be created
+  create: true
+  # The name of the ServiceAccount to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name:
+
+
+psp:
+  # Specifies whether a podsecuritypolicy should be created
+  create: false
+
+image:
+  repository: untergeek/curator
+  tag: 5.7.6
+  pullPolicy: IfNotPresent
+
+hooks:
+  install: false
+  upgrade: false
+
+# run curator in dry-run mode
+dryrun: false
+
+command: ["/curator/curator"]
+env: {}
+
+configMaps:
+  # Delete indices older than 7 days
+  action_file_yml: |-
+    ---
+    actions:
+      1:
+        action: delete_indices
+        description: "Clean up ES by deleting old indices"
+        options:
+          timeout_override:
+          continue_if_exception: False
+          disable_action: False
+          ignore_empty_list: True
+        filters:
+        - filtertype: age
+          source: name
+          direction: older
+          timestring: '%Y.%m.%d'
+          unit: days
+          unit_count: 7
+          field:
+          stats_result:
+          epoch:
+          exclude: False
+  # Having config_yaml WILL override the other config
+  config_yml: |-
+    ---
+    client:
+      hosts:
+        - CHANGEME.host
+      port: 9200
+      # url_prefix:
+      # use_ssl: True
+      # certificate:
+      # client_cert:
+      # client_key:
+      # ssl_no_validate: True
+      # http_auth:
+      # timeout: 30
+      # master_only: False
+    # logging:
+    #   loglevel: INFO
+    #   logfile:
+    #   logformat: default
+    #   blacklist: ['elasticsearch', 'urllib3']
+
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #  cpu: 100m
+  #  memory: 128Mi
+  # requests:
+  #  cpu: 100m
+  #  memory: 128Mi
+
+priorityClassName: ""
+
+# extraVolumes and extraVolumeMounts allows you to mount other volumes
+# Example Use Case: mount ssl certificates when elasticsearch has tls enabled
+# extraVolumes:
+#   - name: es-certs
+#     secret:
+#       defaultMode: 420
+#       secretName: es-certs
+# extraVolumeMounts:
+#   - name: es-certs
+#     mountPath: /certs
+#     readOnly: true
+
+# Add your own init container or uncomment and modify the given example.
+extraInitContainers: {}
+  ## Don't configure S3 repository till Elasticsearch is reachable.
+  ## Ensure that it is available at http://elasticsearch:9200
+  ##
+  # elasticsearch-s3-repository:
+  #   image: jwilder/dockerize:latest
+  #   imagePullPolicy: "IfNotPresent"
+  #   command:
+  #   - "/bin/sh"
+  #   - "-c"
+  #   args:
+  #   - |
+  #     ES_HOST=elasticsearch
+  #     ES_PORT=9200
+  #     ES_REPOSITORY=backup
+  #     S3_REGION=us-east-1
+  #     S3_BUCKET=bucket
+  #     S3_BASE_PATH=backup
+  #     S3_COMPRESS=true
+  #     S3_STORAGE_CLASS=standard
+  #     apk add curl --no-cache && \
+  #     dockerize -wait http://${ES_HOST}:${ES_PORT} --timeout 120s && \
+  #     cat <<EOF | curl -sS -XPUT -H "Content-Type: application/json" -d @- http://${ES_HOST}:${ES_PORT}/_snapshot/${ES_REPOSITORY} \
+  #     {
+  #       "type": "s3",
+  #       "settings": {
+  #         "bucket": "${S3_BUCKET}",
+  #         "base_path": "${S3_BASE_PATH}",
+  #         "region": "${S3_REGION}",
+  #         "compress": "${S3_COMPRESS}",
+  #         "storage_class": "${S3_STORAGE_CLASS}"
+  #       }
+  #     }
+
+securityContext:
+  runAsUser: 16  # run as cron user instead of root
-- 
GitLab