# _helpers.tpl
{{/* vim: set filetype=mustache: */}}

{{/*
Expand the name of the chart.
*/}}
{{- define "nats.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).
*/}}
{{- define "nats.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 -}}

{{- define "nats.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Return the proper Nats image name
*/}}
{{- define "nats.image" -}}
{{- $registryName := .Values.image.registry -}}
{{- $repositoryName := .Values.image.repository -}}
{{- $tag := .Values.image.tag | toString -}}
{{/*
Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic.
Also, we can't use a single if because lazy evaluation is not an option
*/}}
{{- if .Values.global }}
    {{- if .Values.global.imageRegistry }}
        {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}}
    {{- else -}}
        {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
    {{- end -}}
{{- else -}}
    {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
{{- end -}}

{{/*
Create a random alphanumeric password string.
We prepend a random letter to the string to avoid password validation errors
*/}}
{{- define "nats.randomPassword" -}}
{{- randAlpha 1 -}}{{- randAlphaNum 9 -}}
{{- end -}}

{{/*
Return the appropriate apiVersion for networkpolicy.
*/}}
{{- define "networkPolicy.apiVersion" -}}
{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.GitVersion -}}
{{- print "extensions/v1beta1" -}}
{{- else -}}
{{- print "networking.k8s.io/v1" -}}
{{- end -}}
{{- end -}}

{{/*
Return the proper image name (for the metrics image)
*/}}
{{- define "nats.metrics.image" -}}
{{- $registryName := .Values.metrics.image.registry -}}
{{- $repositoryName := .Values.metrics.image.repository -}}
{{- $tag := .Values.metrics.image.tag | toString -}}
{{/*
Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic.
Also, we can't use a single if because lazy evaluation is not an option
*/}}
{{- if .Values.global }}
    {{- if .Values.global.imageRegistry }}
        {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}}
    {{- else -}}
        {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
    {{- end -}}
{{- else -}}
    {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
{{- end -}}

{{/*
Return the proper Docker Image Registry Secret Names
*/}}
{{- define "nats.imagePullSecrets" -}}
{{/*
Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic.
Also, we can not use a single if because lazy evaluation is not an option
*/}}
{{- if .Values.global }}
{{- if .Values.global.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.global.imagePullSecrets }}
  - name: {{ . }}
{{- end }}
{{- else if or .Values.image.pullSecrets .Values.metrics.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.image.pullSecrets }}
  - name: {{ . }}
{{- end }}
{{- range .Values.metrics.image.pullSecrets }}
  - name: {{ . }}
{{- end }}
{{- end -}}
{{- else if or .Values.image.pullSecrets .Values.metrics.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.image.pullSecrets }}
  - name: {{ . }}
{{- end }}
{{- range .Values.metrics.image.pullSecrets }}
  - name: {{ . }}
{{- end }}
{{- end -}}
{{- end -}}

{{/*
Compile all warnings into a single message, and call fail.
*/}}
{{- define "nats.validateValues" -}}
{{- $messages := list -}}
{{- $messages := append $messages (include "nats.validateValues.resourceType" .) -}}
{{- $messages := without $messages "" -}}
{{- $message := join "\n" $messages -}}

{{- if $message -}}
{{-   printf "\nVALUES VALIDATION:\n%s" $message | fail -}}
{{- end -}}
{{- end -}}

{{/* Validate values of NATS - must provide a valid resourceType ("deployment" or "statefulset") */}}
{{- define "nats.validateValues.resourceType" -}}
{{- if and (ne .Values.resourceType "deployment") (ne .Values.resourceType "statefulset") -}}
nats: resourceType
    Invalid resourceType selected. Valid values are "deployment" and
    "statefulset". Please set a valid mode (--set resourceType="xxxx")
{{- end -}}
{{- end -}}
 # client-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ template "nats.fullname" . }}-client
  labels:
    app: "{{ template "nats.name" . }}"
    chart: "{{ template "nats.chart" . }}"
    release: {{ .Release.Name | quote }}
    heritage: {{ .Release.Service | quote }}
  {{- if .Values.client.service.annotations }}
  annotations:
{{ toYaml .Values.client.service.annotations | indent 4 }}
  {{- end }}
spec:
  type: {{ .Values.client.service.type }}
  {{- if and (eq .Values.client.service.type "LoadBalancer") .Values.client.service.loadBalancerIP }}
  loadBalancerIP: {{ .Values.client.service.loadBalancerIP }}
  {{- end }}
  ports:
    - port: {{ .Values.client.service.port }}
      targetPort: client
      name: client
      {{- if and (eq .Values.client.service.type "NodePort") (not (empty .Values.client.service.nodePort)) }}
      nodePort: {{ .Values.client.service.nodePort  }}
      {{- end }}
  selector:
    app: "{{ template "nats.name" . }}"
    release: {{ .Release.Name | quote }}
 # cluster-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ template "nats.fullname" . }}-cluster
  labels:
    app: "{{ template "nats.name" . }}"
    chart: "{{ template "nats.chart" . }}"
    release: {{ .Release.Name | quote }}
    heritage: {{ .Release.Service | quote }}
  {{- if .Values.cluster.service.annotations }}
  annotations:
{{ toYaml .Values.cluster.service.annotations | indent 4 }}
  {{- end }}
spec:
  type: {{ .Values.cluster.service.type }}
  {{- if and (eq .Values.cluster.service.type "LoadBalancer") .Values.cluster.service.loadBalancerIP }}
  loadBalancerIP: {{ .Values.cluster.service.loadBalancerIP }}
  {{- end }}
  ports:
    - port: {{ .Values.cluster.service.port }}
      targetPort: cluster
      name: cluster
      {{- if and (eq .Values.cluster.service.type "NodePort") (not (empty .Values.cluster.service.nodePort)) }}
      nodePort: {{ .Values.cluster.service.nodePort  }}
      {{- end }}
  selector:
    app: "{{ template "nats.name" . }}"
    release: {{ .Release.Name | quote }}
 # configmap.yaml
{{- $authPwd := default (include "nats.randomPassword" .) .Values.auth.password -}}
{{- $clusterAuthPwd := default (include "nats.randomPassword" .) .Values.clusterAuth.password -}}
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app: "{{ template "nats.name" . }}"
    chart: "{{ template "nats.chart" . }}"
    heritage: {{ .Release.Service | quote }}
    release: {{ .Release.Name | quote }}
  name: {{ template "nats.fullname" . }}
data:
  {{ .Values.natsFilename }}.conf: |-
    listen: 0.0.0.0:{{ .Values.client.service.port }}
    http: 0.0.0.0:{{ .Values.monitoring.service.port }}

    # Authorization for client connections
    {{- if .Values.auth.enabled }}
    authorization {
      {{- if .Values.auth.user }}
      user: {{ .Values.auth.user }}
      password: {{ $authPwd }}
      {{- else if .Values.auth.token }}
      token: {{ .Values.auth.token }}
      {{- end }}
      timeout:  1
    }
    {{- end }}

    # Logging options
    debug: {{ .Values.debug.enabled }}
    trace: {{ .Values.debug.trace }}
    logtime: {{ .Values.debug.logtime }}

    # Pid file
    pid_file: "/tmp/{{ .Values.natsFilename }}.pid"

    # Some system overides
    {{- if .Values.maxConnections }}
    max_connections: {{ int .Values.maxConnections }}
    {{- end }}
    {{- if .Values.maxControlLine }}
    max_control_line: {{ int .Values.maxControlLine }}
    {{- end }}
    {{- if .Values.maxPayload }}
    max_payload: {{ int .Values.maxPayload }}
    {{- end }}
    {{- if .Values.writeDeadline }}
    write_deadline: {{ .Values.writeDeadline | quote }}
    {{- end }}


    # Clustering definition
    cluster {
      listen: 0.0.0.0:{{ .Values.cluster.service.port }}

      # Authorization for cluster connections
      {{- if .Values.clusterAuth.enabled }}
      authorization {
        {{- if .Values.clusterAuth.user }}
        user: {{ .Values.clusterAuth.user }}
        password: {{ $clusterAuthPwd }}
        {{- else if .Values.clusterAuth.token }}
        token: {{ .Values.clusterAuth.token }}
        {{- end }}
        timeout:  1
      }
      {{- end }}

      # Routes are actively solicited and connected to from this server.
      # Other servers can connect to us if they supply the correct credentials
      # in their routes definitions from above
      routes = [
        {{- if .Values.clusterAuth.enabled }}
        {{- if .Values.clusterAuth.user }}
        nats://{{ .Values.clusterAuth.user }}:{{ $clusterAuthPwd }}@{{ template "nats.fullname" . }}-cluster:{{ .Values.cluster.service.port }}
        {{- else if .Values.clusterAuth.token }}
        nats://{{ .Values.clusterAuth.token }}@{{ template "nats.fullname" . }}-cluster:{{ .Values.cluster.service.port }}
        {{- end }}
        {{- else }}
        nats://{{ template "nats.fullname" . }}-cluster:{{ .Values.cluster.service.port }}
        {{- end }}
      ]

      {{- if .Values.cluster.connectRetries }}
      # Configure number of connect retries for implicit routes
      connect_retries: {{ .Values.cluster.connectRetries }}
      {{- end }}
    }
 # deployment.yaml
{{- if eq .Values.resourceType "deployment" }}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ template "nats.fullname" . }}
  labels:
    app: "{{ template "nats.name" . }}"
    chart: "{{ template "nats.chart" . }}"
    release: {{ .Release.Name | quote }}
    heritage: {{ .Release.Service | quote }}
spec:
  replicas: {{ .Values.replicaCount }}
  strategy:
    rollingUpdate:
      maxSurge: {{ .Values.deployment.maxSurge }}
      maxUnavailable: {{ .Values.deployment.maxUnavailable }}
    type: {{ .Values.deployment.updateType }}
  selector:
    matchLabels:
      app: "{{ template "nats.name" . }}"
      release: {{ .Release.Name | quote }}
  template:
    metadata:
      labels:
        app: "{{ template "nats.name" . }}"
        chart: "{{ template "nats.chart" . }}"
        release: {{ .Release.Name | quote }}
        {{- if .Values.podLabels }}
{{ toYaml .Values.podLabels | indent 8 }}
        {{- end }}
{{- if or .Values.podAnnotations .Values.metrics.enabled }}
      annotations:
{{- if .Values.podAnnotations }}
{{ toYaml .Values.podAnnotations | indent 8 }}
{{- end }}
{{- if .Values.metrics.podAnnotations }}
{{ toYaml .Values.metrics.podAnnotations | indent 8 }}
{{- end }}
{{- end }}
    spec:
{{- include "nats.imagePullSecrets" . | indent 6 }}
      {{- if .Values.securityContext.enabled }}
      securityContext:
        fsGroup: {{ .Values.securityContext.fsGroup }}
        runAsUser: {{ .Values.securityContext.runAsUser }}
      {{- end }}
      {{- if .Values.priorityClassName }}
      priorityClassName: {{ .Values.priorityClassName | quote }}
      {{- end }}
      {{- if .Values.nodeSelector }}
      nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
      {{- end }}
      {{- if .Values.tolerations }}
      tolerations:
{{ toYaml .Values.tolerations | indent 8 }}
      {{- end }}
      {{- if .Values.schedulerName }}
      schedulerName: {{ .Values.schedulerName | quote }}
      {{- end }}
      {{- if eq .Values.antiAffinity "hard" }}
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - topologyKey: "kubernetes.io/hostname"
              labelSelector:
                matchLabels:
                  app: "{{ template "nats.name" . }}"
                  release: {{ .Release.Name | quote }}
      {{- else if eq .Values.antiAffinity "soft" }}
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            podAffinityTerm:
              topologyKey: kubernetes.io/hostname
              labelSelector:
                matchLabels:
                  app: "{{ template "nats.name" . }}"
                  release: {{ .Release.Name | quote }}
      {{- end }}
      containers:
      - name: {{ template "nats.name" . }}
        image: {{ template "nats.image" . }}
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        command:
        - {{ .Values.natsFilename }}
        args:
        - -c
        - /opt/bitnami/nats/{{ .Values.natsFilename }}.conf
        # to ensure nats could run with non-root user, we put the configuration
        # file under `/opt/bitnami/nats/{{ .Values.natsFilename }}.conf`, please check the link below
        # for the implementation inside Dockerfile:
        # - https://github.com/bitnami/bitnami-docker-nats#configuration
        {{- if .Values.extraArgs }}
{{ toYaml .Values.extraArgs | indent 8 }}
        {{- end }}
        ports:
        - name: client
          containerPort: {{ .Values.client.service.port }}
        - name: cluster
          containerPort: {{ .Values.cluster.service.port }}
        - name: monitoring
          containerPort: {{ .Values.monitoring.service.port }}
        {{- if .Values.livenessProbe.enabled }}
        livenessProbe:
          httpGet:
            path: /
            port: monitoring
          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: /
            port: monitoring
          initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
          periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
          timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
          successThreshold: {{ .Values.readinessProbe.successThreshold }}
          failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
        {{- end }}
        resources:
{{ toYaml .Values.resources | indent 10 }}
        volumeMounts:
          - name: config
            mountPath: /opt/bitnami/nats/{{ .Values.natsFilename }}.conf
            subPath: {{ .Values.natsFilename }}.conf
        {{- if .Values.sidecars }}
{{ toYaml .Values.sidecars | indent 6 }}
        {{- end }}
{{- if .Values.metrics.enabled }}
      - name: metrics
        image: {{ template "nats.metrics.image" . }}
        imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }}
        args: {{- toYaml .Values.metrics.args | nindent 10 }}
          - "http://localhost:{{ .Values.monitoring.service.port }}"
        ports:
        - name: metrics
          containerPort: {{ .Values.metrics.port }}
        livenessProbe:
          httpGet:
            path: /metrics
            port: metrics
          initialDelaySeconds: 15
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            path: /metrics
            port: metrics
          initialDelaySeconds: 5
          timeoutSeconds: 1
        resources:
{{ toYaml .Values.metrics.resources | indent 10 }}
{{- end }}
      volumes:
      - name: config
        configMap:
          name: {{ template "nats.fullname" . }}
{{- end }}
 # headless-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ template "nats.fullname" . }}-headless
  labels:
    app: {{ template "nats.name" . }}
    chart: {{ template "nats.chart" . }}
    release: "{{ .Release.Name }}"
    heritage: "{{ .Release.Service }}"
