feat(hydra-cleaner): add component

This commit is contained in:
Laurent Gourvenec 2025-02-27 16:01:54 +01:00
parent f300b91316
commit 7a09045e82
3 changed files with 187 additions and 0 deletions

View File

@ -0,0 +1,116 @@
#!/bin/sh
set -e
set -o nounset
# 4 tables to empty, at least
# oidc, code, flow, authentication_session
# \d hydra_oauth2_flow
#Referenced by:
# TABLE "hydra_oauth2_access" CONSTRAINT "hydra_oauth2_access_challenge_id_fk" FOREIGN KEY (challenge_id) REFERENCES hydra_oauth2_flow(consent_challenge_id) ON DELETE CASCADE
# TABLE "hydra_oauth2_code" CONSTRAINT "hydra_oauth2_code_challenge_id_fk" FOREIGN KEY (challenge_id) REFERENCES hydra_oauth2_flow(consent_challenge_id) ON DELETE CASCADE
# TABLE "hydra_oauth2_oidc" CONSTRAINT "hydra_oauth2_oidc_challenge_id_fk" FOREIGN KEY (challenge_id) REFERENCES hydra_oauth2_flow(consent_challenge_id) ON DELETE CASCADE
# TABLE "hydra_oauth2_pkce" CONSTRAINT "hydra_oauth2_pkce_challenge_id_fk" FOREIGN KEY (challenge_id) REFERENCES hydra_oauth2_flow(consent_challenge_id) ON DELETE CASCADE
# TABLE "hydra_oauth2_refresh" CONSTRAINT "hydra_oauth2_refresh_challenge_id_fk" FOREIGN KEY (challenge_id) REFERENCES hydra_oauth2_flow(consent_challenge_id) ON DELETE CASCADE
# -> delete "cascade" on table "flow" cleans access, code, oidc, pkce and refresh tables.
DSN="postgresql://${HYDRA_DATABASE_USER}:${HYDRA_DATABASE_PASSWORD}@${HYDRA_DATABASE_SERVICE_NAME}:5432/hydra?sslmode=disable"
RETENTION_HOURS="${RETENTION_HOURS:-48}"
BATCH_SIZE="${BATCH_SIZE:-50}"
LIMIT="${LIMIT:-1000}"
BEFORE_DATE="$(date +'%Y-%m-%d %H:%M:%S' --date=@$(($(date +%s) - RETENTION_HOURS * 3600)))"
log() {
echo "$(date +'%d-%m-%y %H:%M:%S%z')| $1"
}
perror() {
log "Something went wrong, exiting."
trap - EXIT
exit 1
}
trap perror EXIT
if ! [[ ${RETENTION_HOURS} =~ '^[0-9]+$' ]]; then
log "Error: variable RETENTION_HOURS is not a positive integer."
perror
fi
if ! [[ ${LIMIT} =~ '^[0-9]+$' ]]; then
log "Error: variable LIMIT is not a positive integer."
perror
fi
if ! [[ ${BATCH_SIZE} =~ '^[0-9]+$' ]]; then
log "Error: variable BATCH_SIZE is not a positive integer."
perror
fi
log "Starting hydra cleaner"
log "Removing up to ${LIMIT} elements before ${BEFORE_DATE} by batch of ${BATCH_SIZE}"
log "Beginning estimated size:"
psql "${DSN}" <<EOF
select
table_name, reltuples as estimate,
pg_size_pretty(pg_total_relation_size(quote_ident(table_name))),
pg_total_relation_size(quote_ident(table_name))
from information_schema.tables left join pg_class on information_schema.tables.table_name=pg_class.relname
where table_schema = 'public'
order by 4 desc;
EOF
REMAINING_ELMTS="${LIMIT}"
while [ "${REMAINING_ELMTS}" -gt 0 ]; do
OUTPUT=$(psql "${DSN}" <<EOF
DELETE
FROM hydra_oauth2_flow
WHERE login_challenge = ANY (
array(
SELECT login_challenge
FROM hydra_oauth2_flow
WHERE requested_at < '${BEFORE_DATE}'
LIMIT ${BATCH_SIZE}
)
);
EOF
)
log "${OUTPUT}"
if ! [[ "${OUTPUT}" =~ '^DELETE ' ]] ; then
log "Output doesn't seems OK..."
break
fi
OUTPUT_NB=$(echo "${OUTPUT}" | cut -d' ' -f 2)
if [ "${OUTPUT_NB}" -lt "${BATCH_SIZE}" ]; then
break
fi
REMAINING_ELMTS=$((REMAINING_ELMTS - BATCH_SIZE))
if [ "${REMAINING_ELMTS}" -lt "${BATCH_SIZE}" ]; then
BATCH_SIZE="${REMAINING_ELMTS}"
fi
done
log "Final estimated size:"
psql "${DSN}" <<EOF
select
table_name, reltuples as estimate,
pg_size_pretty(pg_total_relation_size(quote_ident(table_name))),
pg_total_relation_size(quote_ident(table_name))
from information_schema.tables left join pg_class on information_schema.tables.table_name=pg_class.relname
where table_schema = 'public'
order by 4 desc;
EOF
trap - EXIT

View File

@ -0,0 +1,17 @@
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
- ./resources/hydra-cleaner-cronjob.yaml
configMapGenerator:
- name: hydra-cleaner-env
behavior: create
literals:
- RETENTION_HOURS="48"
- BATCH_SIZE="100"
- LIMIT="1000"
- name: hydra-cleaner-script
behavior: create
files:
- ./files/hydra-cleaner.sh

View File

@ -0,0 +1,54 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: hydra-cleaner
labels:
app.kubernetes.io/name: hydra-cleaner
spec:
concurrencyPolicy: Forbid
schedule: "30 */1 * * *"
jobTemplate:
spec:
template:
metadata:
labels:
app.kubernetes.io/name: hydra-cleaner
spec:
restartPolicy: OnFailure
serviceAccountName: hydra-sa
containers:
- name: hydra-cleaner
image: reg.cadoles.com/proxy_cache/alpine/psql:17.4
envFrom:
- configMapRef:
name: hydra-env
- configMapRef:
name: hydra-cleaner-env
imagePullPolicy: IfNotPresent
command: ["/hydra-cleaner.sh"]
env:
- name: HYDRA_DATABASE_USER
valueFrom:
secretKeyRef:
name: hydra-postgres-app
key: username
- name: HYDRA_DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: hydra-postgres-app
key: password
- name: HYDRA_DATABASE_SERVICE_NAME
valueFrom:
secretKeyRef:
name: hydra-postgres-app
key: host
args: []
volumeMounts:
- name: hydra-cleaner-script
mountPath: "/hydra-cleaner.sh"
subPath: "hydra-cleaner.sh"
volumes:
- name: hydra-cleaner-script
configMap:
name: hydra-cleaner-script
defaultMode: 0544