{{- if and .Values.cluster.update.addNodes ( or (and .Values.cluster.externalAccess.enabled .Values.cluster.externalAccess.service.loadBalancerIP) ( not .Values.cluster.externalAccess.enabled )) }}
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ template "common.names.fullname" . }}-cluster-update
  labels: {{- include "common.labels.standard" . | nindent 4 }}
    {{- if .Values.commonLabels }}
    {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }}
    {{- end }}
  annotations:
    "helm.sh/hook": post-upgrade
    {{- if .Values.updateJob.annotations }}
    {{- include "common.tplvalues.render" ( dict "value" .Values.updateJob.annotations "context" $ ) | nindent 4 }}
    {{- end }}
    {{- if .Values.commonAnnotations }}
    {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
    {{- end }}
spec:
  activeDeadlineSeconds: {{ .Values.updateJob.activeDeadlineSeconds }}
  template:
    metadata:
      labels: {{- include "common.labels.standard" . | nindent 8 }}
        {{- if .Values.commonLabels }}
        {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 8 }}
        {{- end }}
        {{- if .Values.updateJob.podLabels }}
        {{- include "common.tplvalues.render" (dict "value" .Values.updateJob.podLabels "context" $) | nindent 8 }}
        {{- end }}
      annotations:
        {{- if .Values.commonAnnotations }}
        {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 8 }}
        {{- end }}
        {{- if .Values.updateJob.podAnnotations }}
        {{- include "common.tplvalues.render" (dict "value" .Values.updateJob.podAnnotations "context" $) | nindent 8 }}
        {{- end }}
    spec:
      {{- include "redis-cluster.imagePullSecrets" . | nindent 6 }}
      {{- if .Values.updateJob.affinity }}
      affinity: {{- include "common.tplvalues.render" (dict "value" .Values.updateJob.affinity "context" $) | nindent 8 }}
      {{- end }}
      {{- if .Values.updateJob.nodeSelector }}
      nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.updateJob.nodeSelector "context" $) | nindent 8 }}
      {{- end }}
      {{- if .Values.updateJob.tolerations }}
      tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.updateJob.tolerations "context" $) | nindent 8 }}
      {{- end }}
      {{- if .Values.podSecurityContext.enabled }}
      securityContext:
        fsGroup: {{ .Values.podSecurityContext.fsGroup }}
        {{- if .Values.podSecurityContext.sysctls }}
        sysctls:
          {{- toYaml .Values.podSecurityContext.sysctls | nindent 8 }}
        {{- end }}
      {{- end }}
      serviceAccountName: {{ include "redis-cluster.serviceAccountName" . }}
      {{- if .Values.updateJob.initContainers }}
      initContainers: {{- include "common.tplvalues.render" (dict "value" .Values.updateJob.initContainers "context" $) | nindent 8 }}
      {{- end }}
      containers:
        - name: trigger
          image: {{ include "redis-cluster.image" . }}
          imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
          {{- if .Values.containerSecurityContext.enabled }}
          securityContext:
            runAsUser: {{ .Values.containerSecurityContext.runAsUser }}
          {{- end }}
          {{- if .Values.updateJob.command }}
          command: {{- include "common.tplvalues.render" (dict "value" .Values.updateJob.command "context" $) | nindent 12 }}
          {{- else }}
          command: ['/bin/bash', '-c']
          {{- end }}
          {{- if .Values.updateJob.args }}
          args: {{- include "common.tplvalues.render" (dict "value" .Values.updateJob.args "context" $) | nindent 12 }}
          {{- else }}
          args:
            - |
              . /opt/bitnami/scripts/libnet.sh
              . /opt/bitnami/scripts/libos.sh
              # Backwards compatibility change
              if ! [[ -f /opt/bitnami/redis/etc/redis.conf ]]; then
                  cp /opt/bitnami/redis/etc/redis-default.conf /opt/bitnami/redis/etc/redis.conf
              fi
              previousNodeIp=""
              firstNodeIp=$(wait_for_dns_lookup {{ template "common.names.fullname" . }}-0.{{ template "common.names.fullname" . }}-headless 120 5)
              {{- if .Values.cluster.externalAccess.enabled }}
              newNodeCounter=0
              for nodeIp in $(echo "{{ .Values.cluster.update.newExternalIPs }}" | cut -d [ -f2 | cut -d ] -f 1 ); do
                {{- if .Values.tls.enabled }}
                while [[ $(redis-cli -h "$nodeIp" -p "$REDIS_TLS_PORT" --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} ping) != 'PONG' ]]; do
                {{- else }}
                while [[ $(redis-cli -h "$nodeIp" -p "$REDIS_PORT" ping) != 'PONG' ]]; do
                {{- end }}
                  echo "Node $nodeIp not ready, waiting for all the nodes to be ready..."
                  sleep 5
                done
                slave=()
                if (( $REDIS_CLUSTER_REPLICAS >= 1 )) && (( newNodeCounter % (( $REDIS_CLUSTER_REPLICAS + 1 )) )); then
                  slave+=("--cluster-slave")
                  [ -z previousNodeIp ] && previousNodeIp=$firstNodeIp
                  masterID=$(redis-cli -c -h $previousNodeIp -a $REDISCLI_AUTH cluster myid)
                  slave+=("--cluster-master-id $masterID")
                  echo "Adding Node ${newNodeCounter} ip: ${nodeIp} as slave of ${masterID}"
                else
                  previousNodeIp=$nodeIp
                  echo "Adding Node ${newNodeCounter} ip: ${nodeIp} as master"
                fi
                {{- if .Values.tls.enabled }}
                while ! redis-cli --cluster --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} add-node "${nodeIp}:${REDIS_TLS_PORT}" "{{ index .Values.cluster.externalAccess.service.loadBalancerIP 0 }}:${REDIS_TLS_PORT}" ${slave[@]}; do
                {{- else }}
                while ! redis-cli --cluster add-node "${nodeIp}:${REDIS_PORT}" "{{ index .Values.cluster.externalAccess.service.loadBalancerIP 0 }}:${REDIS_PORT}" ${slave[@]}; do
                {{- end }}
                  echo "Add-node ${new_node_index} ${new_node_ip} failed, retrying"
                  sleep 5
                done
                ((newNodeCounter += 1))
              done
              {{- else }}
              for node in $(seq $((1+{{ .Values.cluster.update.currentNumberOfNodes }})) {{ .Values.cluster.nodes }}); do
                new_node_index="$(($node - 1))"
                new_node_ip=$(wait_for_dns_lookup {{ template "common.names.fullname" . }}-"$new_node_index".{{ template "common.names.fullname" . }}-headless 120 5)
                {{- if .Values.tls.enabled }}
                while [[ $(redis-cli -h "$new_node_ip" -p "$REDIS_TLS_PORT" --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} ping) != 'PONG' ]]; do
                {{- else }}
                while [[ $(redis-cli -h "$new_node_ip" -p "$REDIS_PORT" ping) != 'PONG' ]]; do
                {{- end }}
                  echo "Node $new_node_ip not ready, waiting for all the nodes to be ready..."
                  sleep 5
                done
                slave=()
                if (( $REDIS_CLUSTER_REPLICAS >= 1 )) && (( new_node_index % (( $REDIS_CLUSTER_REPLICAS + 1 )) )); then
                  slave+=("--cluster-slave")
                  [ -z previousNodeIp ] && previousNodeIp=$firstNodeIp
                  masterID=$(redis-cli -c -h $previousNodeIp -a $REDISCLI_AUTH cluster myid)
                  slave+=("--cluster-master-id $masterID")
                  echo "Adding Node $new_node_index ${new_node_ip} as slave of ${masterID}"
                else
                  previousNodeIp=$new_node_ip
                  echo "Adding Node $new_node_index ${new_node_ip} as master"
                fi
                {{- if .Values.tls.enabled }}
                while ! redis-cli --cluster add-node --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} "${new_node_ip}:${REDIS_TLS_PORT}" "${firstNodeIp}:${REDIS_TLS_PORT}" ${slave[@]}; do
                {{- else }}
                while ! redis-cli --cluster add-node "${new_node_ip}:${REDIS_PORT}" "${firstNodeIp}:${REDIS_PORT}" ${slave[@]}; do
                {{- end }}
                  echo "Add-node ${new_node_index} ${new_node_ip} failed, retrying"
                  sleep 5
                done
              done
              {{- end }}
          {{- end }}
          env:
            {{- if .Values.cluster.externalAccess.enabled }}
            {{- if .Values.tls.enabled }}
            - name: REDIS_TLS_PORT
            {{- else }}
            - name: REDIS_PORT
            {{- end }}
              value: {{ .Values.cluster.externalAccess.service.port | quote }}
            {{- else }}
            {{- if .Values.tls.enabled }}
            - name: REDIS_TLS_PORT
            {{- else }}
            - name: REDIS_PORT
            {{- end }}
              value: {{ .Values.redis.port | quote }}
            {{- end }}
            - name: REDIS_CLUSTER_REPLICAS
              value: {{ .Values.cluster.replicas | quote }}
            {{- if .Values.usePassword }}
            - name: REDISCLI_AUTH
              valueFrom:
                secretKeyRef:
                  name: {{ template "redis-cluster.secretName" . }}
                  key: {{ template "redis-cluster.secretPasswordKey" . }}
            {{- end }}
            {{- if .Values.updateJob.extraEnvVars }}
            {{- include "common.tplvalues.render" (dict "value" .Values.updateJob.extraEnvVars "context" $) | nindent 12 }}
            {{- end }}
          envFrom:
            {{- if .Values.updateJob.extraEnvVarsCM }}
            - configMapRef:
                name: {{ include "common.tplvalues.render" (dict "value" .Values.updateJob.extraEnvVarsCM "context" $) }}
            {{- end }}
            {{- if .Values.updateJob.extraEnvVarsSecret }}
            - secretRef:
                name: {{ include "common.tplvalues.render" (dict "value" .Values.updateJob.extraEnvVarsSecret "context" $) }}
            {{- end }}
          {{- if .Values.updateJob.resources }}
          resources: {{- toYaml .Values.updateJob.resources | nindent 12 }}
          {{- end }}
          {{- if or .Values.tls.enabled .Values.updateJob.extraVolumeMounts }}
          volumeMounts:
            {{- if .Values.tls.enabled }}
            - name: redis-certificates
              mountPath: /opt/bitnami/redis/certs
              readOnly: true
            {{- end }}
            {{- if .Values.updateJob.extraVolumeMounts }}
            {{- include "common.tplvalues.render" (dict "value" .Values.updateJob.extraVolumeMounts "context" $) | nindent 12 }}
            {{- end }}
          {{- end }}
      restartPolicy: OnFailure
      volumes:
      {{- if .Values.tls.enabled }}
        - name: redis-certificates
          secret:
            secretName: {{ include "common.tplvalues.render" (dict "value" .Values.tls.certificatesSecret "context" $) }}
      {{- end }}
      {{- if .Values.updateJob.extraVolumes }}
      {{- include "common.tplvalues.render" (dict "value" .Values.updateJob.extraVolumes "context" $) | nindent 6 }}
      {{- end }}
{{- end }}