spec:
  type: ClusterIP
  clusterIP: None
  ports:
  - name: client
    port: {{ .Values.client.service.port }}
    targetPort: client
  - name: cluster
    port: {{ .Values.cluster.service.port }}
    targetPort: cluster
  selector:
    app: {{ template "nats.name" . }}
    release: {{ .Release.Name | quote }}
 # ingress.yaml
{{- if .Values.ingress.enabled -}}
{{- range .Values.ingress.hosts }}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ template "nats.fullname" $ }}-monitoring
  labels:
    app: "{{ template "nats.name" $ }}"
    chart: "{{ template "nats.chart" $ }}"
    release: {{ $.Release.Name | quote }}
    heritage: {{ $.Release.Service | quote }}
  annotations:
    {{- if .tls }}
    ingress.kubernetes.io/secure-backends: "true"
    {{- end }}
    {{- range $key, $value := .annotations }}
    {{ $key }}: {{ $value | quote }}
    {{- end }}
spec:
  rules:
    - host: {{ .name }}
      http:
        paths:
        - path: {{ default "/" .path }}
          backend:
            serviceName: {{ template "nats.fullname" $ }}-monitoring
            servicePort: monitoring
{{- if .tls }}
  tls:
  - hosts:
    - {{ .name }}
    secretName: {{ .tlsSecret }}
{{- end }}
---
{{- end }}
{{- end }}
 # monitoring-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ template "nats.fullname" . }}-monitoring
  labels:
    app: "{{ template "nats.name" . }}"
    chart: "{{ template "nats.chart" . }}"
    release: {{ .Release.Name | quote }}
    heritage: {{ .Release.Service | quote }}
  {{- if .Values.monitoring.service.annotations }}
  annotations:
{{ toYaml .Values.monitoring.service.annotations | indent 4 }}
  {{- end }}
