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

{{- if contains .Values.master.service.type "LoadBalancer" }}
{{- if not .Values.usePassword }}
{{ if and (not .Values.networkPolicy.enabled) (.Values.networkPolicy.allowExternal) }}

-------------------------------------------------------------------------------
 WARNING

    By specifying "master.service.type=LoadBalancer" and "usePassword=false" you have
    most likely exposed the Redis(TM) service externally without any authentication
    mechanism.

    For security reasons, we strongly suggest that you switch to "ClusterIP" or
    "NodePort". As alternative, you can also switch to "usePassword=true"
    providing a valid password on "password" parameter.

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

{{- if and .Values.global.redis.sentinel.enabled (not .Values.global.redis.cluster.enabled)}}

-------------------------------------------------------------------------------
 WARNING

    Using redis sentinel without a cluster is not supported. A single pod with
    standalone redis has been deployed.

    To deploy redis sentinel, please use the values "cluster.enabled=true" and
    "sentinel.enabled=true".

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

{{- if .Values.global.redis.cluster.enabled }}
{{- if .Values.global.redis.sentinel.enabled }}
Redis can be accessed via port {{ .Values.sentinel.service.redisPort }} on the following DNS name from within your cluster:

{{ template "redis.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} for read only operations

For read/write operations, first access the Redis(TM) Sentinel cluster, which is available in port {{ .Values.sentinel.service.sentinelPort }} using the same domain name above.

{{- else }}
Redis(TM) can be accessed via port {{ .Values.redisPort }} on the following DNS names from within your cluster:

{{ template "redis.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} for read/write operations
{{ template "redis.fullname" . }}-slave.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} for read-only operations
{{- end }}

{{- else }}
Redis(TM) can be accessed via port {{ .Values.redisPort }} on the following DNS name from within your cluster:

{{ template "redis.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}

{{- end }}

{{ if .Values.usePassword }}
To get your password run:

    export REDIS_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "redis.secretName" . }} -o jsonpath="{.data.redis-password}" | base64 --decode)
{{- end }}

To connect to your Redis(TM) server:

1. Run a Redis(TM) pod that you can use as a client:

{{- if .Values.tls.enabled }}
   kubectl run --namespace {{ .Release.Namespace }} {{ template "redis.fullname" . }}-client --restart='Never' --env REDIS_PASSWORD=$REDIS_PASSWORD --image {{ template "redis.image" . }} --command -- sleep infinity

   Copy your TLS certificates to the pod:

   kubectl cp --namespace {{ .Release.Namespace }} /path/to/client.cert {{ template "redis.fullname" . }}-client:/tmp/client.cert
   kubectl cp --namespace {{ .Release.Namespace }} /path/to/client.key {{ template "redis.fullname" . }}-client:/tmp/client.key
   kubectl cp --namespace {{ .Release.Namespace }} /path/to/CA.cert {{ template "redis.fullname" . }}-client:/tmp/CA.cert

   Use the following command to attach to the pod:

   kubectl exec --tty -i {{ template "redis.fullname" . }}-client \
   {{- if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }}--labels="{{ template "redis.fullname" . }}-client=true" \{{- end }}
   --namespace {{ .Release.Namespace }} -- bash
{{- else }}
   kubectl run --namespace {{ .Release.Namespace }} {{ template "redis.fullname" . }}-client --rm --tty -i --restart='Never' \
   {{ if .Values.usePassword }} --env REDIS_PASSWORD=$REDIS_PASSWORD \{{ end }}
   {{- if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }}--labels="{{ template "redis.fullname" . }}-client=true" \{{- end }}
   --image {{ template "redis.image" . }} -- bash
{{- end }}

2. Connect using the Redis(TM) CLI:

{{- if .Values.global.redis.cluster.enabled }}
   {{- if .Values.global.redis.sentinel.enabled }}
   redis-cli -h {{ template "redis.fullname" . }} -p {{ .Values.sentinel.service.redisPort }}{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }}{{ if .Values.tls.enabled }} --tls --cert /tmp/client.cert --key /tmp/client.key --cacert /tmp/CA.cert{{ end }} # Read only operations
   redis-cli -h {{ template "redis.fullname" . }} -p {{ .Values.sentinel.service.sentinelPort }}{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }}{{ if .Values.tls.enabled }} --tls --cert /tmp/client.cert --key /tmp/client.key --cacert /tmp/CA.cert{{ end }} # Sentinel access
   {{- else }}
   redis-cli -h {{ template "redis.fullname" . }}-master{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }}{{ if .Values.tls.enabled }} --tls --cert /tmp/client.cert --key /tmp/client.key --cacert /tmp/CA.cert{{ end }}
   redis-cli -h {{ template "redis.fullname" . }}-slave{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }}{{ if .Values.tls.enabled }} --tls --cert /tmp/client.cert --key /tmp/client.key --cacert /tmp/CA.cert{{ end }}
   {{- end }}
{{- else }}
   redis-cli -h {{ template "redis.fullname" . }}-master{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }}{{ if .Values.tls.enabled }} --tls --cert /tmp/client.cert --key /tmp/client.key --cacert /tmp/CA.cert{{ end }}
{{- end }}

{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }}
Note: Since NetworkPolicy is enabled, only pods with label
{{ template "redis.fullname" . }}-client=true"
will be able to connect to redis.
{{- else -}}

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

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

    export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
    export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "redis.fullname" . }}-master)
    redis-cli -h $NODE_IP -p $NODE_PORT {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }}{{ if .Values.tls.enabled }} --tls --cert /tmp/client.cert --key /tmp/client.key --cacert /tmp/CA.cert{{ end }}

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

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

    export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "redis.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
    redis-cli -h $SERVICE_IP -p {{ .Values.master.service.port }} {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }}{{ if .Values.tls.enabled }} --tls --cert /tmp/client.cert --key /tmp/client.key --cacert /tmp/CA.cert{{ end }}

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

    kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "redis.fullname" . }}-master {{ .Values.redisPort }}:{{ .Values.redisPort }} &
    redis-cli -h 127.0.0.1 -p {{ .Values.redisPort }} {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }}{{ if .Values.tls.enabled }} --tls --cert /tmp/client.cert --key /tmp/client.key --cacert /tmp/CA.cert{{ end }}

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

{{ include "redis.checkRollingTags" . }}

{{- include "redis.validateValues" . }}
