{{- $replicaCount := int .Values.replicaCount }}
{{- $portNumber := int .Values.service.port }}
{{- $fullname := include "mongodb.fullname" . }}
{{- $releaseNamespace := include "mongodb.namespace" . }}
{{- $clusterDomain := .Values.clusterDomain }}
{{- $loadBalancerIPListLength := len .Values.externalAccess.service.loadBalancerIPs }}

{{- if and (eq .Values.architecture "replicaset") .Values.externalAccess.enabled (not .Values.externalAccess.autoDiscovery.enabled) (not (eq $replicaCount $loadBalancerIPListLength )) (eq .Values.externalAccess.service.type "LoadBalancer") }}

###############################################################################
### ERROR: You enabled external access to MongoDB nodes without specifying  ###
###   the array of load balancer IPs for MongoDB nodes.                     ###
###############################################################################

This deployment will be incomplete until you configure the array of load balancer
IPs for MongoDB nodes. To complete your deployment follow the steps below:

1. Wait for the load balancer IPs (it may take a few minutes for them to be available):

    kubectl get svc --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ template "mongodb.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=mongodb" -w

2. Obtain the load balancer IPs and upgrade your chart:

    {{- range $e, $i := until $replicaCount }}
    LOAD_BALANCER_IP_{{ add $i 1 }}="$(kubectl get svc --namespace {{ $releaseNamespace }} {{ $fullname }}-{{ $i }}-external -o jsonpath='{.status.loadBalancer.ingress[0].ip}')"
    {{- end }}

3. Upgrade you chart:

    helm upgrade {{ .Release.Name }} bitnami/{{ .Chart.Name }} \
      --set mongodb.replicaCount={{ $replicaCount }} \
      --set mongodb.externalAccess.enabled=true \
      {{- range $i, $e := until $replicaCount }}
      --set mongodb.externalAccess.service.loadBalancerIPs[{{ $i }}]=$LOAD_BALANCER_IP_{{ add $i 1 }} \
      {{- end }}
      --set mongodb.externalAccess.service.type=LoadBalancer

{{- else }}