spec:
  type: {{ .Values.monitoring.service.type }}
  {{- if and (eq .Values.monitoring.service.type "LoadBalancer") .Values.monitoring.service.loadBalancerIP }}
  loadBalancerIP: {{ .Values.monitoring.service.loadBalancerIP }}
  {{- end }}
  ports:
    - port: {{ .Values.monitoring.service.port }}
      targetPort: monitoring
      name: monitoring
      {{- if and (eq .Values.monitoring.service.type "NodePort") (not (empty .Values.monitoring.service.nodePort)) }}
      nodePort: {{ .Values.monitoring.service.nodePort  }}
      {{- end }}
  selector:
    app: "{{ template "nats.name" . }}"
    release: {{ .Release.Name | quote }}
 # networkpolicy.yaml
{{- if .Values.networkPolicy.enabled }}
kind: NetworkPolicy
apiVersion: {{ template "networkPolicy.apiVersion" . }}
metadata:
  name: {{ template "nats.fullname" . }}
  labels:
    app: "{{ template "nats.name" . }}"
    chart: "{{ template "nats.chart" . }}"
    release: {{ .Release.Name | quote }}
    heritage: {{ .Release.Service | quote }}
spec:
  podSelector:
    matchLabels:
      app: "{{ template "nats.name" . }}"
      release: {{ .Release.Name | quote }}
  ingress:
    # Allow inbound connections
    - ports:
      - port: {{ .Values.client.service.port }}
      {{- if not .Values.networkPolicy.allowExternal }}
      from:
        - podSelector:
            matchLabels:
              {{ template "nats.fullname" . }}-client: "true"
      {{- end }}
    - ports:
      - port: {{ .Values.cluster.service.port }}
    - ports:
      - port: {{ .Values.monitoring.service.port }}
{{- end }}
 # statefulset.yaml
{{- if or (eq .Values.resourceType "statefulset") (not (contains .Values.resourceType "deployment")) }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ template "nats.fullname" . }}
  labels:
    app: "{{ template "nats.name" . }}"
    chart: "{{ template "nats.chart" . }}"
    release: {{ .Release.Name | quote }}
    heritage: {{ .Release.Service | quote }}
