From 88a326bacdffde9e065b08ba893a17149584e72e Mon Sep 17 00:00:00 2001 From: Saumit Date: Sat, 11 Oct 2025 02:34:38 +0530 Subject: platform: Adding argocd helm chart --- .../charts/redis-ha/templates/NOTES.txt | 25 + .../charts/redis-ha/templates/_configs.tpl | 730 +++++++++++++++++++++ .../charts/redis-ha/templates/_helpers.tpl | 130 ++++ .../redis-ha/templates/redis-auth-secret.yaml | 15 + .../templates/redis-ha-announce-service.yaml | 64 ++ .../redis-ha/templates/redis-ha-configmap.yaml | 37 ++ .../redis-ha-exporter-script-configmap.yaml | 14 + .../templates/redis-ha-health-configmap.yaml | 20 + .../templates/redis-ha-network-policy.yaml | 80 +++ .../charts/redis-ha/templates/redis-ha-pdb.yaml | 18 + .../templates/redis-ha-prometheus-rule.yaml | 17 + .../charts/redis-ha/templates/redis-ha-role.yaml | 19 + .../redis-ha/templates/redis-ha-rolebinding.yaml | 19 + .../charts/redis-ha/templates/redis-ha-secret.yaml | 32 + .../redis-ha/templates/redis-ha-service.yaml | 57 ++ .../templates/redis-ha-serviceaccount.yaml | 31 + .../templates/redis-ha-servicemonitor.yaml | 39 ++ .../redis-ha/templates/redis-ha-statefulset.yaml | 668 +++++++++++++++++++ .../templates/redis-haproxy-deployment.yaml | 202 ++++++ .../templates/redis-haproxy-network-policy.yaml | 74 +++ .../redis-ha/templates/redis-haproxy-pdb.yaml | 18 + .../redis-ha/templates/redis-haproxy-role.yaml | 22 + .../templates/redis-haproxy-rolebinding.yaml | 22 + .../redis-ha/templates/redis-haproxy-service.yaml | 60 ++ .../templates/redis-haproxy-serviceaccount.yaml | 15 + .../templates/redis-haproxy-servicemonitor.yaml | 39 ++ .../redis-ha/templates/redis-tls-secret.yaml | 27 + .../redis-ha/templates/sentinel-auth-secret.yaml | 15 + .../templates/tests/test-redis-ha-configmap.yaml | 32 + .../templates/tests/test-redis-ha-pod.yaml | 29 + 30 files changed, 2570 insertions(+) create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/NOTES.txt create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/_configs.tpl create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/_helpers.tpl create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-auth-secret.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-announce-service.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-configmap.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-exporter-script-configmap.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-health-configmap.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-network-policy.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-pdb.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-prometheus-rule.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-role.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-rolebinding.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-secret.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-service.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-serviceaccount.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-servicemonitor.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-ha-statefulset.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-deployment.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-network-policy.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-pdb.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-role.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-rolebinding.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-service.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-serviceaccount.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-haproxy-servicemonitor.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/redis-tls-secret.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/sentinel-auth-secret.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/tests/test-redis-ha-configmap.yaml create mode 100644 astroshop-platform/argocd-helmchart/charts/redis-ha/templates/tests/test-redis-ha-pod.yaml (limited to 'astroshop-platform/argocd-helmchart/charts/redis-ha/templates') 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 +{{- 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 }} -- cgit v1.2.3