{{- if and (or (and (eq .Values.architecture "standalone") (or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort"))) (and (eq .Values.architecture "replicaset") .Values.externalAccess.enabled)) (not .Values.auth.enabled) }}
-------------------------------------------------------------------------------
 WARNING

    By not enabling "mongodb.auth.enabled" you have most likely exposed the
    MongoDB service externally without any authentication mechanism.

    For security reasons, we strongly suggest that you enable authentiation
    setting the "mongodb.auth.enabled" parameter to "true".

-------------------------------------------------------------------------------
{{- end }}

** Please be patient while the chart is being deployed **

MongoDB can be accessed via port {{ .Values.service.port }} on the following DNS name(s) from within your cluster:

{{- if eq .Values.architecture "replicaset" }}

    {{ range $e, $i := until $replicaCount }}
    {{- $fullname }}-{{ $i }}.{{ $fullname }}-headless.{{ $releaseNamespace }}.svc.{{ $clusterDomain }}
    {{ end }}

{{- else }}

    {{ $fullname }}.{{ $releaseNamespace }}.svc.{{ .Values.clusterDomain }}

{{- end }}

{{- if .Values.auth.enabled }}

To get the root password run:

    export MONGODB_ROOT_PASSWORD=$(kubectl get secret --namespace {{ template "mongodb.namespace" . }} {{ template "mongodb.fullname" . }} -o jsonpath="{.data.mongodb-root-password}" | base64 --decode)

{{- end }}
{{- if and .Values.auth.username .Values.auth.database .Values.auth.password }}

To get the password for "{{ .Values.auth.username }}" run:

    export MONGODB_PASSWORD=$(kubectl get secret --namespace {{ template "mongodb.namespace" . }} {{ template "mongodb.fullname" . }} -o jsonpath="{.data.mongodb-password}" | base64 --decode)

{{- end }}

To connect to your database, create a MongoDB client container:

    kubectl run --namespace {{ template "mongodb.namespace" . }} {{ template "mongodb.fullname" . }}-client --rm --tty -i --restart='Never' --image {{ template "mongodb.image" . }} --command -- bash

Then, run the following command:

    {{- if eq .Values.architecture "replicaset" }}
    mongo admin --host "{{- range $e, $i := until $replicaCount }}{{ $fullname }}-{{ $i }}.{{ $fullname }}-headless.{{ $releaseNamespace }}.svc.{{ $clusterDomain }},{{ end }}" {{- if .Values.auth.enabled }} --authenticationDatabase admin -u root -p $MONGODB_ROOT_PASSWORD{{- end }}
    {{- else }}
    mongo admin --host "{{ template "mongodb.fullname" . }}" {{- if .Values.auth.enabled }} --authenticationDatabase admin -u root -p $MONGODB_ROOT_PASSWORD{{- end }}
    {{- end }}

{{- if and (eq .Values.architecture "replicaset") .Values.externalAccess.enabled }}

To connect to your database nodes from outside, you need to add both primary and secondary nodes hostnames/IPs to your Mongo client. To obtain them, follow the instructions below:

{{- if eq "NodePort" .Values.externalAccess.service.type }}
{{- if .Values.externalAccess.service.domain }}

    MongoDB nodes domain: Use your provided hostname to reach MongoDB nodes, {{ .Values.externalAccess.service.domain }}

{{- else }}

    MongoDB nodes domain: you can reach MongoDB nodes on any of the K8s nodes external IPs.

        kubectl get nodes -o wide

{{- end }}

    MongoDB nodes port: You will have a different node port for each MongoDB node. You can get the list of configured node ports using the command below:

        echo "$(kubectl get svc --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ template "mongodb.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=mongodb,pod" -o jsonpath='{.items[*].spec.ports[0].nodePort}' | tr ' ' '\n')"

{{- else if contains "LoadBalancer" .Values.externalAccess.service.type }}

  NOTE: It may take a few minutes for the LoadBalancer IPs to be available.
        Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ template "mongodb.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=mongodb,pod" -w'

    MongoDB nodes domain: You will have a different external IP for each MongoDB node. You can get the list of external IPs using the command below:

        echo "$(kubectl get svc --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ template "mongodb.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=mongodb,pod" -o jsonpath='{.items[*].status.loadBalancer.ingress[0].ip}' | tr ' ' '\n')"

    MongoDB nodes port: {{ .Values.externalAccess.service.port }}

{{- end }}

{{- else if eq .Values.architecture "standalone" }}

To connect to your database from outside the cluster execute the following commands:

{{- if contains "NodePort" .Values.service.type }}

    export NODE_IP=$(kubectl get nodes --namespace {{ template "mongodb.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}")
    export NODE_PORT=$(kubectl get --namespace {{ template "mongodb.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "mongodb.fullname" . }})
    mongo --host $NODE_IP --port $NODE_PORT {{- if .Values.auth.enabled }} --authenticationDatabase admin -p $MONGODB_ROOT_PASSWORD{{- end }}

{{- else if contains "LoadBalancer" .Values.service.type }}

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace {{ template "mongodb.namespace" . }} -w {{ template "mongodb.fullname" . }}'

    export SERVICE_IP=$(kubectl get svc --namespace {{ template "mongodb.namespace" . }} {{ template "mongodb.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
    mongo --host $SERVICE_IP --port {{ .Values.service.port }} {{- if .Values.auth.enabled }} --authenticationDatabase admin -p $MONGODB_ROOT_PASSWORD{{- end }}

{{- else if contains "ClusterIP" .Values.service.type }}

    kubectl port-forward --namespace {{ template "mongodb.namespace" . }} svc/{{ template "mongodb.fullname" . }} {{ .Values.service.port }}:{{ .Values.service.port }} &
    mongo --host 127.0.0.1 {{- if .Values.auth.enabled }} --authenticationDatabase admin -p $MONGODB_ROOT_PASSWORD{{- end }}

{{- end }}
{{- end }}
{{- end }}

{{- if .Values.metrics.enabled }}

To access the MongoDB Prometheus metrics, get the MongoDB Prometheus URL by running:

    kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ include "mongodb.fullname" . }}-metrics {{ .Values.metrics.service.port }}:{{ .Values.metrics.service.port }} &
    echo "Prometheus Metrics URL: http://127.0.0.1:{{ .Values.metrics.service.port }}/metrics"

Then, open the obtained URL in a browser.

{{- end }}

{{- include "common.warnings.rollingTag" .Values.image }}
{{- include "common.warnings.rollingTag" .Values.metrics.image }}
{{- include "common.warnings.rollingTag" .Values.externalAccess.autoDiscovery.image }}
{{- include "mongodb.validateValues" . }}
{{- $secretName := include "mongodb.fullname" . -}}
{{- $requiredPasswords := list -}}

{{- if and .Values.auth.enabled (not .Values.auth.existingSecret) }}

{{- $requiredRootPassword := dict "valueKey" "auth.rootPassword" "secret" $secretName "field" "mongodb-root-password" "context" $ -}}
{{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}}

{{- if and .Values.auth.username .Values.auth.database }}
  {{- $requiredDBPassword := dict "valueKey" "auth.password" "secret" $secretName "field" "mongodb-password" "context" $ -}}
  {{- $requiredPasswords = append $requiredPasswords $requiredDBPassword -}}
{{- end -}}


{{- if eq .Values.architecture "replicaset" }}
  {{- $requiredReplicaSetKey := dict "valueKey" "auth.replicaSetKey" "secret" $secretName "field" "mongodb-replica-set-key" "context" $ -}}
  {{- $requiredPasswords = append $requiredPasswords $requiredReplicaSetKey -}}
{{- end -}}

{{- $requiredPasswordValidationErrors := include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" $) -}}
{{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $requiredPasswordValidationErrors) "context" $) -}}
{{- end }}