spec:
  serviceName: {{ template "nats.fullname" . }}-headless
  replicas: {{ .Values.replicaCount }}
  updateStrategy:
    type: {{ .Values.statefulset.updateStrategy }}
    {{- if (eq "Recreate" .Values.statefulset.updateStrategy) }}
    rollingUpdate: null
    {{- else }}
    {{- if .Values.statefulset.rollingUpdatePartition }}
    rollingUpdate:
      partition: {{ .Values.statefulset.rollingUpdatePartition }}
    {{- end }}
    {{- end }}
  selector:
    matchLabels:
      app: "{{ template "nats.name" . }}"
      release: {{ .Release.Name | quote }}
  template:
    metadata:
      labels:
        app: "{{ template "nats.name" . }}"
        chart: "{{ template "nats.chart" . }}"
        release: {{ .Release.Name | quote }}
        {{- if .Values.podLabels }}
{{ toYaml .Values.podLabels | indent 8 }}
        {{- end }}
{{- if or .Values.podAnnotations .Values.metrics.enabled }}
      annotations:
{{- if .Values.podAnnotations }}
{{ toYaml .Values.podAnnotations | indent 8 }}
{{- end }}
{{- if .Values.metrics.podAnnotations }}
{{ toYaml .Values.metrics.podAnnotations | indent 8 }}
{{- end }}
{{- end }}
    spec:
{{- include "nats.imagePullSecrets" . | indent 6 }}
      {{- if .Values.securityContext.enabled }}
      securityContext:
        fsGroup: {{ .Values.securityContext.fsGroup }}
        runAsUser: {{ .Values.securityContext.runAsUser }}
      {{- end }}
      {{- if .Values.priorityClassName }}
      priorityClassName: {{ .Values.priorityClassName | quote }}
      {{- end }}
      {{- if .Values.nodeSelector }}
      nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
      {{- end }}
      {{- if .Values.tolerations }}
      tolerations:
{{ toYaml .Values.tolerations | indent 8 }}
      {{- end }}
      {{- if .Values.schedulerName }}
      schedulerName: {{ .Values.schedulerName | quote }}
      {{- end }}
      {{- if eq .Values.antiAffinity "hard" }}
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - topologyKey: "kubernetes.io/hostname"
              labelSelector:
                matchLabels:
                  app: "{{ template "nats.name" . }}"
                  release: {{ .Release.Name | quote }}
      {{- else if eq .Values.antiAffinity "soft" }}
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            podAffinityTerm:
              topologyKey: kubernetes.io/hostname
              labelSelector:
                matchLabels:
                  app: "{{ template "nats.name" . }}"
                  release: {{ .Release.Name | quote }}
      {{- end }}
      containers:
      - name: {{ template "nats.name" . }}
        image: {{ template "nats.image" . }}
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        command:
        - {{ .Values.natsFilename }}
        args:
        - -c
        - /opt/bitnami/nats/{{ .Values.natsFilename }}.conf
        # to ensure nats could run with non-root user, we put the configuration
        # file under `/opt/bitnami/nats/{{ .Values.natsFilename }}.conf`, please check the link below
        # for the implementation inside Dockerfile:
        # - https://github.com/bitnami/bitnami-docker-nats#configuration
        {{- if .Values.extraArgs }}
{{ toYaml .Values.extraArgs | indent 8 }}
        {{- end }}
        ports:
        - name: client
          containerPort: {{ .Values.client.service.port }}
        - name: cluster
          containerPort: {{ .Values.cluster.service.port }}
        - name: monitoring
          containerPort: {{ .Values.monitoring.service.port }}
        {{- if .Values.livenessProbe.enabled }}
        livenessProbe:
          httpGet:
            path: /
            port: monitoring
          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: /
            port: monitoring
          initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
          periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
          timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
          successThreshold: {{ .Values.readinessProbe.successThreshold }}
          failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
        {{- end }}
        resources:
{{ toYaml .Values.resources | indent 10 }}
        volumeMounts:
          - name: config
            mountPath: /opt/bitnami/nats/{{ .Values.natsFilename }}.conf
            subPath: {{ .Values.natsFilename }}.conf
        {{- if .Values.sidecars }}
{{ toYaml .Values.sidecars | indent 6 }}
        {{- end }}
{{- if .Values.metrics.enabled }}
      - name: metrics
        image: {{ template "nats.metrics.image" . }}
        imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }}
        args: {{- toYaml .Values.metrics.args | nindent 10 }}
          - "http://localhost:{{ .Values.monitoring.service.port }}"
        ports:
        - name: metrics
          containerPort: {{ .Values.metrics.port }}
        livenessProbe:
          httpGet:
            path: /metrics
            port: metrics
          initialDelaySeconds: 15
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            path: /metrics
            port: metrics
          initialDelaySeconds: 5
          timeoutSeconds: 1
        resources:
{{ toYaml .Values.metrics.resources | indent 10 }}
{{- end }}
      volumes:
      - name: config
        configMap:
          name: {{ template "nats.fullname" . }}
{{- end }}
 # tls-secret.yaml
{{- if .Values.ingress.enabled }}
{{- range .Values.ingress.secrets }}
apiVersion: v1
kind: Secret
metadata:
  name: {{ .name }}
  labels:
    app: "{{ template "nats.name" $ }}"
    chart: "{{ template "nats.chart" $ }}"
    release: {{ $.Release.Name | quote }}
    heritage: {{ $.Release.Service | quote }}
