# _helpers.tpl
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "hazelcast.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 "hazelcast.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 "hazelcast.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create the name of the service account to use
*/}}
{{- define "hazelcast.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
    {{ default (include "hazelcast.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
    {{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}

{{/*
Create the name of the service to use
*/}}
{{- define "hazelcast.serviceName" -}}
{{- if .Values.service.create -}}
    {{ template "hazelcast.fullname" .}}
{{- else -}}
    {{ default "default" .Values.service.name }}
{{- end -}}
{{- end -}}

{{/*
Create a default fully qualified Management Center 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 "mancenter.fullname" -}}
{{ (include "hazelcast.fullname" .) | trunc 53 | }}-mancenter
{{- end -}} # config.yaml
{{- if and (or .Values.hazelcast.configurationFiles .Values.hazelcast.yaml) (not .Values.hazelcast.existingConfigMap) }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ template "hazelcast.fullname" . }}-configuration
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
data:
{{- range $key, $val := .Values.hazelcast.configurationFiles }}
  {{ $key }}: |-
{{ $val | indent 4}}
{{- end }}
  hazelcast.yaml: |-
{{ toYaml .Values.hazelcast.yaml | indent 4 }}
{{- end -}}
 # mancenter-config.yaml
{{- if and .Values.mancenter.enabled (and .Values.mancenter.yaml (not .Values.mancenter.existingConfigMap)) }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ template "mancenter.fullname" . }}-configuration
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
data:
  hazelcast-client.yaml: |-
{{ toYaml .Values.mancenter.yaml | indent 4 }}
{{- end -}}
 # mancenter-ingress.yaml
{{- if .Values.mancenter.ingress.enabled -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: "{{ include "mancenter.fullname" . }}"
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
{{- if .Values.mancenter.ingress.annotations }}
  annotations:
{{ toYaml .Values.mancenter.ingress.annotations | indent 4 }}
{{- end }}
spec:
{{- if .Values.mancenter.ingress.tls }}
  tls:
  {{- range .Values.mancenter.ingress.tls }}
    - hosts:
      {{- range .hosts }}
        - {{ . | quote }}
      {{- end }}
      secretName: {{ .secretName }}
  {{- end }}
{{- end }}
  rules:
  {{- $serviceName := include "mancenter.fullname" . -}}
  {{- if .Values.mancenter.ingress.hosts }}
  {{- range $host := .Values.mancenter.ingress.hosts }}
    - host: {{ $host | quote }}
      http:
        paths:
          - backend:
              serviceName: {{ $serviceName }}
              servicePort: http
  {{- end }}
  {{- else }}
  - http:
      paths:
      - backend:
          serviceName: {{ $serviceName }}
          servicePort: http
  {{- end }}
{{- end }}
 # mancenter-pvc.yaml
{{- if and (and .Values.mancenter.enabled .Values.mancenter.persistence.enabled (not .Values.mancenter.persistence.existingClaim)) }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: {{ template "mancenter.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
spec:
  accessModes:
  {{- range .Values.mancenter.persistence.accessModes }}
    - {{ . | quote }}
  {{- end }}
  resources:
    requests:
      storage: {{ .Values.mancenter.persistence.size | quote }}
{{- if .Values.mancenter.persistence.storageClass }}
{{- if (eq "-" .Values.mancenter.persistence.storageClass) }}
  storageClassName: ""
{{- else }}
  storageClassName: "{{ .Values.mancenter.persistence.storageClass }}"
{{- end }}
{{- end }}
{{- end }} # mancenter-service.yaml
{{- if .Values.mancenter.enabled }}
apiVersion: v1
kind: Service
metadata:
{{- if .Values.mancenter.service.annotations }}
  annotations:
{{ toYaml .Values.mancenter.service.annotations | indent 4 }}
{{- end }}
  name: {{ template "mancenter.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
spec:
  type: {{ .Values.mancenter.service.type }}
  {{- if .Values.mancenter.service.clusterIP }}
  clusterIP: {{ .Values.mancenter.service.clusterIP }}
  {{- end }}
  selector:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    role: mancenter
  ports:
  - protocol: TCP
    port: {{ .Values.mancenter.service.port }}
    targetPort: mancenter
    name: http
  - protocol: TCP
    port: {{ .Values.mancenter.service.httpsPort }}
    targetPort: mancenter
    name: https
{{- end }} # mancenter-statefulset.yaml
{{- if .Values.mancenter.enabled }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ template "mancenter.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
spec:
  serviceName: {{ template "mancenter.fullname" . }}
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ template "hazelcast.name" . }}
      app.kubernetes.io/instance: "{{ .Release.Name }}"
      role: mancenter
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ template "hazelcast.name" . }}
        helm.sh/chart: {{ template "hazelcast.chart" . }}
        app.kubernetes.io/instance: "{{ .Release.Name }}"
        app.kubernetes.io/managed-by: "{{ .Release.Service }}"
        role: mancenter
    spec:
      {{- if .Values.mancenter.image.pullSecrets }}
      imagePullSecrets:
        {{- range .Values.mancenter.image.pullSecrets }}
        - name: {{ . }}
        {{- end}}
      {{- end}}
      {{- if .Values.mancenter.nodeSelector }}
      nodeSelector:
{{ toYaml .Values.mancenter.nodeSelector | indent 8 }}
      {{- end }}
      hostNetwork: false
      hostPID: false
      hostIPC: false
      {{- if .Values.securityContext.enabled }}
      securityContext:
        runAsNonRoot: {{ if eq (int .Values.securityContext.runAsUser) 0 }}false{{ else }}true{{ end }}
        runAsUser: {{ .Values.securityContext.runAsUser }}
        runAsGroup: {{ .Values.securityContext.runAsGroup }}
        fsGroup: {{ .Values.securityContext.fsGroup }}
      {{- end }}
      {{- if .Values.mancenter.affinity }}
      affinity:
{{ toYaml .Values.mancenter.affinity | indent 8 }}
      {{- end }}
      {{- if .Values.mancenter.tolerations }}
      tolerations:
{{ toYaml .Values.mancenter.tolerations | indent 8 }}
      {{- end }}
      containers:
      - name: {{ template "mancenter.fullname" . }}
        image: "{{ .Values.mancenter.image.repository }}:{{ .Values.mancenter.image.tag }}"
        imagePullPolicy: {{ .Values.mancenter.image.pullPolicy | quote }}
        resources:
{{ toYaml .Values.mancenter.resources | indent 10 }}
        ports:
        - name: mancenter
          containerPort: {{ if .Values.mancenter.ssl }}8443{{ else }}8080{{ end }}
        {{- if .Values.mancenter.livenessProbe.enabled }}
        livenessProbe:
          httpGet:
            path: {{ if .Values.mancenter.contextPath }}{{ .Values.mancenter.contextPath }}{{ end }}/health
            port: 8081
          initialDelaySeconds: {{ .Values.mancenter.livenessProbe.initialDelaySeconds }}
          periodSeconds: {{ .Values.mancenter.livenessProbe.periodSeconds }}
          timeoutSeconds: {{ .Values.mancenter.livenessProbe.timeoutSeconds }}
          successThreshold: {{ .Values.mancenter.livenessProbe.successThreshold }}
          failureThreshold: {{ .Values.mancenter.livenessProbe.failureThreshold }}
        {{- end }}
        {{- if .Values.mancenter.readinessProbe.enabled }}
        readinessProbe:
          httpGet:
            path: {{ if .Values.mancenter.contextPath }}{{ .Values.mancenter.contextPath }}{{ end }}/health
            port: 8081
          initialDelaySeconds: {{ .Values.mancenter.readinessProbe.initialDelaySeconds }}
          periodSeconds: {{ .Values.mancenter.readinessProbe.periodSeconds }}
          timeoutSeconds: {{ .Values.mancenter.readinessProbe.timeoutSeconds }}
          successThreshold: {{ .Values.mancenter.readinessProbe.successThreshold }}
          failureThreshold: {{ .Values.mancenter.readinessProbe.failureThreshold }}
        {{- end }}
        volumeMounts:
        - name: config
          mountPath: /config
        - name: mancenter-storage
          mountPath: /data
        {{- if .Values.mancenter.secretsMountName }}
        - name: mancenter-secrets
          mountPath: /secrets
        {{- end }}
        env:
        {{- if .Values.mancenter.contextPath }}
        - name: MC_CONTEXT_PATH
          value: {{ .Values.mancenter.contextPath }}
        {{- end }}
        - name: MC_LICENSE_KEY
        {{- if .Values.mancenter.licenseKeySecretName }}
          valueFrom:
            secretKeyRef:
              name: {{ .Values.mancenter.licenseKeySecretName }}
              key: key
        {{- else }}
          value: {{ .Values.mancenter.licenseKey }}
        {{- end }}
        - name: MC_INIT_CMD
          value: "./mc-conf.sh cluster add --lenient=true -H /data -cc /config/hazelcast-client.yaml"
        - name: JAVA_OPTS
          value: "{{ if or .Values.mancenter.licenseKey .Values.mancenter.licenseKeySecretName }}-Dhazelcast.mc.license=$(MC_LICENSE_KEY){{ end }} {{ if or .Values.mancenter.readinessProbe.enabled .Values.mancenter.livenessProbe.enabled }}-Dhazelcast.mc.healthCheck.enable=true{{ end }} -DserviceName={{ template "hazelcast.serviceName" . }} -Dhazelcast.mc.tls.enabled={{ .Values.mancenter.ssl }} {{ .Values.mancenter.javaOpts }}"
        {{- if .Values.securityContext.enabled }}
        securityContext:
          runAsNonRoot: {{ if eq (int .Values.securityContext.runAsUser) 0 }}false{{ else }}true{{ end }}
          runAsUser: {{ .Values.securityContext.runAsUser }}
          runAsGroup: {{ .Values.securityContext.runAsGroup }}
          privileged: false
          readOnlyRootFilesystem: false
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
        {{- end }}
      {{- if .Values.securityContext.enabled }}
      securityContext:
        fsGroup: {{ .Values.securityContext.fsGroup }}
      {{- end }}
      serviceAccountName: {{ template "hazelcast.serviceAccountName" . }}
      volumes:
      - name: config
        configMap:
           {{- if .Values.mancenter.existingConfigMap }}
           name: {{ .Values.mancenter.existingConfigMap }}
           {{- else }}
           name: {{ template "mancenter.fullname" . }}-configuration
           {{- end }}
      {{- if .Values.mancenter.secretsMountName }}
      - name: mancenter-secrets
        secret:
          secretName: {{ .Values.mancenter.secretsMountName }}
      {{- end }}
      - name: mancenter-storage
        {{- if and (eq .Values.mancenter.persistence.enabled true) .Values.mancenter.persistence.existingClaim }}
        persistentVolumeClaim:
          claimName: {{ .Values.mancenter.persistence.existingClaim }}
        {{- else if (eq .Values.mancenter.persistence.enabled false) }}
        emptyDir: {}
        {{- end }}
    {{ if and (eq .Values.mancenter.persistence.enabled true) (empty .Values.mancenter.persistence.existingClaim) }}
  volumeClaimTemplates:
  - metadata:
      name: mancenter-storage
      labels:
        app.kubernetes.io/name: {{ template "hazelcast.name" . }}
        helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
        app.kubernetes.io/instance: "{{ .Release.Name }}"
        app.kubernetes.io/managed-by: "{{ .Release.Service }}"
    spec:
      accessModes:
      {{- range .Values.mancenter.persistence.accessModes }}
        - {{ . | quote }}
      {{- end }}
      {{- if .Values.mancenter.persistence.storageClass }}
      {{- if (eq "-" .Values.mancenter.persistence.storageClass) }}
      storageClassName: ""
      {{- else }}
      storageClassName: "{{ .Values.mancenter.persistence.storageClass }}"
      {{- end }}
      {{- end }}
      resources:
        requests:
          storage: {{ .Values.mancenter.persistence.size | quote }}
  {{- end -}}
{{- end -}}
 # metrics-service.yaml
{{- if .Values.metrics.enabled }}
apiVersion: v1
kind: Service
metadata:
  name: {{ template "hazelcast.fullname" . }}-metrics
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
  annotations:
{{ toYaml .Values.metrics.service.annotations | indent 4 }}
spec:
  type: {{ .Values.metrics.service.type }}
  selector:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
  ports:
  - protocol: TCP
    port: {{ .Values.metrics.service.port }}
    targetPort: metrics
    name: metrics
{{- end }}
 # role.yaml
{{- if .Values.rbac.create -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: {{ template "hazelcast.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
rules:
- apiGroups:
  - ""
  resources:
  - endpoints
  - pods
  - nodes
  verbs:
  - get
  - list
{{- end -}}
 # rolebinding.yaml
{{- if .Values.rbac.create -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: {{ template "hazelcast.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: {{ template "hazelcast.fullname" . }}
subjects:
- kind: ServiceAccount
  name: {{ template "hazelcast.serviceAccountName" . }}
  namespace: {{ .Release.Namespace }}
{{ end }}
 # service.yaml
{{- if .Values.service.create }}
apiVersion: v1
kind: Service
metadata:
  name: {{ template "hazelcast.serviceName" . }}
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
spec:
  type: {{ .Values.service.type }}
  {{- if .Values.service.clusterIP }}
  clusterIP: {{ .Values.service.clusterIP }}
  {{- end }}
  selector:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    role: hazelcast
  ports:
  - protocol: TCP
    port: {{ .Values.service.port }}
    targetPort: hazelcast
    name: hzport
{{- end -}}
 # serviceaccount.yaml
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ template "hazelcast.serviceAccountName" . }}
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
{{- end -}}
 # statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ template "hazelcast.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
spec:
  serviceName: {{ template "hazelcast.fullname" . }}
  replicas: {{ .Values.cluster.memberCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ template "hazelcast.name" . }}
      app.kubernetes.io/instance: "{{ .Release.Name }}"
      role: hazelcast
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ template "hazelcast.name" . }}
        helm.sh/chart: {{ template "hazelcast.chart" . }}
        app.kubernetes.io/instance: "{{ .Release.Name }}"
        app.kubernetes.io/managed-by: "{{ .Release.Service }}"
        role: hazelcast
      annotations:
        checksum/hazelcast-config: {{ toYaml .Values.hazelcast.yaml | sha256sum }}
    spec:
      {{- if .Values.image.pullSecrets }}
      imagePullSecrets:
        {{- range .Values.image.pullSecrets }}
        - name: {{ . }}
        {{- end}}
      {{- end}}
      {{- if .Values.nodeSelector }}
      nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
      {{- end }}
      {{- if .Values.gracefulShutdown.enabled }}
      terminationGracePeriodSeconds: {{ .Values.gracefulShutdown.maxWaitSeconds }}
      {{- end }}
      hostNetwork: false
      hostPID: false
      hostIPC: false
      {{- if .Values.securityContext.enabled }}
      securityContext:
        runAsNonRoot: {{ if eq (int .Values.securityContext.runAsUser) 0 }}false{{ else }}true{{ end }}
        runAsUser: {{ .Values.securityContext.runAsUser }}
        runAsGroup: {{ .Values.securityContext.runAsGroup }}
        fsGroup: {{ .Values.securityContext.fsGroup }}
      {{- end }}
      {{- if .Values.affinity }}
      affinity:
{{ toYaml .Values.affinity | indent 8 }}
      {{- end }}
      {{- if .Values.tolerations }}
      tolerations:
{{ toYaml .Values.tolerations | indent 8 }}
      {{- end }}
      containers:
      - name: {{ template "hazelcast.fullname" . }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
        resources:
{{ toYaml .Values.resources | indent 10 }}
        ports:
        - name: hazelcast
          containerPort: {{ if .Values.hostPort }}{{ .Values.hostPort }}{{ else }}5701{{ end }}
          hostPort: {{ .Values.hostPort }}
        {{- if .Values.metrics.enabled }}
        - name: metrics
          containerPort: {{ .Values.metrics.service.port }}
        {{- end }}
        {{- if .Values.livenessProbe.enabled }}
        livenessProbe:
          httpGet:
            path: {{ .Values.livenessProbe.path }}
            port: {{ if .Values.livenessProbe.port }}{{ .Values.livenessProbe.port }}{{ else if .Values.hostPort }}{{ .Values.hostPort }}{{ else }}5701{{ end }}
          initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
          periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
          timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
          successThreshold: {{ .Values.livenessProbe.successThreshold }}
          failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
        {{- end }}
        {{- if .Values.readinessProbe.enabled }}
        readinessProbe:
          httpGet:
            path: {{ .Values.readinessProbe.path }}
            port: {{ if .Values.readinessProbe.port }}{{ .Values.readinessProbe.port }}{{ else if .Values.hostPort }}{{ .Values.hostPort }}{{ else }}5701{{ end }}
          initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
          periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
          timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
          successThreshold: {{ .Values.readinessProbe.successThreshold }}
          failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
        {{- end }}
        volumeMounts:
        - name: hazelcast-storage
          mountPath: /data/hazelcast
        {{- if .Values.customVolume }}
        - name: hazelcast-custom
          mountPath: /data/custom
        {{- end }}
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        {{- if .Values.customVolume }}
        - name: CLASSPATH
          value: "/data/custom:/data/custom/*"
        {{- end }}
        {{- if .Values.metrics.enabled }}
        - name: PROMETHEUS_PORT
          value: "{{ .Values.metrics.service.port }}"
        {{- end }}
        - name: JAVA_OPTS
          value: "-Dhazelcast.config=/data/hazelcast/hazelcast.yaml -DserviceName={{ template "hazelcast.serviceName" . }} -Dnamespace={{ .Release.Namespace }} {{ if .Values.gracefulShutdown.enabled }}-Dhazelcast.shutdownhook.policy=GRACEFUL -Dhazelcast.shutdownhook.enabled=true -Dhazelcast.graceful.shutdown.max.wait={{ .Values.gracefulShutdown.maxWaitSeconds }} {{ end }} {{ if .Values.metrics.enabled }}-Dhazelcast.jmx=true{{ end }} {{ .Values.hazelcast.javaOpts }}"
        {{- if .Values.hazelcast.loggingLevel }}
        - name: LOGGING_LEVEL
          value: {{ .Values.hazelcast.loggingLevel }}
        {{- end }}
        {{- if .Values.securityContext.enabled }}
        securityContext:
          runAsNonRoot: {{ if eq (int .Values.securityContext.runAsUser) 0 }}false{{ else }}true{{ end }}
          runAsUser: {{ .Values.securityContext.runAsUser }}
          runAsGroup: {{ .Values.securityContext.runAsGroup }}
          privileged: false
          readOnlyRootFilesystem: {{ .Values.securityContext.readOnlyRootFilesystem }}
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
        {{- end }}
      serviceAccountName: {{ template "hazelcast.serviceAccountName" . }}
      volumes:
      - name: hazelcast-storage
        configMap:
          {{- if .Values.hazelcast.existingConfigMap }}
          name: {{ .Values.hazelcast.existingConfigMap }}
          {{- else }}
          name: {{ template "hazelcast.fullname" . }}-configuration
          {{- end }}
      {{- if .Values.customVolume }}
      - name: hazelcast-custom
{{ toYaml .Values.customVolume | indent 8 }}
      {{- end }}
 # test-hazelcast.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "{{ template "hazelcast.fullname" . }}-test-{{ randAlphaNum 5 | lower }}"
  annotations:
    "helm.sh/hook": test-success
    "helm.sh/hook-delete-policy": hook-succeeded, hook-failed
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
    app.kubernetes.io/component: "test"
    role: test
spec:
  hostNetwork: false
  hostPID: false
  hostIPC: false
  securityContext:
    runAsNonRoot: true
    runAsUser: 1001
    runAsGroup: 1001
  {{- if .Values.nodeSelector }}
  nodeSelector:
{{ toYaml .Values.nodeSelector | indent 4 }}
  {{- end }}
  containers:
  - name: "{{ template "hazelcast.fullname" . }}-test"
    image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
    command:
    - "bash"
    - "-c"
    - |
      set -ex
      # Get the number of Hazelcast members in the cluster
      CLUSTER_SIZE=$(curl {{ template "hazelcast.fullname" . }}:{{ .Values.service.port }}/hazelcast/health/cluster-size)
      # Test the currect number of Hazelcast members
      test ${CLUSTER_SIZE} -eq {{ .Values.cluster.memberCount }}
    securityContext:
      runAsNonRoot: true
      runAsUser: 1001
      runAsGroup: 1001
      privileged: false
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      capabilities:
        drop:
        - ALL
  restartPolicy: Never # test-management-center.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "{{ template "mancenter.fullname" . }}-test-{{ randAlphaNum 5 | lower }}"
  annotations:
    "helm.sh/hook": test-success
    "helm.sh/hook-delete-policy": hook-succeeded, hook-failed
  labels:
    app.kubernetes.io/name: {{ template "hazelcast.name" . }}
    helm.sh/chart: {{ template "hazelcast.chart" . }}
    app.kubernetes.io/instance: "{{ .Release.Name }}"
    app.kubernetes.io/managed-by: "{{ .Release.Service }}"
    app.kubernetes.io/component: "test"
    role: test
spec:
  hostNetwork: false
  hostPID: false
  hostIPC: false
  securityContext:
    runAsNonRoot: true
    runAsUser: 1001
    runAsGroup: 1001
  {{- if .Values.nodeSelector }}
  nodeSelector:
{{ toYaml .Values.nodeSelector | indent 4 }}
  {{- end }}
  containers:
  - name: "{{ template "mancenter.fullname" . }}-test"
    image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
    command:
    - "bash"
    - "-c"
    - |
      set -ex
      # Get the HTTP Response Code of the Health Check
      HEALTH_CHECK_HTTP_RESPONSE_CODE=$(curl --write-out %{http_code} --silent --output /dev/null {{ template "mancenter.fullname" . }}:{{ .Values.mancenter.service.port }}{{ .Values.mancenter.contextPath }}/health)
      # Test the currect number of Hazelcast members
      test ${HEALTH_CHECK_HTTP_RESPONSE_CODE} -eq 200
    securityContext:
      runAsNonRoot: true
      runAsUser: 1001
      runAsGroup: 1001
      privileged: false
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      capabilities:
        drop:
        - ALL
  restartPolicy: Never
## Hazelcast image version
## ref: https://hub.docker.com/r/hazelcast/hazelcast-kubernetes/tags/
##
image:
  # repository is the Hazelcast image name
  repository: "hazelcast/hazelcast"
  # tag is the Hazelcast image tag
  tag: "4.0.1"
  # pullPolicy is the Docker image pull policy
  # It's recommended to change this to 'Always' if the image tag is 'latest'
  # ref: http://kubernetes.io/docs/user-guide/images/#updating-images
  #
  pullPolicy: IfNotPresent
  # pullSecrets is an array of docker-registry secret names
  # Secrets must be manually created in the namespace.
  # ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
  # pullSecrets:
  # - myRegistryKeySecretName

# Cluster settings
cluster:
  # memberCount is the number Hazelcast members
  memberCount: 3

# Hazelcast properties
hazelcast:
  # javaOpts are additional JAVA_OPTS properties for Hazelcast member
  javaOpts:
  # loggingLevel is the level of Hazelcast logs (SEVERE, WARNING, INFO, CONFIG, FINE, FINER, and FINEST)
  # Note that changing this value requires setting securityContext.runAsUser to 0 and securityContext.readOnlyRootFilesystem to false
  # loggingLevel:
  # existingConfigMap defines a ConfigMap which contains Hazelcast configuration file(s) that are used instead of hazelcast.yaml configuration below
  # existingConfigMap:
  # yaml is the Hazelcast YAML configuration file
  yaml:
    hazelcast:
      network:
        join:
          multicast:
            enabled: false
          kubernetes:
            enabled: true
            service-name: ${serviceName}
            namespace: ${namespace}
            resolve-not-ready-addresses: true
        rest-api:
          enabled: true
          endpoint-groups:
            HEALTH_CHECK:
              enabled: true
  # configurationFiles are any additional Hazelcast configuration files
  # configurationFiles:

# affinity specifies the affinity/anti-affinity of different pods. The commented out
# example below shows how you could ensure your hazelcast pods are scheduled on
# different Kubernetes nodes
affinity:
#  podAntiAffinity:
#    requiredDuringSchedulingIgnoredDuringExecution:
#    - labelSelector:
#        matchExpressions:
#        - key: app.kubernetes.io/name
#          operator: In
#          values:
#          - hazelcast
#        - key: role
#          operator: In
#          values:
#          - hazelcast
#      topologyKey: kubernetes.io/hostname

# tolerations enable Hazelcast PODs to be able to run on nodes with taints
# tolerations:

# nodeSelector is an array of Hazelcast Node labels for POD assignments
# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
nodeSelector: {}

# hostPort is a port under which Hazelcast PODs are exposed on the host machines
# hostPort:

gracefulShutdown:
  enabled: true
  maxWaitSeconds: 600

# Hazelcast Liveness probe
livenessProbe:
  # enabled is a flag to used to enable liveness probe
  enabled: true
  # initialDelaySeconds is a delay before liveness probe is initiated
  initialDelaySeconds: 30
  # periodSeconds decides how often to perform the probe
  periodSeconds: 10
  # timeoutSeconds decides when the probe times out
  timeoutSeconds: 10
  # successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed
  successThreshold: 1
  # failureThreshold is the minimum consecutive failures for the probe to be considered failed after having succeeded
  failureThreshold: 10
  # url path that will be called to check liveness
  path: /hazelcast/health/node-state
  # port that will be used in liveness probe calls
  # port:

# Hazelcast Readiness probe
readinessProbe:
  # enabled is a flag to used to enable readiness probe
  enabled: true
  # initialDelaySeconds is a delay before readiness probe is initiated
  initialDelaySeconds: 30
  # periodSeconds decides how often to perform the probe
  periodSeconds: 10
  # timeoutSeconds decides when the probe times out
  timeoutSeconds: 10
  # successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed
  successThreshold: 1
  # failureThreshold is the minimum consecutive failures for the probe to be considered failed after having succeeded
  failureThreshold: 10
  # url path that will be called to check readiness
  path: /hazelcast/health/ready
  # port that will be used in readiness probe calls
  # port:

# Configure resource requests and limits
# ref: http://kubernetes.io/docs/user-guide/compute-resources/
#
# resources:
#   requests:
#     memory: 256Mi
#     cpu: 100m
#   limits:
#     memory: 1024Mi
#     cpu: 200m

# Hazelcast Service properties
service:
  # Specifies whether a Service should be created
  create: true
  # The name of the Service to use.
  # The name is used for service discovery by Hazelcast K8S discovery plugin.
  # If not set and create is true, a name is generated using the fullname template
  # name:
  # type defines the Kubernetes service type ('ClusterIP', 'LoadBalancer', or 'NodePort')
  type: ClusterIP
  # port is the Kubernetes service port
  port: 5701
  # clusterIP set to None makes the service headless
  # It is required if DNS Lookup is used (https://github.com/hazelcast/hazelcast-kubernetes#dns-lookup)
  clusterIP: "None"


# Role-based Access Control
rbac:
  # Specifies whether RBAC resources should be created
  # It is not required if DNS Lookup is used (https://github.com/hazelcast/hazelcast-kubernetes#dns-lookup)
  create: true

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:

# Security Context properties
securityContext:
  # enabled is a flag to enable Security Context
  enabled: true
  # runAsUser is the user ID used to run the container
  runAsUser: 65534
  # runAsGroup is the primary group ID used to run all processes within any container of the pod
  runAsGroup: 65534
  # fsGroup is the group ID associated with the container
  fsGroup: 65534
  # readOnlyRootFilesystem is a flag to enable readOnlyRootFilesystem for the Hazelcast security context
  readOnlyRootFilesystem: true

# Allows to enable a Prometheus to scrape pods, implemented for Hazelcast version >= 3.12 (or 'latest')
metrics:
  enabled: false
  service:
    type: ClusterIP
    port: 8080
    annotations:
      prometheus.io/scrape: "true"
      prometheus.io/path: "/metrics"
      prometheus.io/port: "8080"

# customVolume is the configuration for any volume mounted as '/data/custom/' (e.g. to mount a volume with custom JARs)
# customVolume:

# Hazelcast Management Center application properties
mancenter:
  # enabled is a flag to enable Management Center application
  enabled: true
  ## Hazelcast Management Center image version
  ## ref: https://hub.docker.com/r/hazelcast/management-center/tags/
  ##
  image:
    # repository is the Hazelcast Management Center image name
    repository: "hazelcast/management-center"
    # tag is the Hazelcast Management Center image tag
    tag: "4.0.2"
    # pullPolicy is the Docker image pull policy
    # It's recommended to change this to 'Always' if the image tag is 'latest'
    # ref: http://kubernetes.io/docs/user-guide/images/#updating-images
    #
    pullPolicy: IfNotPresent
    # pullSecrets is an array of docker-registry secret names
    # Secrets must be manually created in the namespace.
    # ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
    # pullSecrets:
    # - myRegistryKeySecretName

  # ingress configuration for mancenter
  ingress:
    enabled: false
    annotations: {}
    # hosts:
    # - hazelcast-mancenter.cluster.domain
    # tls:
    # - secretName: hazelcast-ingress-tls
    #   hosts:
    #   - hazelcast-mancenter.cluster.domain

  # ssl is a flag to enable SSL for Management Center
  ssl: false
  # javaOpts are additional JAVA_OPTS properties for Hazelcast Management Center
  javaOpts:

  # contextPath is the value for the MC_CONTEXT_PATH environment variable, thus overriding the default context path for Hazelcast Management Center
  # ref: https://hub.docker.com/r/hazelcast/management-center/
  contextPath:

  # licenseKey is the license key for Hazelcast Management Center
  # if not provided, it can be filled in the Management Center web interface
  licenseKey:
  # licenseKeySecretName is the name of the secret where the Hazelcast Management Center License Key is stored (can be used instead of licenseKey)
  # licenseKeySecretName:

  # existingConfigMap defines a ConfigMap which contains Hazelcast Client configuration file(s) that are used instead of hazelcast-client.yaml configuration below
  # existingConfigMap:
  # yaml is the Hazelcast Client YAML configuration file
  yaml:
    hazelcast-client:
      network:
        cluster-members:
          - ${serviceName}

  # affinity specifies the Management Center affinity/anti-affinity of different pods
  # affinity:

  # tolerations enable Management Center POD to be able to run on nodes with taints
  # tolerations:

  # nodeSelector is an array of Hazelcast Management Center Node labels for POD assignments
  # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
  nodeSelector: {}

  # Configure resource requests and limits
  # ref: http://kubernetes.io/docs/user-guide/compute-resources/
  #
  # resources:
  #   requests:
  #     memory: 256Mi
  #     cpu: 100m
  #   limits:
  #     memory: 1024Mi
  #     cpu: 200m

  # Management Center persistence properties
  persistence:
    # enabled is a flag to enable persistence for Management Center
    enabled: true
    # existingClaim is a name of the existing Persistence Volume Claim that will be used for persistence
    # if not defined, a new Persistent Value Claim is created with the default name
    # existingClaim:
    # accessModes defines the access modes for the created Persistent Volume Claim
    accessModes:
    - ReadWriteOnce
    # size is the size of Persistent Volume Claim
    size: 8Gi

  # Hazelcast Management Center Service properties
  service:
    # type defines the Kubernetes service type ('ClusterIP', 'LoadBalancer', or 'NodePort')
    type: LoadBalancer
    # port is the Kubernetes service port
    port: 8080
    # service https port
    httpsPort: 443
    # service annotations for management center
    annotations: {}

  # Hazelcast Management Center Liveness probe
  livenessProbe:
    # enabled is a flag to used to enable liveness probe
    enabled: true
    # initialDelaySeconds is a delay before liveness probe is initiated
    initialDelaySeconds: 30
    # periodSeconds decides how often to perform the probe
    periodSeconds: 10
    # timeoutSeconds decides when the probe times out
    timeoutSeconds: 5
    # successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed
    successThreshold: 1
    # failureThreshold is the minimum consecutive failures for the probe to be considered failed after having succeeded
    failureThreshold: 3
  # Hazelcast Management Center Readiness probe
  readinessProbe:
    # enabled is a flag to used to enable readiness probe
    enabled: true
    # initialDelaySeconds is a delay before readiness probe is initiated
    initialDelaySeconds: 30
    # periodSeconds decides how often to perform the probe
    periodSeconds: 10
    # timeoutSeconds decides when the probe times out
    timeoutSeconds: 1
    # successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed
    successThreshold: 1
    # failureThreshold is the minimum consecutive failures for the probe to be considered failed after having succeeded
    failureThreshold: 3

  # secretsMountName is the secret name that is mounted as '/data/secrets/' (e.g. with keystore/trustore files)
  # secretsMountName:
