From f8505401d745521759ff78de75df3b70a323da72 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Tue, 31 Mar 2026 17:54:44 +0200 Subject: [PATCH] fix: ClickHouse auth credentials and non-fatal schema init - Set CLICKHOUSE_USER/PASSWORD via k8s secret (fixes "disabling network access for user 'default'" when no password is set) - Add clickhouse-credentials secret to CI deploy + feature branch copy - Pass CLICKHOUSE_USERNAME/PASSWORD env vars to server pod - Make schema initializer non-fatal so server starts even if CH is temporarily unavailable Co-Authored-By: Claude Opus 4.6 (1M context) --- .gitea/workflows/ci.yml | 10 ++++++- .../config/ClickHouseSchemaInitializer.java | 30 +++++++++++-------- deploy/base/server.yaml | 10 +++++++ deploy/clickhouse.yaml | 13 ++++++++ 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 0bd33bea..259f8684 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -222,6 +222,12 @@ jobs: --from-literal=AUTHENTIK_SECRET_KEY="${AUTHENTIK_SECRET_KEY}" \ --dry-run=client -o yaml | kubectl apply -f - + kubectl create secret generic clickhouse-credentials \ + --namespace=cameleer \ + --from-literal=CLICKHOUSE_USER="${CLICKHOUSE_USER:-default}" \ + --from-literal=CLICKHOUSE_PASSWORD="$CLICKHOUSE_PASSWORD" \ + --dry-run=client -o yaml | kubectl apply -f - + kubectl apply -f deploy/postgres.yaml kubectl -n cameleer rollout status statefulset/postgres --timeout=120s @@ -256,6 +262,8 @@ jobs: AUTHENTIK_PG_USER: ${{ secrets.AUTHENTIK_PG_USER }} AUTHENTIK_PG_PASSWORD: ${{ secrets.AUTHENTIK_PG_PASSWORD }} AUTHENTIK_SECRET_KEY: ${{ secrets.AUTHENTIK_SECRET_KEY }} + CLICKHOUSE_USER: ${{ secrets.CLICKHOUSE_USER }} + CLICKHOUSE_PASSWORD: ${{ secrets.CLICKHOUSE_PASSWORD }} deploy-feature: needs: docker @@ -295,7 +303,7 @@ jobs: run: kubectl create namespace "$BRANCH_NS" --dry-run=client -o yaml | kubectl apply -f - - name: Copy secrets from cameleer namespace run: | - for SECRET in gitea-registry postgres-credentials opensearch-credentials cameleer-auth; do + for SECRET in gitea-registry postgres-credentials opensearch-credentials clickhouse-credentials cameleer-auth; do kubectl get secret "$SECRET" -n cameleer -o json \ | jq 'del(.metadata.namespace, .metadata.resourceVersion, .metadata.uid, .metadata.creationTimestamp, .metadata.managedFields)' \ | kubectl apply -n "$BRANCH_NS" -f - diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseSchemaInitializer.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseSchemaInitializer.java index a2a5f720..c9b3c49c 100644 --- a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseSchemaInitializer.java +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseSchemaInitializer.java @@ -30,23 +30,27 @@ public class ClickHouseSchemaInitializer { } @EventListener(ApplicationReadyEvent.class) - public void initializeSchema() throws IOException { - PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); - Resource[] scripts = resolver.getResources("classpath:clickhouse/*.sql"); + public void initializeSchema() { + try { + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + Resource[] scripts = resolver.getResources("classpath:clickhouse/*.sql"); - Arrays.sort(scripts, Comparator.comparing(Resource::getFilename)); + Arrays.sort(scripts, Comparator.comparing(Resource::getFilename)); - for (Resource script : scripts) { - String sql = script.getContentAsString(StandardCharsets.UTF_8); - log.info("Executing ClickHouse schema script: {}", script.getFilename()); - for (String statement : sql.split(";")) { - String trimmed = statement.trim(); - if (!trimmed.isEmpty()) { - clickHouseJdbc.execute(trimmed); + for (Resource script : scripts) { + String sql = script.getContentAsString(StandardCharsets.UTF_8); + log.info("Executing ClickHouse schema script: {}", script.getFilename()); + for (String statement : sql.split(";")) { + String trimmed = statement.trim(); + if (!trimmed.isEmpty()) { + clickHouseJdbc.execute(trimmed); + } } } - } - log.info("ClickHouse schema initialization complete ({} scripts)", scripts.length); + log.info("ClickHouse schema initialization complete ({} scripts)", scripts.length); + } catch (Exception e) { + log.error("ClickHouse schema initialization failed — server will continue but ClickHouse features may not work", e); + } } } diff --git a/deploy/base/server.yaml b/deploy/base/server.yaml index d0b00b97..63ef5009 100644 --- a/deploy/base/server.yaml +++ b/deploy/base/server.yaml @@ -79,6 +79,16 @@ spec: value: "true" - name: CLICKHOUSE_URL value: "jdbc:clickhouse://clickhouse.cameleer.svc.cluster.local:8123/cameleer?async_insert=1&wait_for_async_insert=0" + - name: CLICKHOUSE_USERNAME + valueFrom: + secretKeyRef: + name: clickhouse-credentials + key: CLICKHOUSE_USER + - name: CLICKHOUSE_PASSWORD + valueFrom: + secretKeyRef: + name: clickhouse-credentials + key: CLICKHOUSE_PASSWORD - name: CAMELEER_STORAGE_METRICS value: "postgres" diff --git a/deploy/clickhouse.yaml b/deploy/clickhouse.yaml index f9347556..8af4fb06 100644 --- a/deploy/clickhouse.yaml +++ b/deploy/clickhouse.yaml @@ -17,6 +17,19 @@ spec: containers: - name: clickhouse image: clickhouse/clickhouse-server:24.12 + env: + - name: CLICKHOUSE_USER + valueFrom: + secretKeyRef: + name: clickhouse-credentials + key: CLICKHOUSE_USER + - name: CLICKHOUSE_PASSWORD + valueFrom: + secretKeyRef: + name: clickhouse-credentials + key: CLICKHOUSE_PASSWORD + - name: CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT + value: "1" ports: - containerPort: 8123 name: http