type: kubernetes.io/tls
data:
  tls.crt: {{ .certificate | b64enc }}
  tls.key: {{ .key | b64enc }}
---
{{- end }}
{{- end }}

## Global Docker image parameters
## Please, note that this will override the image parameters, including dependencies, configured to use the global value
## Current available global Docker image parameters: imageRegistry and imagePullSecrets
##
# global:
#   imageRegistry: myRegistryName
#   imagePullSecrets:
#     - myRegistryKeySecretName

## Bitnami NATS image version
## ref: https://hub.docker.com/r/bitnami/nats/tags/
##
image:
  registry: docker.io
  repository: bitnami/nats
  tag: 2.1.4-debian-10-r24
  ## Specify a imagePullPolicy
  ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent'
  ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
  ##
  pullPolicy: IfNotPresent
  ## Optionally specify an array of imagePullSecrets.
  ## Secrets must be manually created in the namespace.
  ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
  ##
  # pullSecrets:
  #   - name: myRegistryKeySecretName

## String to partially override nats.fullname template (will maintain the release name)
##
# nameOverride:

## String to fully override nats.fullname template
##
# fullnameOverride:

## NATS replicas
replicaCount: 1

## NATS Pod Security Context
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
##
securityContext:
  enabled: true
  fsGroup: 1001
  runAsUser: 1001

