summaryrefslogtreecommitdiff
path: root/astroshop-platform/argocd-helmchart/charts/redis-ha/templates
diff options
context:
space:
mode:
Diffstat (limited to 'astroshop-platform/argocd-helmchart/charts/redis-ha/templates')
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/NOTES.txt25
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/_configs.tpl730
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/_helpers.tpl130
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-auth-secret.yaml15
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-announce-service.yaml64
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-configmap.yaml37
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-exporter-script-configmap.yaml14
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-health-configmap.yaml20
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-network-policy.yaml80
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-pdb.yaml18
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-prometheus-rule.yaml17
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-role.yaml19
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-rolebinding.yaml19
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-secret.yaml32
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-service.yaml57
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-serviceaccount.yaml31
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-servicemonitor.yaml39
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-statefulset.yaml668
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-deployment.yaml202
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-network-policy.yaml74
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-pdb.yaml18
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-role.yaml22
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-rolebinding.yaml22
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-service.yaml60
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-serviceaccount.yaml15
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-servicemonitor.yaml39
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-tls-secret.yaml27
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/sentinel-auth-secret.yaml15
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/tests/test-redis-ha-configmap.yaml32
-rw-r--r--astroshop-platform/argocd-helmchart/charts/redis-ha/templates/tests/test-redis-ha-pod.yaml29
30 files changed, 2570 insertions, 0 deletions
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/NOTES.txt b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/NOTES.txt
new file mode 100644
index 0000000..07ea429
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/NOTES.txt
@@ -0,0 +1,25 @@
+Redis can be accessed via {{ if ne (int .Values.redis.port) 0 }}port {{ .Values.redis.port }}{{ end }} {{ if .Values.redis.tlsPort }} tls-port {{ .Values.redis.tlsPort }}{{ end }} and Sentinel can be accessed via {{ if ne (int .Values.sentinel.port) 0 }}port {{ .Values.sentinel.port }}{{ end }} {{ if .Values.sentinel.tlsPort }} tls-port {{ .Values.sentinel.tlsPort }}{{ end }} on the following DNS name from within your cluster:
+{{ template "redis-ha.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
+
+To connect to your Redis server:
+
+{{- if .Values.auth }}
+1. To retrieve the redis password:
+ echo $(kubectl get secret {{ template "redis-ha.fullname" . }} -o "jsonpath={.data['auth']}" | base64 --decode)
+
+2. Connect to the Redis master pod that you can use as a client. By default the {{ template "redis-ha.fullname" . }}-server-0 pod is configured as the master:
+
+ kubectl exec -it {{ template "redis-ha.fullname" . }}-server-0 -n {{ .Release.Namespace }} -c redis -- sh
+
+3. Connect using the Redis CLI (inside container):
+
+ redis-cli -a <REDIS-PASS-FROM-SECRET>
+{{- else }}
+1. Run a Redis pod that you can use as a client:
+
+ kubectl exec -it {{ template "redis-ha.fullname" . }}-server-0 -n {{ .Release.Namespace }} -c redis -- sh
+
+2. Connect using the Redis CLI:
+
+ redis-cli -h {{ template "redis-ha.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/_configs.tpl b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/_configs.tpl
new file mode 100644
index 0000000..e1222ad
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/_configs.tpl
@@ -0,0 +1,730 @@
+{{/* vim: set filetype=mustache: */}}
+
+{{- define "config-redis.conf" }}
+{{- if .Values.redis.customConfig }}
+{{ tpl .Values.redis.customConfig . | indent 4 }}
+{{- else }}
+ dir "/data"
+ port {{ .Values.redis.port }}
+ {{- if .Values.sentinel.tlsPort }}
+ tls-port {{ .Values.redis.tlsPort }}
+ tls-cert-file /tls-certs/{{ .Values.tls.certFile }}
+ tls-key-file /tls-certs/{{ .Values.tls.keyFile }}
+ {{- if .Values.tls.dhParamsFile }}
+ tls-dh-params-file /tls-certs/{{ .Values.tls.dhParamsFile }}
+ {{- end }}
+ {{- if .Values.tls.caCertFile }}
+ tls-ca-cert-file /tls-certs/{{ .Values.tls.caCertFile }}
+ {{- end }}
+ {{- if eq (default "yes" .Values.redis.authClients) "no"}}
+ tls-auth-clients no
+ {{- end }}
+ tls-replication {{ if .Values.redis.tlsReplication }}yes{{ else }}no{{ end }}
+ {{- end }}
+ {{- if .Values.redis.disableCommands }}
+ {{- range .Values.redis.disableCommands }}
+ rename-command {{ . }} ""
+ {{- end }}
+ {{- end }}
+ {{- range $key, $value := .Values.redis.config }}
+ {{- if kindIs "slice" $value }}
+ {{- range $value }}
+ {{ $key }} {{ . }}
+ {{- end }}
+ {{- else }}
+ {{ $key }} {{ $value }}
+ {{- end }}
+ {{- end }}
+{{- if .Values.auth }}
+ requirepass replace-default-auth
+ masterauth replace-default-auth
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{- define "config-sentinel.conf" }}
+{{- if .Values.sentinel.customConfig }}
+{{ tpl .Values.sentinel.customConfig . | indent 4 }}
+{{- else }}
+ dir "/data"
+ port {{ .Values.sentinel.port }}
+ {{- if .Values.sentinel.bind }}
+ bind {{ .Values.sentinel.bind }}
+ {{- end }}
+ {{- if .Values.sentinel.tlsPort }}
+ tls-port {{ .Values.sentinel.tlsPort }}
+ tls-cert-file /tls-certs/{{ .Values.tls.certFile }}
+ tls-key-file /tls-certs/{{ .Values.tls.keyFile }}
+ {{- if .Values.tls.dhParamsFile }}
+ tls-dh-params-file /tls-certs/{{ .Values.tls.dhParamsFile }}
+ {{- end }}
+ {{- if .Values.tls.caCertFile }}
+ tls-ca-cert-file /tls-certs/{{ .Values.tls.caCertFile }}
+ {{- end }}
+ {{- if eq (default "yes" .Values.sentinel.authClients) "no"}}
+ tls-auth-clients no
+ {{- end }}
+ tls-replication {{ if .Values.sentinel.tlsReplication }}yes{{ else }}no{{ end }}
+ {{- end }}
+ {{- range $key, $value := .Values.sentinel.config }}
+ {{- if eq "maxclients" $key }}
+ {{ $key }} {{ $value }}
+ {{- else }}
+ sentinel {{ $key }} {{ template "redis-ha.masterGroupName" $ }} {{ $value }}
+ {{- end }}
+ {{- end }}
+{{- if .Values.auth }}
+ sentinel auth-pass {{ template "redis-ha.masterGroupName" . }} replace-default-auth
+{{- end }}
+{{- if .Values.sentinel.auth }}
+ requirepass replace-default-sentinel-auth
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{- define "lib.sh" }}
+ sentinel_get_master() {
+ set +e
+ if [ "$SENTINEL_PORT" -eq 0 ]; then
+ redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} sentinel get-master-addr-by-name "${MASTER_GROUP}" |\
+ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))'
+ else
+ redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} sentinel get-master-addr-by-name "${MASTER_GROUP}" |\
+ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))'
+ fi
+ set -e
+ }
+
+ sentinel_get_master_retry() {
+ master=''
+ retry=${1}
+ sleep=3
+ for i in $(seq 1 "${retry}"); do
+ master=$(sentinel_get_master)
+ if [ -n "${master}" ]; then
+ break
+ fi
+ sleep $((sleep + i))
+ done
+ echo "${master}"
+ }
+
+ identify_master() {
+ echo "Identifying redis master (get-master-addr-by-name).."
+ echo " using sentinel ({{ template "redis-ha.fullname" . }}), sentinel group name ({{ template "redis-ha.masterGroupName" . }})"
+ MASTER="$(sentinel_get_master_retry 3)"
+ if [ -n "${MASTER}" ]; then
+ echo " $(date) Found redis master (${MASTER})"
+ else
+ echo " $(date) Did not find redis master (${MASTER})"
+ fi
+ }
+
+ sentinel_update() {
+ echo "Updating sentinel config.."
+ echo " evaluating sentinel id (\${SENTINEL_ID_${INDEX}})"
+ eval MY_SENTINEL_ID="\$SENTINEL_ID_${INDEX}"
+ echo " sentinel id (${MY_SENTINEL_ID}), sentinel grp (${MASTER_GROUP}), quorum (${QUORUM})"
+ sed -i "1s/^/sentinel myid ${MY_SENTINEL_ID}\\n/" "${SENTINEL_CONF}"
+ if [ "$SENTINEL_TLS_REPLICATION_ENABLED" = true ]; then
+ echo " redis master (${1}:${REDIS_TLS_PORT})"
+ sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_TLS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}"
+ else
+ echo " redis master (${1}:${REDIS_PORT})"
+ sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}"
+ fi
+ echo "sentinel announce-ip ${ANNOUNCE_IP}" >> ${SENTINEL_CONF}
+ if [ "$SENTINEL_PORT" -eq 0 ]; then
+ echo " announce (${ANNOUNCE_IP}:${SENTINEL_TLS_PORT})"
+ echo "sentinel announce-port ${SENTINEL_TLS_PORT}" >> ${SENTINEL_CONF}
+ else
+ echo " announce (${ANNOUNCE_IP}:${SENTINEL_PORT})"
+ echo "sentinel announce-port ${SENTINEL_PORT}" >> ${SENTINEL_CONF}
+ fi
+ }
+
+ redis_update() {
+ echo "Updating redis config.."
+ if [ "$REDIS_TLS_REPLICATION_ENABLED" = true ]; then
+ echo " we are slave of redis master (${1}:${REDIS_TLS_PORT})"
+ echo "slaveof ${1} ${REDIS_TLS_PORT}" >> "${REDIS_CONF}"
+ echo "slave-announce-port ${REDIS_TLS_PORT}" >> ${REDIS_CONF}
+ else
+ echo " we are slave of redis master (${1}:${REDIS_PORT})"
+ echo "slaveof ${1} ${REDIS_PORT}" >> "${REDIS_CONF}"
+ echo "slave-announce-port ${REDIS_PORT}" >> ${REDIS_CONF}
+ fi
+ echo "slave-announce-ip ${ANNOUNCE_IP}" >> ${REDIS_CONF}
+ }
+
+ copy_config() {
+ echo "Copying default redis config.."
+ echo " to '${REDIS_CONF}'"
+ cp /readonly-config/redis.conf "${REDIS_CONF}"
+ echo "Copying default sentinel config.."
+ echo " to '${SENTINEL_CONF}'"
+ cp /readonly-config/sentinel.conf "${SENTINEL_CONF}"
+ }
+
+ setup_defaults() {
+ echo "Setting up defaults.."
+ echo " using statefulset index (${INDEX})"
+ if [ "${INDEX}" = "0" ]; then
+ echo "Setting this pod as master for redis and sentinel.."
+ echo " using announce (${ANNOUNCE_IP})"
+ redis_update "${ANNOUNCE_IP}"
+ sentinel_update "${ANNOUNCE_IP}"
+ echo " make sure ${ANNOUNCE_IP} is not a slave (slaveof no one)"
+ sed -i "s/^.*slaveof.*//" "${REDIS_CONF}"
+ else
+ echo "Getting redis master ip.."
+ echo " blindly assuming (${SERVICE}-announce-0) or (${SERVICE}-server-0) are master"
+ DEFAULT_MASTER="$(getent_hosts 0 | awk '{ print $1 }')"
+ if [ -z "${DEFAULT_MASTER}" ]; then
+ echo "Error: Unable to resolve redis master (getent hosts)."
+ exit 1
+ fi
+ echo " identified redis (may be redis master) ip (${DEFAULT_MASTER})"
+ echo "Setting default slave config for redis and sentinel.."
+ echo " using master ip (${DEFAULT_MASTER})"
+ redis_update "${DEFAULT_MASTER}"
+ sentinel_update "${DEFAULT_MASTER}"
+ fi
+ }
+
+ redis_ping() {
+ set +e
+ if [ "$REDIS_PORT" -eq 0 ]; then
+ redis-cli -h "${MASTER}"{{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} ping
+ else
+ redis-cli -h "${MASTER}"{{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_PORT}" ping
+ fi
+ set -e
+ }
+
+ redis_ping_retry() {
+ ping=''
+ retry=${1}
+ sleep=3
+ for i in $(seq 1 "${retry}"); do
+ if [ "$(redis_ping)" = "PONG" ]; then
+ ping='PONG'
+ break
+ fi
+ sleep $((sleep + i))
+ MASTER=$(sentinel_get_master)
+ done
+ echo "${ping}"
+ }
+
+ find_master() {
+ echo "Verifying redis master.."
+ if [ "$REDIS_PORT" -eq 0 ]; then
+ echo " ping (${MASTER}:${REDIS_TLS_PORT})"
+ else
+ echo " ping (${MASTER}:${REDIS_PORT})"
+ fi
+ if [ "$(redis_ping_retry 3)" != "PONG" ]; then
+ echo " $(date) Can't ping redis master (${MASTER})"
+ echo "Attempting to force failover (sentinel failover).."
+
+ if [ "$SENTINEL_PORT" -eq 0 ]; then
+ echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})"
+ if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then
+ echo " $(date) Failover returned with 'NOGOODSLAVE'"
+ echo "Setting defaults for this pod.."
+ setup_defaults
+ return 0
+ fi
+ else
+ echo " on sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})"
+ if redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then
+ echo " $(date) Failover returned with 'NOGOODSLAVE'"
+ echo "Setting defaults for this pod.."
+ setup_defaults
+ return 0
+ fi
+ fi
+
+ echo "Hold on for 10sec"
+ sleep 10
+ echo "We should get redis master's ip now. Asking (get-master-addr-by-name).."
+ if [ "$SENTINEL_PORT" -eq 0 ]; then
+ echo " sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})"
+ else
+ echo " sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})"
+ fi
+ MASTER="$(sentinel_get_master)"
+ if [ "${MASTER}" ]; then
+ echo " $(date) Found redis master (${MASTER})"
+ echo "Updating redis and sentinel config.."
+ sentinel_update "${MASTER}"
+ redis_update "${MASTER}"
+ else
+ echo "$(date) Error: Could not failover, exiting..."
+ exit 1
+ fi
+ else
+ echo " $(date) Found reachable redis master (${MASTER})"
+ echo "Updating redis and sentinel config.."
+ sentinel_update "${MASTER}"
+ redis_update "${MASTER}"
+ fi
+ }
+
+ redis_ro_update() {
+ echo "Updating read-only redis config.."
+ echo " redis.conf set 'replica-priority 0'"
+ echo "replica-priority 0" >> ${REDIS_CONF}
+ }
+
+ getent_hosts() {
+ index=${1:-${INDEX}}
+ service="${SERVICE}-announce-${index}"
+ host=$(getent hosts "${service}")
+ echo "${host}"
+ }
+
+ identify_announce_ip() {
+ echo "Identify announce ip for this pod.."
+ echo " using (${SERVICE}-announce-${INDEX}) or (${SERVICE}-server-${INDEX})"
+ ANNOUNCE_IP=$(getent_hosts | awk '{ print $1 }')
+ echo " identified announce (${ANNOUNCE_IP})"
+ }
+{{- end }}
+
+{{- define "vars.sh" }}
+ HOSTNAME="$(hostname)"
+ {{- if .Values.ro_replicas }}
+ RO_REPLICAS="{{ .Values.ro_replicas }}"
+ {{- end }}
+ INDEX="${HOSTNAME##*-}"
+ SENTINEL_PORT={{ .Values.sentinel.port }}
+ ANNOUNCE_IP=''
+ MASTER=''
+ MASTER_GROUP="{{ template "redis-ha.masterGroupName" . }}"
+ QUORUM="{{ .Values.sentinel.quorum }}"
+ REDIS_CONF=/data/conf/redis.conf
+ REDIS_PORT={{ .Values.redis.port }}
+ REDIS_TLS_PORT={{ .Values.redis.tlsPort }}
+ SENTINEL_CONF=/data/conf/sentinel.conf
+ SENTINEL_TLS_PORT={{ .Values.sentinel.tlsPort }}
+ SERVICE={{ template "redis-ha.fullname" . }}
+ SENTINEL_TLS_REPLICATION_ENABLED={{ default false .Values.sentinel.tlsReplication }}
+ REDIS_TLS_REPLICATION_ENABLED={{ default false .Values.redis.tlsReplication }}
+{{- end }}
+
+{{- define "config-init.sh" }}
+ echo "$(date) Start..."
+ {{- include "vars.sh" . }}
+
+ set -eu
+
+ {{- include "lib.sh" . }}
+
+ mkdir -p /data/conf/
+
+ echo "Initializing config.."
+ copy_config
+
+ # where is redis master
+ identify_master
+
+ identify_announce_ip
+
+ if [ -z "${ANNOUNCE_IP}" ]; then
+ "Error: Could not resolve the announce ip for this pod"
+ exit 1
+ elif [ "${MASTER}" ]; then
+ find_master
+ else
+ setup_defaults
+ fi
+
+ {{- if .Values.ro_replicas }}
+ # works only if index is less than 10
+ echo "Verifying redis read-only replica.."
+ echo " we have RO_REPLICAS='${RO_REPLICAS}' with INDEX='${INDEX}'"
+ if echo "${RO_REPLICAS}" | grep -q "${INDEX}" ; then
+ redis_ro_update
+ fi
+ {{- end }}
+
+ if [ "${AUTH:-}" ]; then
+ echo "Setting redis auth values.."
+ ESCAPED_AUTH=$(echo "${AUTH}" | sed -e 's/[\/&]/\\&/g');
+ sed -i "s/replace-default-auth/${ESCAPED_AUTH}/" "${REDIS_CONF}" "${SENTINEL_CONF}"
+ fi
+
+ if [ "${SENTINELAUTH:-}" ]; then
+ echo "Setting sentinel auth values"
+ ESCAPED_AUTH_SENTINEL=$(echo "$SENTINELAUTH" | sed -e 's/[\/&]/\\&/g');
+ sed -i "s/replace-default-sentinel-auth/${ESCAPED_AUTH_SENTINEL}/" "$SENTINEL_CONF"
+ fi
+
+ echo "$(date) Ready..."
+{{- end }}
+
+{{- define "trigger-failover-if-master.sh" }}
+ {{- if or (eq (int .Values.redis.port) 0) (eq (int .Values.sentinel.port) 0) }}
+ TLS_CLIENT_OPTION="--tls --cacert /tls-certs/{{ .Values.tls.caCertFile }}{{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{end}}"
+ {{- end }}
+ get_redis_role() {
+ is_master=$(
+ redis-cli \
+ {{- if .Values.auth }}
+ -a "${AUTH}" --no-auth-warning \
+ {{- end }}
+ -h localhost \
+ {{- if (int .Values.redis.port) }}
+ -p {{ .Values.redis.port }} \
+ {{- else }}
+ -p {{ .Values.redis.tlsPort }} ${TLS_CLIENT_OPTION} \
+ {{- end}}
+ info | grep -c 'role:master' || true
+ )
+ }
+ get_redis_role
+ if [[ "$is_master" -eq 1 ]]; then
+ echo "This node is currently master, we trigger a failover."
+ {{- $masterGroupName := include "redis-ha.masterGroupName" . }}
+ response=$(
+ redis-cli \
+ {{- if .Values.sentinel.auth }}
+ -a "${SENTINELAUTH}" --no-auth-warning \
+ {{- end }}
+ -h localhost \
+ {{- if (int .Values.sentinel.port) }}
+ -p {{ .Values.sentinel.port }} \
+ {{- else }}
+ -p {{ .Values.sentinel.tlsPort }} ${TLS_CLIENT_OPTION} \
+ {{- end}}
+ SENTINEL failover {{ $masterGroupName }}
+ )
+ if [[ "$response" != "OK" ]] ; then
+ echo "$response"
+ exit 1
+ fi
+ timeout=30
+ while [[ "$is_master" -eq 1 && $timeout -gt 0 ]]; do
+ sleep 1
+ get_redis_role
+ timeout=$((timeout - 1))
+ done
+ echo "Failover successful"
+ fi
+{{- end }}
+
+{{- define "fix-split-brain.sh" }}
+ {{- include "vars.sh" . }}
+
+ ROLE=''
+ REDIS_MASTER=''
+
+ set -eu
+
+ {{- include "lib.sh" . }}
+
+ redis_role() {
+ set +e
+ if [ "$REDIS_PORT" -eq 0 ]; then
+ ROLE=$(redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} info | grep role | sed 's/role://' | sed 's/\r//')
+ else
+ ROLE=$(redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//')
+ fi
+ set -e
+ }
+
+ identify_redis_master() {
+ set +e
+ if [ "$REDIS_PORT" -eq 0 ]; then
+ REDIS_MASTER=$(redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} info | grep master_host | sed 's/master_host://' | sed 's/\r//')
+ else
+ REDIS_MASTER=$(redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//')
+ fi
+ set -e
+ }
+
+ reinit() {
+ set +e
+ sh /readonly-config/init.sh
+
+ if [ "$REDIS_PORT" -eq 0 ]; then
+ echo "shutdown" | redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }}
+ else
+ echo "shutdown" | redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_PORT}"
+ fi
+ set -e
+ }
+
+ identify_announce_ip
+
+ while [ -z "${ANNOUNCE_IP}" ]; do
+ echo "Error: Could not resolve the announce ip for this pod."
+ sleep 30
+ identify_announce_ip
+ done
+
+ trap "exit 0" TERM
+ while true; do
+ sleep {{ .Values.splitBrainDetection.interval }}
+
+ # where is redis master
+ identify_master
+
+ if [ "$MASTER" = "$ANNOUNCE_IP" ]; then
+ redis_role
+ if [ "$ROLE" != "master" ]; then
+ reinit
+ fi
+ elif [ "${MASTER}" ]; then
+ identify_redis_master
+ if [ "$REDIS_MASTER" != "$MASTER" ]; then
+ reinit
+ fi
+ fi
+ done
+
+{{- end }}
+
+{{- define "config-haproxy.cfg" }}
+{{- if .Values.haproxy.customConfig }}
+{{ tpl .Values.haproxy.customConfig . | indent 4 }}
+{{- else }}
+ defaults REDIS
+ mode tcp
+ timeout connect {{ .Values.haproxy.timeout.connect }}
+ timeout server {{ .Values.haproxy.timeout.server }}
+ timeout client {{ .Values.haproxy.timeout.client }}
+ timeout check {{ .Values.haproxy.timeout.check }}
+
+ listen health_check_http_url
+ bind {{ if .Values.haproxy.IPv6.enabled }}[::]{{ end }}:8888 {{ if .Values.haproxy.IPv6.enabled }}v4v6{{ end }}
+ mode http
+ monitor-uri /healthz
+ option dontlognull
+
+ {{- $root := . }}
+ {{- $fullName := include "redis-ha.fullname" . }}
+ {{- $replicas := int (toString .Values.replicas) }}
+ {{- $masterGroupName := include "redis-ha.masterGroupName" . }}
+ {{- range $i := until $replicas }}
+ # Check Sentinel and whether they are nominated master
+ backend check_if_redis_is_master_{{ $i }}
+ mode tcp
+ option tcp-check
+ tcp-check connect
+ {{- if $root.Values.sentinel.auth }}
+ tcp-check send "AUTH ${SENTINELAUTH}"\r\n
+ tcp-check expect string +OK
+ {{- end }}
+ tcp-check send PING\r\n
+ tcp-check expect string +PONG
+ tcp-check send SENTINEL\ get-master-addr-by-name\ {{ $masterGroupName }}\r\n
+ tcp-check expect string REPLACE_ANNOUNCE{{ $i }}
+ tcp-check send QUIT\r\n
+ {{- range $i := until $replicas }}
+ server R{{ $i }} {{ $fullName }}-announce-{{ $i }}:26379 check inter {{ $root.Values.haproxy.checkInterval }}
+ {{- end }}
+ {{- end }}
+
+ # decide redis backend to use
+ #master
+ frontend ft_redis_master
+ {{- if .Values.haproxy.tls.enabled }}
+ bind {{ if .Values.haproxy.IPv6.enabled }}[::]{{ end }}:{{ $root.Values.haproxy.containerPort }} ssl crt {{ .Values.haproxy.tls.certMountPath }}{{ .Values.haproxy.tls.keyName }} {{ if .Values.haproxy.IPv6.enabled }}v4v6{{ end }}
+ {{ else }}
+ bind {{ if .Values.haproxy.IPv6.enabled }}[::]{{ end }}:{{ if ne (int $root.Values.redis.port) 0 }}{{ $root.Values.redis.port }}{{ else }}{{ $root.Values.redis.tlsPort }}{{ end }} {{ if .Values.haproxy.IPv6.enabled }}v4v6{{ end }}
+ {{- end }}
+ use_backend bk_redis_master
+ {{- if .Values.haproxy.readOnly.enabled }}
+ #slave
+ frontend ft_redis_slave
+ bind {{ if .Values.haproxy.IPv6.enabled }}[::]{{ end }}:{{ .Values.haproxy.readOnly.port }} {{ if .Values.haproxy.IPv6.enabled }}v4v6{{ end }}
+ use_backend bk_redis_slave
+ {{- end }}
+ # Check all redis servers to see if they think they are master
+ backend bk_redis_master
+ {{- if .Values.haproxy.stickyBalancing }}
+ balance source
+ hash-type consistent
+ {{- end }}
+ mode tcp
+ option tcp-check
+ tcp-check connect
+ {{- if .Values.auth }}
+ tcp-check send "AUTH ${AUTH}"\r\n
+ tcp-check expect string +OK
+ {{- end }}
+ tcp-check send PING\r\n
+ tcp-check expect string +PONG
+ tcp-check send info\ replication\r\n
+ tcp-check expect string role:master
+ tcp-check send QUIT\r\n
+ tcp-check expect string +OK
+ {{- range $i := until $replicas }}
+ use-server R{{ $i }} if { srv_is_up(R{{ $i }}) } { nbsrv(check_if_redis_is_master_{{ $i }}) ge 2 }
+ server R{{ $i }} {{ $fullName }}-announce-{{ $i }}:{{ $root.Values.redis.port }} check inter {{ $root.Values.haproxy.checkInterval }} fall {{ $root.Values.haproxy.checkFall }} rise 1
+ {{- end }}
+ {{- if .Values.haproxy.readOnly.enabled }}
+ backend bk_redis_slave
+ {{- if .Values.haproxy.stickyBalancing }}
+ balance source
+ hash-type consistent
+ {{- end }}
+ mode tcp
+ option tcp-check
+ tcp-check connect
+ {{- if .Values.auth }}
+ tcp-check send "AUTH ${AUTH}"\r\n
+ tcp-check expect string +OK
+ {{- end }}
+ tcp-check send PING\r\n
+ tcp-check expect string +PONG
+ tcp-check send info\ replication\r\n
+ tcp-check expect string role:slave
+ tcp-check send QUIT\r\n
+ tcp-check expect string +OK
+ {{- range $i := until $replicas }}
+ server R{{ $i }} {{ $fullName }}-announce-{{ $i }}:{{ $root.Values.redis.port }} check inter {{ $root.Values.haproxy.checkInterval }} fall {{ $root.Values.haproxy.checkFall }} rise 1
+ {{- end }}
+ {{- end }}
+ {{- if .Values.haproxy.metrics.enabled }}
+ frontend stats
+ mode http
+ bind {{ if .Values.haproxy.IPv6.enabled }}[::]{{ end }}:{{ .Values.haproxy.metrics.port }} {{ if .Values.haproxy.IPv6.enabled }}v4v6{{ end }}
+ http-request use-service prometheus-exporter if { path {{ .Values.haproxy.metrics.scrapePath }} }
+ stats enable
+ stats uri /stats
+ stats refresh 10s
+ {{- end }}
+{{- if .Values.haproxy.extraConfig }}
+ # Additional configuration
+{{ .Values.haproxy.extraConfig | indent 4 }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+
+{{- define "config-haproxy_init.sh" }}
+ HAPROXY_CONF=/data/haproxy.cfg
+ cp /readonly/haproxy.cfg "$HAPROXY_CONF"
+ {{- $fullName := include "redis-ha.fullname" . }}
+ {{- $replicas := int (toString .Values.replicas) }}
+ {{- range $i := until $replicas }}
+ for loop in $(seq 1 10); do
+ getent hosts {{ $fullName }}-announce-{{ $i }} && break
+ echo "Waiting for service {{ $fullName }}-announce-{{ $i }} to be ready ($loop) ..." && sleep 1
+ done
+ ANNOUNCE_IP{{ $i }}=$(getent hosts "{{ $fullName }}-announce-{{ $i }}" | awk '{ print $1 }')
+ if [ -z "$ANNOUNCE_IP{{ $i }}" ]; then
+ echo "Could not resolve the announce ip for {{ $fullName }}-announce-{{ $i }}"
+ exit 1
+ fi
+ sed -i "s/REPLACE_ANNOUNCE{{ $i }}/$ANNOUNCE_IP{{ $i }}/" "$HAPROXY_CONF"
+
+ {{- end }}
+{{- end }}
+
+{{- define "redis_liveness.sh" }}
+ {{- if not (ne (int .Values.sentinel.port) 0) }}
+ TLS_CLIENT_OPTION="--tls --cacert /tls-certs/{{ .Values.tls.caCertFile }}{{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{end}}"
+ {{- end }}
+ response=$(
+ redis-cli \
+ {{- if .Values.auth }}
+ -a "${AUTH}" --no-auth-warning \
+ {{- end }}
+ -h localhost \
+ {{- if ne (int .Values.redis.port) 0 }}
+ -p {{ .Values.redis.port }} \
+ {{- else }}
+ -p {{ .Values.redis.tlsPort }} ${TLS_CLIENT_OPTION} \
+ {{- end}}
+ ping
+ )
+ echo "response=$response"
+ case $response in
+ PONG|LOADING*) ;;
+ *) exit 1 ;;
+ esac
+ exit 0
+{{- end }}
+
+{{- define "redis_readiness.sh" }}
+ {{- if not (ne (int .Values.sentinel.port) 0) }}
+ TLS_CLIENT_OPTION="--tls --cacert /tls-certs/{{ .Values.tls.caCertFile }}{{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{end}}"
+ {{- end }}
+ response=$(
+ redis-cli \
+ {{- if .Values.auth }}
+ -a "${AUTH}" --no-auth-warning \
+ {{- end }}
+ -h localhost \
+ {{- if ne (int .Values.redis.port) 0 }}
+ -p {{ .Values.redis.port }} \
+ {{- else }}
+ -p {{ .Values.redis.tlsPort }} ${TLS_CLIENT_OPTION} \
+ {{- end}}
+ ping
+ )
+ if [ "$response" != "PONG" ] ; then
+ echo "ping=$response"
+ exit 1
+ fi
+
+ response=$(
+ redis-cli \
+ {{- if .Values.auth }}
+ -a "${AUTH}" --no-auth-warning \
+ {{- end }}
+ -h localhost \
+ {{- if ne (int .Values.redis.port) 0 }}
+ -p {{ .Values.redis.port }} \
+ {{- else }}
+ -p {{ .Values.redis.tlsPort }} ${TLS_CLIENT_OPTION} \
+ {{- end}}
+ role
+ )
+ role=$( echo "$response" | sed "1!d" )
+ if [ "$role" = "master" ]; then
+ echo "role=$role"
+ exit 0
+ elif [ "$role" = "slave" ]; then
+ repl=$( echo "$response" | sed "4!d" )
+ echo "role=$role; repl=$repl"
+ if [ "$repl" = "connected" ]; then
+ exit 0
+ else
+ exit 1
+ fi
+ else
+ echo "role=$role"
+ exit 1
+ fi
+{{- end }}
+
+{{- define "sentinel_liveness.sh" }}
+ {{- if not (ne (int .Values.sentinel.port) 0) }}
+ TLS_CLIENT_OPTION="--tls --cacert /tls-certs/{{ .Values.tls.caCertFile }}{{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{end}}"
+ {{- end }}
+ response=$(
+ redis-cli \
+ {{- if .Values.sentinel.auth }}
+ -a "${SENTINELAUTH}" --no-auth-warning \
+ {{- end }}
+ -h localhost \
+ {{- if ne (int .Values.sentinel.port) 0 }}
+ -p {{ .Values.sentinel.port }} \
+ {{- else }}
+ -p {{ .Values.sentinel.tlsPort }} ${TLS_CLIENT_OPTION} \
+ {{- end}}
+ ping
+ )
+ if [ "$response" != "PONG" ]; then
+ echo "$response"
+ exit 1
+ fi
+ echo "response=$response"
+{{- end }}
+
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/_helpers.tpl b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/_helpers.tpl
new file mode 100644
index 0000000..047e05f
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/_helpers.tpl
@@ -0,0 +1,130 @@
+{{/* vim: set filetype=mustache: */}}
+
+{{/*
+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 "redis-ha.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 "redis-ha.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 -}}
+
+
+{{/*
+Return sysctl image
+*/}}
+{{- define "redis.sysctl.image" -}}
+{{- $registryName := default "docker.io" .Values.sysctlImage.registry -}}
+{{- $tag := default "latest" .Values.sysctlImage.tag | toString -}}
+{{- printf "%s/%s:%s" $registryName .Values.sysctlImage.repository $tag -}}
+{{- end -}}
+
+{{- /*
+Credit: @technosophos
+https://github.com/technosophos/common-chart/
+labels.standard prints the standard Helm labels.
+The standard labels are frequently used in metadata.
+*/ -}}
+{{- define "labels.standard" -}}
+app: {{ template "redis-ha.name" . }}
+heritage: {{ .Release.Service | quote }}
+release: {{ .Release.Name | quote }}
+chart: {{ template "chartref" . }}
+{{- end -}}
+
+{{- /*
+Credit: @technosophos
+https://github.com/technosophos/common-chart/
+chartref prints a chart name and version.
+It does minimal escaping for use in Kubernetes labels.
+Example output:
+ zookeeper-1.2.3
+ wordpress-3.2.1_20170219
+*/ -}}
+{{- define "chartref" -}}
+ {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "redis-ha.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+ {{ default (include "redis-ha.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+ {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
+
+{{- define "redis-ha.masterGroupName" -}}
+{{- $masterGroupName := tpl ( .Values.redis.masterGroupName | default "") . -}}
+{{- $validMasterGroupName := regexMatch "^[\\w-\\.]+$" $masterGroupName -}}
+{{- if $validMasterGroupName -}}
+{{ $masterGroupName }}
+{{- else -}}
+{{ required "A valid .Values.redis.masterGroupName entry is required (matching ^[\\w-\\.]+$)" ""}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Return the appropriate apiVersion for poddisruptionbudget.
+*/}}
+{{- define "redis-ha.podDisruptionBudget.apiVersion" -}}
+{{- if .Capabilities.APIVersions.Has "policy/v1" }}
+{{- print "policy/v1" -}}
+{{- else -}}
+{{- print "policy/v1beta1" -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Return true if the detected platform is Openshift
+Usage:
+{{- include "common.compatibility.isOpenshift" . -}}
+*/}}
+{{- define "compatibility.isOpenshift" -}}
+{{- if .Capabilities.APIVersions.Has "security.openshift.io/v1" -}}
+{{- true -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Render a compatible securityContext depending on the platform. By default it is maintained as it is. In other platforms like Openshift we remove default user/group values that do not work out of the box with the restricted-v1 SCC
+Usage:
+{{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) -}}
+*/}}
+{{- define "compatibility.renderSecurityContext" -}}
+{{- $adaptedContext := .secContext -}}
+
+{{- if (((.context.Values.global).compatibility).openshift) -}}
+ {{- if or (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "force") (and (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "auto") (include "compatibility.isOpenshift" .context)) -}}
+ {{/* Remove incompatible user/group values that do not work in Openshift out of the box */}}
+ {{- $adaptedContext = omit $adaptedContext "fsGroup" "runAsUser" "runAsGroup" -}}
+ {{- if not .secContext.seLinuxOptions -}}
+ {{/* If it is an empty object, we remove it from the resulting context because it causes validation issues */}}
+ {{- $adaptedContext = omit $adaptedContext "seLinuxOptions" -}}
+ {{- end -}}
+ {{- end -}}
+{{- end -}}
+{{/* Remove fields that are disregarded when running the container in privileged mode */}}
+{{- if $adaptedContext.privileged -}}
+ {{- $adaptedContext = omit $adaptedContext "capabilities" "seLinuxOptions" -}}
+{{- end -}}
+{{- omit $adaptedContext "enabled" | toYaml -}}
+{{- end -}} \ No newline at end of file
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-auth-secret.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-auth-secret.yaml
new file mode 100644
index 0000000..a1fd631
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-auth-secret.yaml
@@ -0,0 +1,15 @@
+{{- if and .Values.auth (not .Values.existingSecret) -}}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ template "redis-ha.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+type: Opaque
+data:
+ {{ .Values.authKey }}: {{ .Values.redisPassword | b64enc | quote }}
+{{- end -}}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-announce-service.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-announce-service.yaml
new file mode 100644
index 0000000..dc24249
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-announce-service.yaml
@@ -0,0 +1,64 @@
+{{- $fullName := include "redis-ha.fullname" . }}
+{{- $namespace := .Release.Namespace -}}
+{{- $replicas := int (toString .Values.replicas) }}
+{{- $root := . }}
+{{- range $i := until $replicas }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ $fullName }}-announce-{{ $i }}
+ namespace: {{ $namespace | quote}}
+ labels:
+{{ include "labels.standard" $root | indent 4 }}
+ {{- range $key, $value := $root.Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ annotations:
+{{- if (semverCompare "<=1.10-0" $.Capabilities.KubeVersion.GitVersion) }}
+ service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
+{{- end }}
+ {{- if $root.Values.serviceAnnotations }}
+{{ toYaml $root.Values.serviceAnnotations | indent 4 }}
+ {{- end }}
+spec:
+{{- if (semverCompare ">=1.11-0" $.Capabilities.KubeVersion.GitVersion) }}
+ publishNotReadyAddresses: true
+{{- end }}
+ type: ClusterIP
+ ports:
+ {{- if ne (int $root.Values.redis.port) 0 }}
+ - name: tcp-server
+ port: {{ $root.Values.redis.port }}
+ protocol: TCP
+ targetPort: redis
+ {{- end }}
+ {{- if $root.Values.redis.tlsPort }}
+ - name: server-tls
+ port: {{ $root.Values.redis.tlsPort }}
+ protocol: TCP
+ targetPort: redis-tls
+ {{- end }}
+ {{- if ne (int $root.Values.sentinel.port) 0 }}
+ - name: tcp-sentinel
+ port: {{ $root.Values.sentinel.port }}
+ protocol: TCP
+ targetPort: sentinel
+ {{- end }}
+ {{- if $root.Values.sentinel.tlsPort }}
+ - name: sentinel-tls
+ port: {{ $root.Values.sentinel.tlsPort }}
+ protocol: TCP
+ targetPort: sentinel-tls
+ {{- end }}
+ {{- if $root.Values.exporter.enabled }}
+ - name: http-exporter
+ port: {{ $root.Values.exporter.port }}
+ protocol: TCP
+ targetPort: {{ $root.Values.exporter.portName }}
+ {{- end }}
+ selector:
+ release: {{ $root.Release.Name }}
+ app: {{ include "redis-ha.name" $root }}
+ "statefulset.kubernetes.io/pod-name": {{ $fullName }}-server-{{ $i }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-configmap.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-configmap.yaml
new file mode 100644
index 0000000..48f2b03
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-configmap.yaml
@@ -0,0 +1,37 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-configmap
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+ chart: {{ .Chart.Name }}-{{ .Chart.Version }}
+ app: {{ template "redis-ha.fullname" . }}
+ {{- range $key, $value := .Values.configmap.labels }}
+ {{ $key }}: {{ $value | toString }}
+ {{- end }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+data:
+ redis.conf: |
+{{- include "config-redis.conf" . }}
+
+ sentinel.conf: |
+{{- include "config-sentinel.conf" . }}
+
+ init.sh: |
+{{- include "config-init.sh" . }}
+
+ fix-split-brain.sh: |
+{{- include "fix-split-brain.sh" . }}
+
+{{ if .Values.haproxy.enabled }}
+ haproxy.cfg: |
+{{- include "config-haproxy.cfg" . }}
+{{- end }}
+ haproxy_init.sh: |
+{{- include "config-haproxy_init.sh" . }}
+ trigger-failover-if-master.sh: |
+{{- include "trigger-failover-if-master.sh" . }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-exporter-script-configmap.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-exporter-script-configmap.yaml
new file mode 100644
index 0000000..a649df4
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-exporter-script-configmap.yaml
@@ -0,0 +1,14 @@
+{{- if .Values.exporter.script }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-exporter-script-configmap
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+data:
+ script: {{ toYaml .Values.exporter.script | indent 2 }}
+{{- end }} \ No newline at end of file
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-health-configmap.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-health-configmap.yaml
new file mode 100644
index 0000000..7aa7002
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-health-configmap.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-health-configmap
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+ chart: {{ .Chart.Name }}-{{ .Chart.Version }}
+ app: {{ template "redis-ha.fullname" . }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+data:
+ redis_liveness.sh: |
+{{- include "redis_liveness.sh" . }}
+ redis_readiness.sh: |
+{{- include "redis_readiness.sh" . }}
+ sentinel_liveness.sh: |
+{{- include "sentinel_liveness.sh" . }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-network-policy.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-network-policy.yaml
new file mode 100644
index 0000000..8f688ca
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-network-policy.yaml
@@ -0,0 +1,80 @@
+{{- if .Values.networkPolicy.enabled }}
+{{- $root := . }}
+kind: NetworkPolicy
+apiVersion: networking.k8s.io/v1
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-network-policy
+ namespace: {{ .Release.Namespace | quote }}
+{{- if .Values.networkPolicy.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.networkPolicy.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+{{- end }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.networkPolicy.labels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+spec:
+ podSelector:
+ matchLabels:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}
+ policyTypes:
+ - Ingress
+ - Egress
+ egress:
+ - to:
+ - podSelector:
+ matchLabels:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}
+ ports:
+ - port: {{ .Values.redis.port }}
+ protocol: TCP
+ - port: {{ .Values.sentinel.port }}
+ protocol: TCP
+{{- range $rule := .Values.networkPolicy.egressRules }}
+ - to:
+{{ (tpl (toYaml $rule.selectors) $) | indent 7 }}
+ ports:
+{{ toYaml $rule.ports | indent 7 }}
+{{- end }}
+ ingress:
+ - from:
+ - podSelector:
+ matchLabels:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}
+ ports:
+ - port: {{ .Values.redis.port }}
+ protocol: TCP
+ - port: {{ .Values.sentinel.port }}
+ protocol: TCP
+{{- if .Values.haproxy.enabled }}
+ - from:
+ - podSelector:
+ matchLabels:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}-haproxy
+ ports:
+ - port: {{ .Values.redis.port }}
+ protocol: TCP
+ - port: {{ .Values.sentinel.port }}
+ protocol: TCP
+{{- end }}
+{{- range $rule := .Values.networkPolicy.ingressRules }}
+ - from:
+{{ (tpl (toYaml $rule.selectors) $) | indent 7 }}
+ ports:
+{{- if $rule.ports }}
+{{ toYaml $rule.ports | indent 7 }}
+{{- else }}
+ - port: {{ $root.Values.redis.port }}
+ protocol: TCP
+ - port: {{ $root.Values.sentinel.port }}
+ protocol: TCP
+{{- end }}
+{{- end }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-pdb.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-pdb.yaml
new file mode 100644
index 0000000..fbcb506
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-pdb.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.podDisruptionBudget -}}
+apiVersion: {{ template "redis-ha.podDisruptionBudget.apiVersion" . }}
+kind: PodDisruptionBudget
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-pdb
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+spec:
+ selector:
+ matchLabels:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}
+{{ toYaml .Values.podDisruptionBudget | indent 2 }}
+{{- end -}}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-prometheus-rule.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-prometheus-rule.yaml
new file mode 100644
index 0000000..e163481
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-prometheus-rule.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.prometheusRule.enabled }}
+apiVersion: monitoring.coreos.com/v1
+kind: PrometheusRule
+metadata:
+ name: {{ template "redis-ha.fullname" . }}
+ {{- if .Values.prometheusRule.namespace }}
+ namespace: {{ .Values.prometheusRule.namespace }}
+ {{- end }}
+ labels: {{- toYaml .Values.prometheusRule.additionalLabels | nindent 4 }}
+spec:
+ groups:
+ - name: {{ template "redis-ha.fullname" . }}
+ {{- if .Values.prometheusRule.interval }}
+ interval: {{ .Values.prometheusRule.interval }}
+ {{- end }}
+ rules: {{- tpl (toYaml .Values.prometheusRule.rules) . | nindent 8 }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-role.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-role.yaml
new file mode 100644
index 0000000..aa65cce
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-role.yaml
@@ -0,0 +1,19 @@
+{{- if and .Values.serviceAccount.create .Values.rbac.create }}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: {{ template "redis-ha.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - endpoints
+ verbs:
+ - get
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-rolebinding.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-rolebinding.yaml
new file mode 100644
index 0000000..402ba0d
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-rolebinding.yaml
@@ -0,0 +1,19 @@
+{{- if and .Values.serviceAccount.create .Values.rbac.create }}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: {{ template "redis-ha.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+subjects:
+- kind: ServiceAccount
+ name: {{ template "redis-ha.serviceAccountName" . }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: {{ template "redis-ha.fullname" . }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-secret.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-secret.yaml
new file mode 100644
index 0000000..91cc7f2
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-secret.yaml
@@ -0,0 +1,32 @@
+{{- if not .Values.restore.existingSecret }}
+
+
+{{- $regexRestoreS3 := "^s3://.+|^S3://.+" -}}
+{{- $regexRestoreSSH := "^.+@.+:.+" -}}
+
+{{- if or (regexFind $regexRestoreSSH (toString .Values.restore.ssh.source)) (regexFind $regexRestoreS3 (toString .Values.restore.s3.source)) }}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ include "redis-ha.fullname" . }}-secret
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+ chart: {{ .Chart.Name }}-{{ .Chart.Version }}
+ app: {{ template "redis-ha.fullname" . }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+type: Opaque
+data:
+{{- if regexFind $regexRestoreSSH (toString .Values.restore.ssh.source) }}
+ SSH_KEY: "{{ .Values.restore.ssh.key | b64enc }}"
+{{- end }}
+{{- if regexFind $regexRestoreS3 (toString .Values.restore.s3.source) }}
+ AWS_SECRET_ACCESS_KEY: "{{ .Values.restore.s3.secret_key | b64enc }}"
+ AWS_ACCESS_KEY_ID: "{{ .Values.restore.s3.access_key | b64enc }}"
+{{- end }}
+{{- end }}
+
+{{- end }} \ No newline at end of file
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-service.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-service.yaml
new file mode 100644
index 0000000..5fe077e
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-service.yaml
@@ -0,0 +1,57 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "redis-ha.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+{{- if .Values.exporter.enabled }}
+ exporter: enabled
+{{- end }}
+{{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+{{- end }}
+{{- range $key, $value := .Values.serviceLabels }}
+ {{ $key }}: {{ $value | quote }}
+{{- end }}
+ annotations:
+ {{- if .Values.serviceAnnotations }}
+{{ toYaml .Values.serviceAnnotations | indent 4 }}
+ {{- end }}
+spec:
+ type: ClusterIP
+ clusterIP: None
+ ports:
+ {{- if ne (int .Values.redis.port) 0 }}
+ - name: tcp-server
+ port: {{ .Values.redis.port }}
+ protocol: TCP
+ targetPort: redis
+ {{- end }}
+ {{- if .Values.redis.tlsPort }}
+ - name: server-tls
+ port: {{ .Values.redis.tlsPort }}
+ protocol: TCP
+ targetPort: redis-tls
+ {{- end }}
+ {{- if ne (int .Values.sentinel.port) 0 }}
+ - name: tcp-sentinel
+ port: {{ .Values.sentinel.port }}
+ protocol: TCP
+ targetPort: sentinel
+ {{- end }}
+ {{- if .Values.sentinel.tlsPort }}
+ - name: sentinel-tls
+ port: {{ .Values.sentinel.tlsPort }}
+ protocol: TCP
+ targetPort: sentinel-tls
+ {{- end }}
+{{- if .Values.exporter.enabled }}
+ - name: http-exporter-port
+ port: {{ .Values.exporter.port }}
+ protocol: TCP
+ targetPort: {{ .Values.exporter.portName }}
+{{- end }}
+ selector:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-serviceaccount.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-serviceaccount.yaml
new file mode 100644
index 0000000..9e1b21e
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-serviceaccount.yaml
@@ -0,0 +1,31 @@
+{{- if .Values.serviceAccount.create }}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ template "redis-ha.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+ chart: {{ .Chart.Name }}-{{ .Chart.Version }}
+ app: {{ template "redis-ha.fullname" . }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+{{- if .Values.serviceAccount.annotations }}
+ annotations:
+{{ toYaml .Values.serviceAccount.annotations | indent 4 }}
+{{- end }}
+{{- if or .Values.auth .Values.sentinel.auth }}
+secrets:
+{{- end }}
+{{- if .Values.auth }}
+- name: {{ default (include "redis-ha.fullname" .) .Values.existingSecret }}
+{{- end }}
+{{- if .Values.sentinel.auth }}
+- name: {{ default (printf "%s-sentinel" (include "redis-ha.fullname" .)) .Values.sentinel.existingSecret }}
+{{- end }}
+{{- if .Values.imagePullSecrets }}
+imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 0 }}
+{{- end }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-servicemonitor.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-servicemonitor.yaml
new file mode 100644
index 0000000..6b374a8
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-servicemonitor.yaml
@@ -0,0 +1,39 @@
+{{- if and ( or .Values.exporter.serviceMonitor.disableAPICheck ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) ) ( .Values.exporter.serviceMonitor.enabled ) ( .Values.exporter.enabled ) }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ template "redis-ha.fullname" . }}
+ namespace: {{ .Values.exporter.serviceMonitor.namespace | default .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ {{- range $key, $value := .Values.exporter.serviceMonitor.labels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+spec:
+ endpoints:
+ - targetPort: {{ .Values.exporter.port }}
+{{- if .Values.exporter.serviceMonitor.interval }}
+ interval: {{ .Values.exporter.serviceMonitor.interval }}
+{{- end }}
+{{- if .Values.exporter.serviceMonitor.telemetryPath }}
+ path: {{ .Values.exporter.serviceMonitor.telemetryPath }}
+{{- end }}
+{{- if .Values.exporter.serviceMonitor.timeout }}
+ scrapeTimeout: {{ .Values.exporter.serviceMonitor.timeout }}
+{{- end }}
+{{- with .Values.exporter.serviceMonitor.endpointAdditionalProperties }}
+{{- toYaml . | nindent 4 }}
+{{- end }}
+ jobLabel: {{ template "redis-ha.fullname" . }}
+ namespaceSelector:
+ matchNames:
+ - {{ .Release.Namespace | quote }}
+ selector:
+ matchLabels:
+ app: {{ template "redis-ha.name" . }}
+ release: {{ .Release.Name }}
+ exporter: enabled
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-statefulset.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-statefulset.yaml
new file mode 100644
index 0000000..1351ab1
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-statefulset.yaml
@@ -0,0 +1,668 @@
+{{- $regexRestoreS3 := "^s3://.+|^S3://.+" -}}
+{{- $regexRestoreSSH := "^.+@.+:.+" -}}
+{{- $regexRestoreRedis := "^redis://(?:[A-Za-z0-9_]+(?::[^@]+)?@)?[A-Za-z0-9.-]+(?::\\d{1,5})?(?:/\\d+)?$" -}}
+
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-server
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ {{ template "redis-ha.fullname" . }}: replica
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+{{ include "labels.standard" . | indent 4 }}
+ annotations:
+{{ toYaml .Values.redis.annotations | indent 4 }}
+spec:
+ selector:
+ matchLabels:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}
+ serviceName: {{ template "redis-ha.fullname" . }}
+ replicas: {{ .Values.replicas }}
+ podManagementPolicy: {{ .Values.podManagementPolicy }}
+ updateStrategy:
+ type: {{ .Values.redis.updateStrategy.type }}
+ {{- if .Values.redis.minReadySeconds }}
+ minReadySeconds: {{ .Values.redis.minReadySeconds }}
+ {{- end }}
+ template:
+ metadata:
+ annotations:
+ checksum/init-config: {{ print (include "config-redis.conf" .) (include "config-sentinel.conf" .) (include "config-init.sh" .) (include "fix-split-brain.sh" .) (include "redis_liveness.sh" .) (include "redis_readiness.sh" .) (include "sentinel_liveness.sh" .) (include "trigger-failover-if-master.sh" .)| sha256sum }}
+ {{- if .Values.podAnnotations }}
+{{ toYaml .Values.podAnnotations | indent 8 }}
+ {{- end }}
+ {{- if and (.Values.exporter.enabled) (not .Values.exporter.serviceMonitor.enabled) }}
+ prometheus.io/port: "{{ .Values.exporter.port }}"
+ prometheus.io/scrape: "true"
+ prometheus.io/path: {{ .Values.exporter.scrapePath }}
+ {{- end }}
+ labels:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}
+ {{ template "redis-ha.fullname" . }}: replica
+ {{- range $key, $value := .Values.labels }}
+ {{ $key }}: {{ $value | toString }}
+ {{- end }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ spec:
+ {{- if .Values.redis.terminationGracePeriodSeconds }}
+ terminationGracePeriodSeconds: {{ .Values.redis.terminationGracePeriodSeconds }}
+ {{- end }}
+ {{- if .Values.schedulerName }}
+ schedulerName: "{{ .Values.schedulerName }}"
+ {{- end }}
+ {{- if .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml .Values.nodeSelector | indent 8 }}
+ {{- end }}
+ {{- if .Values.tolerations }}
+ tolerations:
+{{ toYaml .Values.tolerations | indent 8 }}
+ {{- end }}
+ affinity:
+ {{- if .Values.affinity }}
+ {{- with .Values.affinity }}
+{{ tpl . $ | indent 8 }}
+ {{- end }}
+ {{- else }}
+ {{- if .Values.additionalAffinities }}
+{{ toYaml .Values.additionalAffinities | indent 8 }}
+ {{- end }}
+ podAntiAffinity:
+ {{- if .Values.hardAntiAffinity }}
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchLabels:
+ app: {{ template "redis-ha.name" . }}
+ release: {{ .Release.Name }}
+ {{ template "redis-ha.fullname" . }}: replica
+ topologyKey: kubernetes.io/hostname
+ {{- else }}
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - weight: 100
+ podAffinityTerm:
+ labelSelector:
+ matchLabels:
+ app: {{ template "redis-ha.name" . }}
+ release: {{ .Release.Name }}
+ {{ template "redis-ha.fullname" . }}: replica
+ topologyKey: kubernetes.io/hostname
+ {{- end }}
+ {{- end }}
+ {{- if .Values.topologySpreadConstraints.enabled }}
+ topologySpreadConstraints:
+ - maxSkew: {{ .Values.topologySpreadConstraints.maxSkew | default 1 }}
+ topologyKey: {{ .Values.topologySpreadConstraints.topologyKey | default "topology.kubernetes.io/zone" }}
+ whenUnsatisfiable: {{ .Values.topologySpreadConstraints.whenUnsatisfiable | default "ScheduleAnyway" }}
+ labelSelector:
+ matchLabels:
+ app: {{ template "redis-ha.name" . }}
+ release: {{ .Release.Name }}
+ {{ template "redis-ha.fullname" . }}: replica
+ {{- end }}
+ {{- if .Values.imagePullSecrets }}
+ imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }}
+ {{- end }}
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.securityContext "context" $) | nindent 8 }}
+ serviceAccountName: {{ template "redis-ha.serviceAccountName" . }}
+ automountServiceAccountToken: {{ .Values.serviceAccount.automountToken }}
+ initContainers:
+ {{- if .Values.sysctlImage.enabled }}
+ - name: init-sysctl
+ image: {{ template "redis.sysctl.image" . }}
+ imagePullPolicy: {{ .Values.sysctlImage.pullPolicy }}
+ resources: {{ toYaml .Values.sysctlImage.resources | nindent 10 }}
+ {{- if .Values.sysctlImage.mountHostSys }}
+ volumeMounts:
+ - name: host-sys
+ mountPath: /host-sys
+ {{- end }}
+ command: {{ toYaml .Values.sysctlImage.command | nindent 10 }}
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
+ {{- end }}
+{{- if and .Values.hostPath.path .Values.hostPath.chown }}
+ - name: hostpath-chown
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
+ command:
+ - chown
+ - "{{ .Values.containerSecurityContext.runAsUser }}"
+ - /data
+ volumeMounts:
+ - name: data
+ mountPath: /data
+{{- end }}
+ - name: config-init
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ resources:
+{{ toYaml .Values.init.resources | indent 10 }}
+ command:
+ - sh
+ args:
+ - /readonly-config/init.sh
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
+ env:
+{{- $replicas := int (toString .Values.replicas) -}}
+{{- range $i := until $replicas }}
+ - name: SENTINEL_ID_{{ $i }}
+ value: {{ printf "%s\n%s\nindex: %d" (include "redis-ha.name" $) ($.Release.Name) $i | sha256sum | trunc 40 }}
+{{- end }}
+{{- if .Values.auth }}
+ - name: AUTH
+ valueFrom:
+ secretKeyRef:
+ {{- if .Values.existingSecret }}
+ name: {{ .Values.existingSecret }}
+ {{- else }}
+ name: {{ template "redis-ha.fullname" . }}
+ {{- end }}
+ key: {{ .Values.authKey }}
+{{- end }}
+{{- if .Values.sentinel.auth }}
+ - name: SENTINELAUTH
+ valueFrom:
+ secretKeyRef:
+ {{- if .Values.sentinel.existingSecret }}
+ name: {{ .Values.sentinel.existingSecret }}
+ {{- else }}
+ name: {{ template "redis-ha.fullname" . }}-sentinel
+ {{- end }}
+ key: {{ .Values.sentinel.authKey }}
+{{- end }}
+ volumeMounts:
+ - name: config
+ mountPath: /readonly-config
+ readOnly: true
+ - name: data
+ mountPath: /data
+ {{- if .Values.redis.tlsPort }}
+ - mountPath: /tls-certs
+ name: tls-certs
+ {{- end}}
+{{ if regexFind $regexRestoreS3 (toString .Values.restore.s3.source) }}
+ - name: restore-s3
+ image: s3cmd/s3cmd:latest
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ resources:
+{{ toYaml .Values.init.resources | indent 10 }}
+ command:
+ - sh
+ args:
+ - "-c"
+ - "timeout -t {{ .Values.restore.timeout }} \
+ s3cmd get {{ if .Values.restore.s3.region }}--region {{ .Values.restore.s3.region }} {{ end }}--force '{{ .Values.restore.s3.source }}' /data/dump.rdb_ \
+ && test -s /data/dump.rdb_ \
+ && if test -s /data/dump.rdb; \
+ then cp -v /data/dump.rdb /data/dump.rdb_orig; fi \
+ && mv -v /data/dump.rdb_ /data/dump.rdb"
+ envFrom:
+ - secretRef:
+ {{- if .Values.restore.existingSecret }}
+ name: {{ .Values.existingSecret }}
+ {{- else }}
+ name: {{ include "redis-ha.fullname" . }}-secret
+ {{- end }}
+ volumeMounts:
+ - name: data
+ mountPath: /data
+{{- end }}
+{{ if regexFind $regexRestoreSSH (toString .Values.restore.ssh.source) }}
+ - name: restore-ssh
+ image: lgatica/openssh-client:latest
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ resources:
+{{ toYaml .Values.init.resources | indent 10 }}
+ command:
+ - sh
+ args:
+ - "-c"
+ - "rm -f key && echo -e \"${SSH_KEY}\" >key \
+ && chmod 400 key \
+ && timeout {{ .Values.restore.timeout }} \
+ scp -i key \
+ -o StrictHostKeyChecking=no \
+ -o UserKnownHostsFile=/dev/null \
+ '{{ .Values.restore.ssh.source }}' \
+ /data/dump.rdb_ \
+ && test -s /data/dump.rdb_ \
+ && if test -s /data/dump.rdb; \
+ then cp -v /data/dump.rdb /data/dump.rdb_orig; fi \
+ && mv -v /data/dump.rdb_ /data/dump.rdb"
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
+ envFrom:
+ - secretRef:
+ {{- if .Values.restore.existingSecret }}
+ name: {{ .Values.existingSecret }}
+ {{- else }}
+ name: {{ include "redis-ha.fullname" . }}-secret
+ {{- end }}
+ volumeMounts:
+ - name: data
+ mountPath: /data
+{{- end }}
+{{ if regexFind $regexRestoreRedis (toString .Values.restore.redis.source) }}
+ - name: restore-redis
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ resources:
+{{ toYaml .Values.init.resources | indent 10 }}
+ command:
+ - sh
+ args:
+ - "-c"
+ - "echo $HOSTNAME | grep -q 'ha-server-0' \
+ && nc -w 5 -vz {{ regexReplaceAll "^redis:\\/\\/(.*)" .Values.restore.redis.source "${1}" }} \
+ && test ! -s /data/dump.rdb \
+ && timeout {{ .Values.restore.timeout }} \
+ redis-cli -u {{ .Values.restore.redis.source }} --rdb /data/dump.rdb_ \
+ && test -s /data/dump.rdb_ \
+ && if test -s /data/dump.rdb; \
+ then cp -v /data/dump.rdb /data/dump.rdb_orig; fi \
+ && mv -v /data/dump.rdb_ /data/dump.rdb || true"
+ {{- if .Values.restore.existingSecret }}
+ envFrom:
+ - secretRef:
+ name: {{ .Values.existingSecret }}
+ {{- end }}
+ volumeMounts:
+ - name: data
+ mountPath: /data
+{{- end }}
+{{- if .Values.extraInitContainers }}
+{{- toYaml .Values.extraInitContainers | nindent 6 }}
+{{- end }}
+ containers:
+ - name: redis
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ {{- if .Values.redis.customCommand }}
+{{ toYaml .Values.redis.customCommand | indent 10 }}
+ {{- else }}
+ - redis-server
+ {{- end }}
+ args:
+ {{- if .Values.redis.customArgs }}
+{{ toYaml .Values.redis.customArgs | indent 10 }}
+ {{- else }}
+ - /data/conf/redis.conf
+ {{- end }}
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
+ {{- if .Values.auth }}
+ env:
+ - name: AUTH
+ valueFrom:
+ secretKeyRef:
+ {{- if .Values.existingSecret }}
+ name: {{ .Values.existingSecret }}
+ {{- else }}
+ name: {{ template "redis-ha.fullname" . }}
+ {{- end }}
+ key: {{ .Values.authKey }}
+ {{- end }}
+ {{- if .Values.redis.envFrom }}
+ envFrom:
+{{ toYaml .Values.redis.envFrom | indent 10 }}
+ {{- end }}
+ {{- if .Values.redis.livenessProbe.enabled }}
+ livenessProbe:
+ initialDelaySeconds: {{ .Values.redis.livenessProbe.initialDelaySeconds }}
+ periodSeconds: {{ .Values.redis.livenessProbe.periodSeconds }}
+ timeoutSeconds: {{ .Values.redis.livenessProbe.timeoutSeconds }}
+ successThreshold: {{ .Values.redis.livenessProbe.successThreshold }}
+ failureThreshold: {{ .Values.redis.livenessProbe.failureThreshold }}
+ exec:
+ command:
+ - sh
+ - -c
+ - /health/redis_liveness.sh
+ {{- end }}
+ {{- if .Values.redis.readinessProbe.enabled }}
+ readinessProbe:
+ initialDelaySeconds: {{ .Values.redis.readinessProbe.initialDelaySeconds }}
+ periodSeconds: {{ .Values.redis.readinessProbe.periodSeconds }}
+ timeoutSeconds: {{ .Values.redis.readinessProbe.timeoutSeconds }}
+ successThreshold: {{ .Values.redis.readinessProbe.successThreshold }}
+ failureThreshold: {{ .Values.redis.readinessProbe.failureThreshold }}
+ exec:
+ command:
+ - sh
+ - -c
+ - /health/redis_readiness.sh
+ {{- end }}
+ {{- if .Values.redis.startupProbe.enabled }}
+ startupProbe:
+ initialDelaySeconds: {{ .Values.redis.startupProbe.initialDelaySeconds }}
+ periodSeconds: {{ .Values.redis.startupProbe.periodSeconds }}
+ timeoutSeconds: {{ .Values.redis.startupProbe.timeoutSeconds }}
+ successThreshold: {{ .Values.redis.startupProbe.successThreshold }}
+ failureThreshold: {{ .Values.redis.startupProbe.failureThreshold }}
+ exec:
+ command:
+ - sh
+ - -c
+ - /health/redis_readiness.sh
+ {{- end }}
+ resources:
+{{ toYaml .Values.redis.resources | indent 10 }}
+ ports:
+ {{- if ne (int .Values.redis.port) 0 }}
+ - name: redis
+ containerPort: {{ .Values.redis.port }}
+ {{- end }}
+ {{- if .Values.redis.tlsPort }}
+ - name: redis-tls
+ containerPort: {{ .Values.redis.tlsPort }}
+ {{- end }}
+ volumeMounts:
+ - name: config
+ mountPath: /readonly-config
+ readOnly: true
+ - mountPath: /data
+ name: data
+ {{- if .Values.redis.tlsPort }}
+ - mountPath: /tls-certs
+ name: tls-certs
+ {{- end}}
+ - mountPath: /health
+ name: health
+{{- if .Values.redis.extraVolumeMounts }}
+{{- toYaml .Values.redis.extraVolumeMounts | nindent 8 }}
+{{- end }}
+ lifecycle:
+{{ toYaml .Values.redis.lifecycle | indent 10 }}
+ - name: sentinel
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ {{- if .Values.sentinel.customCommand }}
+{{ toYaml .Values.sentinel.customCommand | indent 10 }}
+ {{- else }}
+ - redis-sentinel
+ {{- end }}
+ args:
+ {{- if .Values.sentinel.customArgs }}
+{{ toYaml .Values.sentinel.customArgs | indent 10 }}
+ {{- else }}
+ - /data/conf/sentinel.conf
+ {{- end }}
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
+{{- if or .Values.auth .Values.sentinel.auth}}
+ env:
+ {{- if .Values.auth }}
+ - name: AUTH
+ valueFrom:
+ secretKeyRef:
+ {{- if .Values.existingSecret }}
+ name: {{ .Values.existingSecret }}
+ {{- else }}
+ name: {{ template "redis-ha.fullname" . }}
+ {{- end }}
+ key: {{ .Values.authKey }}
+ {{- end }}
+ {{- if .Values.sentinel.auth }}
+ - name: SENTINELAUTH
+ valueFrom:
+ secretKeyRef:
+ {{- if .Values.sentinel.existingSecret }}
+ name: {{ .Values.sentinel.existingSecret }}
+ {{- else }}
+ name: {{ template "redis-ha.fullname" . }}-sentinel
+ {{- end }}
+ key: {{ .Values.sentinel.authKey }}
+ {{- end }}
+{{- end }}
+ {{- if .Values.sentinel.livenessProbe.enabled }}
+ livenessProbe:
+ initialDelaySeconds: {{ .Values.sentinel.livenessProbe.initialDelaySeconds }}
+ periodSeconds: {{ .Values.sentinel.livenessProbe.periodSeconds }}
+ timeoutSeconds: {{ .Values.sentinel.livenessProbe.timeoutSeconds }}
+ successThreshold: {{ .Values.sentinel.livenessProbe.successThreshold }}
+ failureThreshold: {{ .Values.sentinel.livenessProbe.failureThreshold }}
+ exec:
+ command:
+ - sh
+ - -c
+ - /health/sentinel_liveness.sh
+ {{- end }}
+ {{- if .Values.sentinel.readinessProbe.enabled }}
+ readinessProbe:
+ initialDelaySeconds: {{ .Values.sentinel.readinessProbe.initialDelaySeconds }}
+ periodSeconds: {{ .Values.sentinel.readinessProbe.periodSeconds }}
+ timeoutSeconds: {{ .Values.sentinel.readinessProbe.timeoutSeconds }}
+ successThreshold: {{ .Values.sentinel.readinessProbe.successThreshold }}
+ failureThreshold: {{ .Values.sentinel.readinessProbe.failureThreshold }}
+ exec:
+ command:
+ - sh
+ - -c
+ - /health/sentinel_liveness.sh
+ {{- end }}
+ {{- if .Values.sentinel.startupProbe.enabled }}
+ startupProbe:
+ initialDelaySeconds: {{ .Values.sentinel.startupProbe.initialDelaySeconds }}
+ periodSeconds: {{ .Values.sentinel.startupProbe.periodSeconds }}
+ timeoutSeconds: {{ .Values.sentinel.startupProbe.timeoutSeconds }}
+ successThreshold: {{ .Values.sentinel.startupProbe.successThreshold }}
+ failureThreshold: {{ .Values.sentinel.startupProbe.failureThreshold }}
+ exec:
+ command:
+ - sh
+ - -c
+ - /health/sentinel_liveness.sh
+ {{- end }}
+ resources:
+{{ toYaml .Values.sentinel.resources | indent 10 }}
+ ports:
+ {{- if ne (int .Values.sentinel.port) 0 }}
+ - name: sentinel
+ containerPort: {{ .Values.sentinel.port }}
+ {{- end }}
+ {{- if .Values.sentinel.tlsPort }}
+ - name: sentinel-tls
+ containerPort: {{ .Values.sentinel.tlsPort }}
+ {{- end }}
+ volumeMounts:
+ - mountPath: /data
+ name: data
+ {{- if .Values.redis.tlsPort }}
+ - mountPath: /tls-certs
+ name: tls-certs
+ {{- end }}
+ - mountPath: /health
+ name: health
+{{- if .Values.sentinel.extraVolumeMounts }}
+{{- toYaml .Values.sentinel.extraVolumeMounts | nindent 8 }}
+{{- end }}
+ lifecycle:
+{{ toYaml .Values.sentinel.lifecycle | indent 10 }}
+
+ - name: split-brain-fix
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ - sh
+ args:
+ - /readonly-config/fix-split-brain.sh
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
+ env:
+{{- $replicas := int (toString .Values.replicas) -}}
+{{- range $i := until $replicas }}
+ - name: SENTINEL_ID_{{ $i }}
+ value: {{ printf "%s\n%s\nindex: %d" (include "redis-ha.name" $) ($.Release.Name) $i | sha256sum | trunc 40 }}
+{{- end }}
+{{- if .Values.auth }}
+ - name: AUTH
+ valueFrom:
+ secretKeyRef:
+ {{- if .Values.existingSecret }}
+ name: {{ .Values.existingSecret }}
+ {{- else }}
+ name: {{ template "redis-ha.fullname" . }}
+ {{- end }}
+ key: {{ .Values.authKey }}
+{{- end }}
+{{- if .Values.sentinel.auth }}
+ - name: SENTINELAUTH
+ valueFrom:
+ secretKeyRef:
+ {{- if .Values.sentinel.existingSecret }}
+ name: {{ .Values.sentinel.existingSecret }}
+ {{- else }}
+ name: {{ template "redis-ha.fullname" . }}-sentinel
+ {{- end }}
+ key: {{ .Values.sentinel.authKey }}
+{{- end }}
+ resources:
+ {{- toYaml .Values.splitBrainDetection.resources | nindent 10 }}
+ volumeMounts:
+ - name: config
+ mountPath: /readonly-config
+ readOnly: true
+ - mountPath: /data
+ name: data
+ {{- if .Values.redis.tlsPort }}
+ - mountPath: /tls-certs
+ name: tls-certs
+ {{- end }}
+
+{{- if .Values.exporter.enabled }}
+ - name: redis-exporter
+ image: "{{ .Values.exporter.image }}:{{ .Values.exporter.tag }}"
+ imagePullPolicy: {{ .Values.exporter.pullPolicy }}
+ args:
+ {{- range $key, $value := .Values.exporter.extraArgs }}
+ - --{{ $key }}={{ $value }}
+ {{- end }}
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
+ env:
+ - name: REDIS_ADDR
+ {{- if .Values.exporter.sslEnabled }}
+ value: rediss://{{ default "localhost" .Values.exporter.address }}:{{ .Values.redis.tlsPort }}
+ {{- else }}
+ value: redis://{{ default "localhost" .Values.exporter.address }}:{{ .Values.redis.port }}
+ {{- end }}
+ {{- if .Values.auth }}
+ - name: REDIS_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ {{- if .Values.existingSecret }}
+ name: {{ .Values.existingSecret }}
+ {{- else }}
+ name: {{ template "redis-ha.fullname" . }}
+ {{- end }}
+ key: {{ .Values.authKey }}
+ {{- end }}
+ {{- if .Values.exporter.script }}
+ - name: REDIS_EXPORTER_SCRIPT
+ value: /script/script.lua
+ {{- end }}
+ {{- if .Values.exporter.sslEnabled }}
+ - name: REDIS_EXPORTER_TLS_CLIENT_KEY_FILE
+ value: /tls-certs/{{ .Values.tls.keyFile }}
+ - name: REDIS_EXPORTER_TLS_CLIENT_CERT_FILE
+ value: /tls-certs/{{ .Values.tls.certFile }}
+ - name: REDIS_EXPORTER_TLS_CA_CERT_FILE
+ value: /tls-certs/{{ .Values.tls.caCertFile }}
+ {{- end }}
+ livenessProbe:
+{{ toYaml .Values.exporter.livenessProbe | indent 10 }}
+ readinessProbe:
+{{ toYaml .Values.exporter.readinessProbe | indent 10 }}
+ resources:
+{{ toYaml .Values.exporter.resources | indent 10 }}
+ ports:
+ - name: {{ .Values.exporter.portName }}
+ containerPort: {{ .Values.exporter.port }}
+ volumeMounts:
+ {{- if .Values.exporter.script }}
+ - mountPath: /script
+ name: script-mount
+ {{- end }}
+ {{- if .Values.exporter.sslEnabled }}
+ - mountPath: /tls-certs
+ name: tls-certs
+ {{- end }}
+{{- end }}
+{{- if .Values.extraContainers }}
+{{- toYaml .Values.extraContainers | nindent 6 }}
+{{- end -}}
+ {{- with .Values.priorityClassName | default .Values.global.priorityClassName }}
+ priorityClassName: {{ . }}
+ {{- end }}
+ volumes:
+ - name: config
+ configMap:
+ name: {{ template "redis-ha.fullname" . }}-configmap
+ {{- if .Values.sysctlImage.mountHostSys }}
+ - name: host-sys
+ hostPath:
+ path: /sys
+ {{- end }}
+ {{- if .Values.exporter.script }}
+ - name: script-mount
+ configMap:
+ name: {{ template "redis-ha.fullname" . }}-exporter-script-configmap
+ items:
+ - key: script
+ path: script.lua
+ {{- end }}
+ {{- if .Values.redis.tlsPort }}
+ - name: tls-certs
+ secret:
+ {{- if .Values.tls.secretName }}
+ secretName: {{ .Values.tls.secretName }}
+ {{- else }}
+ secretName: {{ template "redis-ha.fullname" . }}-tls-secret
+ {{- end }}
+ {{- end }}
+ - name: health
+ configMap:
+ name: {{ template "redis-ha.fullname" . }}-health-configmap
+ defaultMode: 0755
+{{- if .Values.extraVolumes }}
+{{- toYaml .Values.extraVolumes | nindent 6 }}
+{{- end -}}
+{{- if .Values.persistentVolume.enabled }}
+ volumeClaimTemplates:
+ - apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: data
+ annotations:
+ {{- range $key, $value := .Values.persistentVolume.annotations }}
+ {{ $key }}: {{ $value }}
+ {{- end }}
+ labels: {{- toYaml .Values.persistentVolume.labels | nindent 8 }}
+
+ spec:
+ accessModes:
+ {{- range .Values.persistentVolume.accessModes }}
+ - {{ . | quote }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ .Values.persistentVolume.size | quote }}
+ {{- if .Values.persistentVolume.storageClass }}
+ {{- if (eq "-" .Values.persistentVolume.storageClass) }}
+ storageClassName: ""
+ {{- else }}
+ storageClassName: "{{ .Values.persistentVolume.storageClass }}"
+ {{- end }}
+{{- end }}
+{{- else if .Values.hostPath.path }}
+ - name: data
+ hostPath:
+ path: {{ tpl .Values.hostPath.path .}}
+{{- else }}
+ - name: data
+ emptyDir:
+{{ toYaml .Values.emptyDir | indent 10 }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-deployment.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-deployment.yaml
new file mode 100644
index 0000000..07677fc
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-deployment.yaml
@@ -0,0 +1,202 @@
+{{- if .Values.haproxy.enabled }}
+kind: Deployment
+apiVersion: apps/v1
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-haproxy
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+spec:
+ {{- with .Values.haproxy.deploymentStrategy }}
+ strategy:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ revisionHistoryLimit: 1
+ replicas: {{ .Values.haproxy.replicas }}
+ selector:
+ matchLabels:
+ app: {{ template "redis-ha.name" . }}-haproxy
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ name: {{ template "redis-ha.fullname" . }}-haproxy
+ labels:
+ app: {{ template "redis-ha.name" . }}-haproxy
+ release: {{ .Release.Name }}
+ {{- range $key, $value := .Values.haproxy.labels }}
+ {{ $key }}: {{ $value | toString }}
+ {{- end }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ annotations:
+ {{- if and (.Values.haproxy.metrics.enabled) (not .Values.haproxy.metrics.serviceMonitor.enabled) }}
+ prometheus.io/port: "{{ .Values.haproxy.metrics.port }}"
+ prometheus.io/scrape: "true"
+ prometheus.io/path: "{{ .Values.haproxy.metrics.scrapePath }}"
+ {{- end }}
+ checksum/config: {{ print (include "config-haproxy.cfg" .) (include "config-haproxy_init.sh" .) | sha256sum }}
+ {{- if .Values.haproxy.annotations }}
+{{ toYaml .Values.haproxy.annotations | indent 8 }}
+ {{- end }}
+ spec:
+ # Needed when using unmodified rbac-setup.yml
+ {{ if .Values.haproxy.serviceAccount.create }}
+ serviceAccountName: {{ template "redis-ha.serviceAccountName" . }}-haproxy
+ {{- else }}
+ serviceAccountName: {{ .Values.haproxy.serviceAccountName }}
+ {{- end }}
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.haproxy.securityContext "context" $) | nindent 8 }}
+ automountServiceAccountToken: {{ .Values.haproxy.serviceAccount.automountToken }}
+ nodeSelector:
+{{ toYaml .Values.nodeSelector | indent 8 }}
+ tolerations:
+{{ toYaml .Values.tolerations | indent 8 }}
+ affinity:
+ {{- if .Values.haproxy.affinity }}
+ {{- with .Values.haproxy.affinity }}
+{{ tpl . $ | indent 8 }}
+ {{- end }}
+ {{- else }}
+ {{- if .Values.haproxy.additionalAffinities }}
+{{ toYaml .Values.haproxy.additionalAffinities | indent 8 }}
+ {{- end }}
+ podAntiAffinity:
+ {{- if .Values.haproxy.hardAntiAffinity }}
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchLabels:
+ app: {{ template "redis-ha.name" . }}-haproxy
+ release: {{ .Release.Name }}
+ topologyKey: kubernetes.io/hostname
+ {{- else }}
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - weight: 100
+ podAffinityTerm:
+ labelSelector:
+ matchLabels:
+ app: {{ template "redis-ha.name" . }}-haproxy
+ release: {{ .Release.Name }}
+ topologyKey: kubernetes.io/hostname
+ {{- end }}
+ {{- end }}
+ {{- if .Values.topologySpreadConstraints.enabled }}
+ topologySpreadConstraints:
+ - maxSkew: {{ .Values.topologySpreadConstraints.maxSkew | default 1 }}
+ topologyKey: {{ .Values.topologySpreadConstraints.topologyKey | default "topology.kubernetes.io/zone" }}
+ whenUnsatisfiable: {{ .Values.topologySpreadConstraints.whenUnsatisfiable | default "ScheduleAnyway" }}
+ labelSelector:
+ matchLabels:
+ app: {{ template "redis-ha.name" . }}-haproxy
+ release: {{ .Release.Name }}
+ {{- end }}
+ initContainers:
+ - name: config-init
+ image: {{ .Values.haproxy.image.repository }}:{{ .Values.haproxy.image.tag }}
+ imagePullPolicy: {{ .Values.haproxy.image.pullPolicy }}
+ resources:
+{{ toYaml .Values.haproxy.init.resources | indent 10 }}
+ command:
+ - sh
+ args:
+ - /readonly/haproxy_init.sh
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.haproxy.containerSecurityContext "context" $) | nindent 10 }}
+ volumeMounts:
+ - name: config-volume
+ mountPath: /readonly
+ readOnly: true
+ - name: data
+ mountPath: /data
+ {{- if .Values.haproxy.imagePullSecrets }}
+ imagePullSecrets: {{ toYaml .Values.haproxy.imagePullSecrets | nindent 8 }}
+ {{- end }}
+ containers:
+ - name: haproxy
+ image: {{ .Values.haproxy.image.repository }}:{{ .Values.haproxy.image.tag }}
+ imagePullPolicy: {{ .Values.haproxy.image.pullPolicy }}
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.haproxy.containerSecurityContext "context" $) | nindent 10 }}
+ {{- if or .Values.auth .Values.sentinel.auth}}
+ env:
+ {{- if .Values.auth }}
+ - name: AUTH
+ valueFrom:
+ secretKeyRef:
+ {{- if .Values.existingSecret }}
+ name: {{ .Values.existingSecret }}
+ {{- else }}
+ name: {{ template "redis-ha.fullname" . }}
+ {{- end }}
+ key: {{ .Values.authKey }}
+ {{- end }}
+ {{- if .Values.sentinel.auth }}
+ - name: SENTINELAUTH
+ valueFrom:
+ secretKeyRef:
+ {{- if .Values.sentinel.existingSecret }}
+ name: {{ .Values.sentinel.existingSecret }}
+ {{- else }}
+ name: {{ template "redis-ha.fullname" . }}-sentinel
+ {{- end }}
+ key: {{ .Values.sentinel.authKey }}
+ {{- end }}
+ {{- end }}
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: probe
+ initialDelaySeconds: 5
+ periodSeconds: 3
+ readinessProbe:
+ httpGet:
+ path: /healthz
+ port: probe
+ initialDelaySeconds: 5
+ periodSeconds: 3
+ ports:
+ - name: probe
+ containerPort: 8888
+ - name: redis
+ containerPort: {{ default "6379" .Values.haproxy.containerPort }}
+ {{- if .Values.haproxy.readOnly.enabled }}
+ - name: readonlyport
+ containerPort: {{ default "6380" .Values.haproxy.readOnly.port }}
+ {{- end }}
+ {{- if .Values.haproxy.metrics.enabled }}
+ - name: metrics-port
+ containerPort: {{ default "9101" .Values.haproxy.metrics.port }}
+ {{- end }}
+ resources:
+{{ toYaml .Values.haproxy.resources | indent 10 }}
+ volumeMounts:
+ - name: data
+ mountPath: /usr/local/etc/haproxy
+ - name: shared-socket
+ mountPath: /run/haproxy
+{{- if .Values.haproxy.tls.enabled }}
+ - name: pemfile
+ mountPath: {{ .Values.haproxy.tls.certMountPath }}
+{{- end }}
+ lifecycle:
+{{ toYaml .Values.haproxy.lifecycle | indent 10 }}
+ {{- with .Values.haproxy.priorityClassName | default .Values.global.priorityClassName }}
+ priorityClassName: {{ . }}
+ {{- end }}
+ volumes:
+{{- if .Values.haproxy.tls.enabled }}
+ - name: pemfile
+ secret:
+ secretName: {{ .Values.haproxy.tls.secretName }}
+{{- end }}
+ - name: config-volume
+ configMap:
+ name: {{ template "redis-ha.fullname" . }}-configmap
+ - name: shared-socket
+ emptyDir:
+{{ toYaml .Values.haproxy.emptyDir | indent 10 }}
+ - name: data
+ emptyDir:
+{{ toYaml .Values.haproxy.emptyDir | indent 10 }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-network-policy.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-network-policy.yaml
new file mode 100644
index 0000000..2b746ea
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-network-policy.yaml
@@ -0,0 +1,74 @@
+{{- if and .Values.haproxy.enabled .Values.haproxy.networkPolicy.enabled }}
+{{- $root := . }}
+kind: NetworkPolicy
+apiVersion: networking.k8s.io/v1
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-haproxy-network-policy
+ namespace: {{ .Release.Namespace | quote }}
+ {{- if .Values.haproxy.networkPolicy.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.haproxy.networkPolicy.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ labels:
+ {{- include "labels.standard" . | nindent 4 }}
+ {{- range $key, $value := .Values.haproxy.networkPolicy.labels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+spec:
+ podSelector:
+ matchLabels:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}-haproxy
+ policyTypes:
+ - Ingress
+ - Egress
+ egress:
+ - to:
+ - podSelector:
+ matchLabels:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}
+ ports:
+ - port: {{ .Values.redis.port }}
+ protocol: TCP
+ - port: {{ .Values.sentinel.port }}
+ protocol: TCP
+ - to:
+ - namespaceSelector: {}
+ ports:
+ - port: 53
+ protocol: UDP
+ - port: 53
+ protocol: TCP
+ {{- range $rule := .Values.haproxy.networkPolicy.egressRules }}
+ - to:
+ {{- (tpl (toYaml $rule.selectors) $) | nindent 8 }}
+ ports:
+ {{- toYaml $rule.ports | nindent 8 }}
+ {{- end }}
+ ingress:
+ - from:
+ - podSelector:
+ matchLabels:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}
+ ports:
+ - port: {{ .Values.redis.port }}
+ protocol: TCP
+ - port: {{ .Values.sentinel.port }}
+ protocol: TCP
+ {{- range $rule := .Values.haproxy.networkPolicy.ingressRules }}
+ - from:
+ {{- (tpl (toYaml $rule.selectors) $) | nindent 8 }}
+ ports:
+ {{- if $rule.ports }}
+ {{- toYaml $rule.ports | nindent 8 }}
+ {{- end }}
+ - port: {{ $root.Values.redis.port }}
+ protocol: TCP
+ - port: {{ $root.Values.sentinel.port }}
+ protocol: TCP
+ {{- end }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-pdb.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-pdb.yaml
new file mode 100644
index 0000000..9094ddf
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-pdb.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.haproxy.podDisruptionBudget -}}
+apiVersion: {{ template "redis-ha.podDisruptionBudget.apiVersion" . }}
+kind: PodDisruptionBudget
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-haproxy-pdb
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+spec:
+ selector:
+ matchLabels:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}-haproxy
+{{ toYaml .Values.haproxy.podDisruptionBudget | indent 2 }}
+{{- end -}}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-role.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-role.yaml
new file mode 100644
index 0000000..c6fd1df
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-role.yaml
@@ -0,0 +1,22 @@
+{{- if .Values.haproxy.enabled }}
+{{- if and .Values.haproxy.serviceAccount.create .Values.rbac.create }}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-haproxy
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ component: {{ template "redis-ha.fullname" . }}-haproxy
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - endpoints
+ verbs:
+ - get
+{{- end }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-rolebinding.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-rolebinding.yaml
new file mode 100644
index 0000000..629de55
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-rolebinding.yaml
@@ -0,0 +1,22 @@
+{{- if .Values.haproxy.enabled }}
+{{- if and .Values.haproxy.serviceAccount.create .Values.rbac.create }}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-haproxy
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ component: {{ template "redis-ha.fullname" . }}-haproxy
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+subjects:
+- kind: ServiceAccount
+ name: {{ template "redis-ha.serviceAccountName" . }}-haproxy
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: {{ template "redis-ha.fullname" . }}-haproxy
+{{- end }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-service.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-service.yaml
new file mode 100644
index 0000000..2feff9b
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-service.yaml
@@ -0,0 +1,60 @@
+{{- if .Values.haproxy.enabled }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-haproxy
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ component: {{ template "redis-ha.fullname" . }}-haproxy
+{{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+{{- end }}
+{{- range $key, $value := .Values.haproxy.service.labels }}
+ {{ $key }}: {{ $value | quote }}
+{{- end }}
+ annotations:
+ {{- if .Values.haproxy.service.annotations }}
+{{ toYaml .Values.haproxy.service.annotations | indent 4 }}
+ {{- end }}
+spec:
+ type: {{ default "ClusterIP" .Values.haproxy.service.type }}
+ {{- if and (eq .Values.haproxy.service.type "LoadBalancer") .Values.haproxy.service.loadBalancerIP }}
+ loadBalancerIP: {{ .Values.haproxy.service.loadBalancerIP }}
+ {{- end }}
+ {{- if and (eq .Values.haproxy.service.type "LoadBalancer") .Values.haproxy.service.externalTrafficPolicy }}
+ externalTrafficPolicy: {{ .Values.haproxy.service.externalTrafficPolicy }}
+ {{- end }}
+ {{- if and (eq .Values.haproxy.service.type "LoadBalancer") .Values.haproxy.service.loadBalancerSourceRanges }}
+ loadBalancerSourceRanges: {{ toYaml .Values.haproxy.service.loadBalancerSourceRanges | nindent 2 }}
+ {{- end }}
+ {{- if .Values.haproxy.service.externalIPs }}
+ externalIPs:
+ {{- range $key, $value := .Values.haproxy.service.externalIPs }}
+ - {{ $value }}
+ {{- end }}
+ {{- end }}
+ ports:
+ - name: tcp-haproxy
+ port: {{ .Values.haproxy.servicePort }}
+ protocol: TCP
+ targetPort: redis
+ {{- if and (eq .Values.haproxy.service.type "NodePort") .Values.haproxy.service.nodePort }}
+ nodePort: {{ .Values.haproxy.service.nodePort }}
+ {{- end }}
+{{- if .Values.haproxy.readOnly.enabled }}
+ - name: tcp-haproxyreadonly
+ port: {{ .Values.haproxy.readOnly.port }}
+ protocol: TCP
+ targetPort: {{ .Values.haproxy.readOnly.port }}
+{{- end }}
+{{- if .Values.haproxy.metrics.enabled }}
+ - name: {{ .Values.haproxy.metrics.portName }}
+ port: {{ .Values.haproxy.metrics.port }}
+ protocol: TCP
+ targetPort: metrics-port
+{{- end }}
+ selector:
+ release: {{ .Release.Name }}
+ app: {{ template "redis-ha.name" . }}-haproxy
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-serviceaccount.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-serviceaccount.yaml
new file mode 100644
index 0000000..f016855
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-serviceaccount.yaml
@@ -0,0 +1,15 @@
+{{- if and .Values.haproxy.serviceAccount.create .Values.haproxy.enabled }}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ template "redis-ha.serviceAccountName" . }}-haproxy
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+ chart: {{ .Chart.Name }}-{{ .Chart.Version }}
+ app: {{ template "redis-ha.fullname" . }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-servicemonitor.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-servicemonitor.yaml
new file mode 100644
index 0000000..188eac0
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-servicemonitor.yaml
@@ -0,0 +1,39 @@
+{{- if and ( or .Values.haproxy.metrics.serviceMonitor.disableAPICheck ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) ) ( .Values.haproxy.metrics.serviceMonitor.enabled ) ( .Values.haproxy.metrics.enabled ) }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-haproxy
+ namespace: {{ .Values.haproxy.metrics.serviceMonitor.namespace | default .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ {{- range $key, $value := .Values.haproxy.metrics.serviceMonitor.labels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+spec:
+ endpoints:
+ - targetPort: {{ .Values.haproxy.metrics.port }}
+{{- if .Values.haproxy.metrics.serviceMonitor.interval }}
+ interval: {{ .Values.haproxy.metrics.serviceMonitor.interval }}
+{{- end }}
+{{- if .Values.haproxy.metrics.serviceMonitor.telemetryPath }}
+ path: {{ .Values.haproxy.metrics.serviceMonitor.telemetryPath }}
+{{- end }}
+{{- if .Values.haproxy.metrics.serviceMonitor.timeout }}
+ scrapeTimeout: {{ .Values.haproxy.metrics.serviceMonitor.timeout }}
+{{- end }}
+{{- with .Values.haproxy.metrics.serviceMonitor.endpointAdditionalProperties }}
+{{- toYaml . | nindent 4 }}
+{{- end }}
+ jobLabel: {{ template "redis-ha.fullname" . }}-haproxy
+ namespaceSelector:
+ matchNames:
+ - {{ .Release.Namespace | quote }}
+ selector:
+ matchLabels:
+ app: {{ template "redis-ha.name" . }}
+ release: {{ .Release.Name }}
+ component: {{ template "redis-ha.fullname" . }}-haproxy
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-tls-secret.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-tls-secret.yaml
new file mode 100644
index 0000000..d303470
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-tls-secret.yaml
@@ -0,0 +1,27 @@
+{{- if and .Values.redis.tlsPort (not .Values.tls.secretName) -}}
+apiVersion: v1
+kind: Secret
+metadata:
+ metadata:
+ name: {{ template "redis-ha.fullname" . }}-tls-secret
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+type: Opaque
+data:
+ {{- if .Values.tls.caCertFile }}
+ {{ .Values.tls.caCertFile }}: {{ .Files.Get "certs/ca.crt" | b64enc }}
+ {{- end }}
+ {{- if .Values.tls.certFile }}
+ {{ .Values.tls.certFile }}: {{ .Files.Get "certs/redis.crt" | b64enc }}
+ {{- end }}
+ {{- if .Values.tls.keyFile }}
+ {{ .Values.tls.keyFile }}: {{ .Files.Get "certs/redis.key" | b64enc }}
+ {{- end }}
+ {{- if .Values.tls.dhParamsFile }}
+ {{ .Values.tls.dhParamsFile }}: {{ .Files.Get "certs/redis.dh" | b64enc }}
+ {{- end }}
+{{- end }}
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/sentinel-auth-secret.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/sentinel-auth-secret.yaml
new file mode 100644
index 0000000..d351be6
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/sentinel-auth-secret.yaml
@@ -0,0 +1,15 @@
+{{- if and .Values.sentinel.auth (not .Values.sentinel.existingSecret) -}}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-sentinel
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ {{- range $key, $value := .Values.extraLabels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+type: Opaque
+data:
+ {{ .Values.sentinel.authKey }}: {{ .Values.sentinel.password | b64enc | quote }}
+{{- end -}} \ No newline at end of file
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/tests/test-redis-ha-configmap.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/tests/test-redis-ha-configmap.yaml
new file mode 100644
index 0000000..fbf31ad
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/tests/test-redis-ha-configmap.yaml
@@ -0,0 +1,32 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-configmap-test
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ annotations:
+ "helm.sh/hook": test-success
+spec:
+ nodeSelector: {{ toYaml .Values.nodeSelector | nindent 4 }}
+ tolerations: {{ toYaml .Values.tolerations | nindent 4 }}
+ containers:
+ - name: check-init
+ image: {{ .Values.configmapTest.image.repository }}:{{ .Values.configmapTest.image.tag }}
+ args:
+ - --shell=sh
+ - /readonly-config/init.sh
+ volumeMounts:
+ - name: config
+ mountPath: /readonly-config
+ readOnly: true
+ resources: {{ toYaml .Values.configmapTest.resources | nindent 6 }}
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 6 }}
+ {{- if .Values.imagePullSecrets }}
+ imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 4 }}
+ {{- end }}
+ restartPolicy: Never
+ volumes:
+ - name: config
+ configMap:
+ name: {{ template "redis-ha.fullname" . }}-configmap
diff --git a/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/tests/test-redis-ha-pod.yaml b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/tests/test-redis-ha-pod.yaml
new file mode 100644
index 0000000..ac0c84e
--- /dev/null
+++ b/astroshop-platform/argocd-helmchart/charts/redis-ha/templates/tests/test-redis-ha-pod.yaml
@@ -0,0 +1,29 @@
+{{- if .Values.haproxy.enabled }}
+apiVersion: v1
+kind: Pod
+metadata:
+ name: {{ template "redis-ha.fullname" . }}-service-test
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+{{ include "labels.standard" . | indent 4 }}
+ annotations:
+ "helm.sh/hook": test-success
+spec:
+ nodeSelector:
+{{ toYaml .Values.nodeSelector | indent 4 }}
+ tolerations:
+{{ toYaml .Values.tolerations | indent 4 }}
+ containers:
+ - name: "{{ .Release.Name }}-service-test"
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ command:
+ - sh
+ - -c
+ - redis-cli -h {{ template "redis-ha.fullname" . }}-haproxy -p {{ .Values.redis.port }} info server
+ resources: {{ toYaml .Values.haproxy.tests.resources | nindent 6 }}
+ securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 6 }}
+ {{- if .Values.imagePullSecrets }}
+ imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 4 }}
+ {{- end }}
+ restartPolicy: Never
+{{- end }}