## NATS Node selector and tolerations for pod assignment
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature
##
# nodeSelector: {"beta.kubernetes.io/arch": "amd64"}
# tolerations: []

## Use an alternate scheduler, e.g. "stork".
## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/
##
# schedulerName:

## Pods anti-affinity
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
##
antiAffinity: soft

## Pod annotations
## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
##
podAnnotations: {}

## Additional pod labels
## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
##
podLabels: {}

## Pod Priority Class
## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
##
# priorityClassName: ""

## NATS cluster resource type under Kubernetes. Allowed values: statefulset (default) or deployment
## ref:
## - https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
## - https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
resourceType: "statefulset"

## Update strategy for statefulset, can be set to RollingUpdate or OnDelete by default.
## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets
statefulset:
  updateStrategy: OnDelete
  ## Partition update strategy
  ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions
  # rollingUpdatePartition:

## Update strategy for deployment, can be set to RollingUpdate or OnDelete by default.
## https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
deployment:
  updateType: RollingUpdate
  # maxSurge: 25%
  # maxUnavailable: 25%

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

## Configure extra options for liveness and readiness probes
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes)
livenessProbe:
  enabled: true
  initialDelaySeconds: 30
  periodSeconds: 10
  timeoutSeconds: 5
  failureThreshold: 6
  successThreshold: 1
readinessProbe:
  enabled: true
  initialDelaySeconds: 5
  periodSeconds: 10
  timeoutSeconds: 5
  failureThreshold: 6
  successThreshold: 1

## Client Authentication
## ref: https://github.com/nats-io/gnatsd#authentication
##
auth:
  enabled: true
  user: nats_client
  # password:
  # token:

## Cluster Authentication
## ref: https://github.com/nats-io/gnatsd#authentication
##
clusterAuth:
  enabled: true
  user: nats_cluster
  # password:
  # token:

## Logging parameters
## ref: https://github.com/nats-io/gnatsd#command-line-arguments
##
debug:
  enabled: false
  trace: false
  logtime: false

## System overrides parameters
## ref: https://github.com/nats-io/gnatsd#configuration-file
##
# maxConnections: 100
# maxControlLine: 512
# maxPayload: 65536
# writeDeadline: "2s"

## Network pullPolicy
## https://kubernetes.io/docs/concepts/services-networking/network-policies/
##
networkPolicy:
  ## Enable creation of NetworkPolicy resources.
  enabled: false

  ## The Policy model to apply. When set to false, only pods with the correct
  ## client labels will have network access to the port NATS is listening
  ## on. When true, NATS will accept connections from any source
  ## (with the correct destination port).
  ##
  allowExternal: true

## NATS svc used for client connections
## ref: https://github.com/nats-io/gnatsd#running
##
client:
  service:
    ## Kubernetes service type
    type: ClusterIP
    port: 4222
    ## Specify the nodePort value for the LoadBalancer and NodePort service types.
    ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
    ##
    # nodePort:
    ## Provide any additional annotations which may be required. This can be used to
    ## set the LoadBalancer service type to internal only.
    ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer
    ##
    annotations: {}
    ## Use loadBalancerIP to request a specific static IP,
    ## otherwise leave blank
    ##
    # loadBalancerIP:

## Kubernetes svc used for clustering
## ref: https://github.com/nats-io/gnatsd#clustering
##
cluster:
  ## Use connectRetries to configure number of connect retries for implicit routes,
  ## otherwise leave blank
  ##
  # connectRetries:
  service:
    ## Kubernetes service type
    type: ClusterIP
    port: 6222
    ## Specify the nodePort value for the LoadBalancer and NodePort service types.
    ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
    ##
    # nodePort:
    ## Provide any additional annotations which may be required. This can be used to
    ## set the LoadBalancer service type to internal only.
    ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer
    ##
    annotations: {}
    ## Use loadBalancerIP to request a specific static IP,
    ## otherwise leave blank
    ##
    # loadBalancerIP:

## NATS svc used for monitoring
## ref: https://github.com/nats-io/gnatsd#monitoring
##
monitoring:
  service:
    ## Kubernetes service type
    type: ClusterIP
    port: 8222
    ## Specify the nodePort value for the LoadBalancer and NodePort service types.
    ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
    ##
    # nodePort:
    ## Provide any additional annotations which may be required. This can be used to
    ## set the LoadBalancer service type to internal only.
    ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer
    ##
    annotations: {}
    ## Use loadBalancerIP to request a specific static IP,
    ## otherwise leave blank
    ##
    loadBalancerIP:

## Configure the ingress resource that allows you to access the
## NATS Monitoring. Set up the URL
## ref: http://kubernetes.io/docs/user-guide/ingress/
##
ingress:
  enabled: false
  # The list of hostnames to be covered with this ingress record.
  # Most likely this will be just one host, but in the event more hosts are needed, this is an array
  hosts:
  - name: nats.local

    ## Set this to true in order to enable TLS on the ingress record
    tls: false

    ## If TLS is set to true, you must declare what secret will store the key/certificate for TLS
    tlsSecret: nats.local-tls

    ## Ingress annotations done as key:value pairs
    ## If you're using kube-lego, you will want to add:
    ## kubernetes.io/tls-acme: true
    ##
    ## For a full list of possible ingress annotations, please see
    ## ref: https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md
    ##
    ## If tls is set to true, annotation ingress.kubernetes.io/secure-backends: "true" will automatically be set
    annotations:
    #  kubernetes.io/ingress.class: nginx
    #  kubernetes.io/tls-acme: true

  secrets:
  ## If you're providing your own certificates, please use this to add the certificates as secrets
  ## key and certificate should start with -----BEGIN CERTIFICATE----- or
  ## -----BEGIN RSA PRIVATE KEY-----
  ##
  ## name should line up with a tlsSecret set further up
  ## If you're using kube-lego, this is unneeded, as it will create the secret for you if it is not set
  ##
  ## It is also possible to create and manage the certificates outside of this helm chart
  ## Please see README.md for more information
  # - name: nats.local-tls
  #   key:
  #   certificate:

# Optional additional arguments
extraArgs: []

## Nats filenames:
##  - For Nats 1.x.x version, some filenames (binary, configuration file, pid file) uses `gnatsd` as part of the name.
##  - For Nats 2.x.x version, those filenames now uses `nats-server`
## In order to make the chart compatible with NATS versions 1.0.0 and 2.0.0 we have parametrized the following value
## to specify the proper filename according to the image version.
##
natsFilename: nats-server

## Metrics / Prometheus NATS Exporter
##
## ref: https://github.com/nats-io/prometheus-nats-exporter
metrics:
  enabled: false
  image:
    registry: docker.io
    repository: bitnami/nats-exporter
    tag: 0.6.0-debian-10-r28
    pullPolicy: IfNotPresent
    ## Optionally specify an array of imagePullSecrets.
    ## Secrets must be manually created in the namespace.
    ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
    ##
    # pullSecrets:
    #   - myRegistryKeySecretName
  ## Metrics exporter resource requests and limits
  ## ref: http://kubernetes.io/docs/user-guide/compute-resources/
  ##
  # resources: {}
  ## Metrics exporter port
  port: 7777
  ## Metrics exporter annotations
  podAnnotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "7777"
  ## Metrics exporter flags
  args:
    - -connz
    - -routez
    - -subz
    - -varz

sidecars:
## Add sidecars to the pod.
## e.g.
# - name: your-image-name
  # image: your-image
  # imagePullPolicy: Always
  # ports:
  # - name: portname
  #   containerPort: 1234
