fix(k8s): stabilize keycloak rollout and align CD deploy manifests
Update Keycloak probe/realm import behavior and authority config so auth services start reliably on the dev cluster, while keeping CD deployment steps aligned with the actual Kubernetes overlay behavior.
This commit is contained in:
@@ -47,11 +47,12 @@ jobs:
|
||||
- name: Kustomize Edit Image Tag
|
||||
working-directory: ./infra/k8s/overlays/dev
|
||||
run: |
|
||||
kustomize edit set image 192.168.241.13:8080/workclub-api=192.168.241.13:8080/workclub-api:$IMAGE_TAG
|
||||
kustomize edit set image 192.168.241.13:8080/workclub-frontend=192.168.241.13:8080/workclub-frontend:$IMAGE_TAG
|
||||
kustomize edit set image workclub-api=192.168.241.13:8080/workclub-api:$IMAGE_TAG
|
||||
kustomize edit set image workclub-frontend=192.168.241.13:8080/workclub-frontend:$IMAGE_TAG
|
||||
|
||||
- name: Deploy to Kubernetes
|
||||
run: |
|
||||
set -euo pipefail
|
||||
export KUBECONFIG=$HOME/.kube/config
|
||||
mkdir -p $HOME/.kube
|
||||
if echo "${{ secrets.KUBECONFIG }}" | grep -q "apiVersion"; then
|
||||
@@ -64,27 +65,33 @@ jobs:
|
||||
fi
|
||||
chmod 600 $KUBECONFIG
|
||||
|
||||
kubectl --kubeconfig="$KUBECONFIG" config view >/dev/null
|
||||
|
||||
# Diagnostics
|
||||
echo "Kubeconfig path: $KUBECONFIG"
|
||||
echo "Kubeconfig size: $(wc -c < $KUBECONFIG) bytes"
|
||||
echo "Available contexts:"
|
||||
kubectl config get-contexts
|
||||
kubectl --kubeconfig="$KUBECONFIG" config get-contexts
|
||||
|
||||
if ! grep -q "current-context" $KUBECONFIG; then
|
||||
echo "Warning: current-context missing, attempting to fix..."
|
||||
FIRST_CONTEXT=$(kubectl config get-contexts -o name | head -n 1)
|
||||
FIRST_CONTEXT=$(kubectl --kubeconfig="$KUBECONFIG" config get-contexts -o name | head -n 1)
|
||||
if [ -n "$FIRST_CONTEXT" ]; then
|
||||
kubectl config use-context "$FIRST_CONTEXT"
|
||||
kubectl --kubeconfig="$KUBECONFIG" config use-context "$FIRST_CONTEXT"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Current context: $(kubectl config current-context)"
|
||||
echo "Current context: $(kubectl --kubeconfig="$KUBECONFIG" config current-context)"
|
||||
|
||||
# Ensure target namespace exists
|
||||
kubectl create namespace workclub-dev --dry-run=client -o yaml | kubectl apply -f -
|
||||
kubectl --kubeconfig="$KUBECONFIG" create namespace workclub-dev --dry-run=client -o yaml | kubectl --kubeconfig="$KUBECONFIG" apply -f -
|
||||
|
||||
# Delete existing StatefulSet to allow immutable field changes (vct -> emptyDir)
|
||||
kubectl delete statefulset workclub-postgres -n workclub-dev --ignore-not-found
|
||||
# Apply manifests (non-destructive by default; avoid DB state churn)
|
||||
kubectl --kubeconfig="$KUBECONFIG" config view --minify # Verification of context
|
||||
kustomize build --load-restrictor LoadRestrictionsNone infra/k8s/overlays/dev | kubectl --kubeconfig="$KUBECONFIG" apply -f -
|
||||
|
||||
kubectl config view --minify # Verification of context
|
||||
kubectl apply -k infra/k8s/overlays/dev
|
||||
# Rollout verification
|
||||
kubectl --kubeconfig="$KUBECONFIG" rollout status statefulset/workclub-postgres -n workclub-dev --timeout=300s
|
||||
kubectl --kubeconfig="$KUBECONFIG" rollout status deployment/workclub-keycloak -n workclub-dev --timeout=600s
|
||||
kubectl --kubeconfig="$KUBECONFIG" rollout status deployment/workclub-api -n workclub-dev --timeout=300s
|
||||
kubectl --kubeconfig="$KUBECONFIG" rollout status deployment/workclub-frontend -n workclub-dev --timeout=300s
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
> - Docker Compose for local development (hot reload, Keycloak, PostgreSQL)
|
||||
> - Kubernetes manifests (Kustomize base + dev overlay)
|
||||
> - Gitea CI pipeline (`.gitea/workflows/ci.yml`) for backend/frontend/infrastructure validation
|
||||
> - Gitea CD bootstrap + deployment pipelines (`.gitea/workflows/cd-bootstrap.yml`, `.gitea/workflows/cd-deploy.yml`)
|
||||
> - Comprehensive TDD test suite (xUnit + Testcontainers, Vitest + RTL, Playwright E2E)
|
||||
> - Seed data for development (2 clubs, 5 users, sample tasks + shifts)
|
||||
>
|
||||
@@ -36,7 +37,7 @@ Build a multi-tenant internet application for managing work items over several m
|
||||
- **Testing**: TDD approach (tests first).
|
||||
- **Notifications**: None for MVP.
|
||||
- **CI extension**: Add Gitea-hosted CI pipeline for this repository.
|
||||
- **Pipeline scope**: CI-only (build/test/lint/manifest validation), no auto-deploy in this iteration.
|
||||
- **Pipeline scope (updated)**: CI + CD. CI handles build/test/lint/manifest validation; CD bootstrap publishes multi-arch images; CD deploy applies Kubernetes manifests.
|
||||
|
||||
**Research Findings**:
|
||||
- **Finbuckle.MultiTenant**: ClaimStrategy + HeaderStrategy fallback is production-proven (fullstackhero/dotnet-starter-kit pattern).
|
||||
@@ -73,6 +74,8 @@ Deliver a working multi-tenant club work management application where authentica
|
||||
- `/docker-compose.yml` — Local dev stack (PostgreSQL, Keycloak, .NET API, Next.js)
|
||||
- `/infra/k8s/` — Kustomize manifests (base + dev overlay)
|
||||
- `/.gitea/workflows/ci.yml` — Gitea Actions CI pipeline (parallel backend/frontend/infra checks)
|
||||
- `/.gitea/workflows/cd-bootstrap.yml` — Gitea Actions CD bootstrap workflow (manual multi-arch image publish)
|
||||
- `/.gitea/workflows/cd-deploy.yml` — Gitea Actions CD deployment workflow (Kubernetes deploy with Kustomize overlay)
|
||||
- PostgreSQL database with RLS policies on all tenant-scoped tables
|
||||
- Keycloak realm configuration with test users and club memberships
|
||||
- Seed data for development
|
||||
@@ -106,6 +109,8 @@ Deliver a working multi-tenant club work management application where authentica
|
||||
- TDD: all backend features have tests BEFORE implementation
|
||||
- Gitea-hosted CI pipeline for this repository (`code.hal9000.damnserver.com/MasterMito/work-club-manager`)
|
||||
- CI jobs run in parallel (backend, frontend, infrastructure validation)
|
||||
- Gitea-hosted CD bootstrap workflow for private registry image publication (`workclub-api`, `workclub-frontend`)
|
||||
- Gitea-hosted CD deployment workflow for Kubernetes dev namespace rollout (`workclub-dev`)
|
||||
|
||||
### Must NOT Have (Guardrails)
|
||||
- **No CQRS/MediatR** — Direct service injection from controllers/endpoints
|
||||
@@ -124,7 +129,7 @@ Deliver a working multi-tenant club work management application where authentica
|
||||
- **No in-memory database for tests** — Real PostgreSQL via Testcontainers
|
||||
- **No billing, subscriptions, or analytics dashboard**
|
||||
- **No mobile app**
|
||||
- **No automatic deployment in this CI extension** — CD remains out-of-scope for this append
|
||||
- **No single-step build-and-deploy coupling** — keep image bootstrap and cluster deployment as separate workflows
|
||||
|
||||
---
|
||||
|
||||
@@ -193,11 +198,11 @@ Wave 5 (After Wave 4 — polish + Docker):
|
||||
├── Task 24: Frontend Dockerfiles (dev + prod standalone) (depends: 18) [quick]
|
||||
└── Task 25: Kustomize dev overlay + resource limits + health checks (depends: 6, 23, 24) [unspecified-high]
|
||||
|
||||
Wave 6 (After Wave 5 — E2E + integration):
|
||||
Wave 6 (After Wave 5 — E2E + CI/CD integration):
|
||||
├── Task 26: Playwright E2E tests — auth flow + club switching (depends: 21, 22) [unspecified-high]
|
||||
├── Task 27: Playwright E2E tests — task management flow (depends: 19, 22) [unspecified-high]
|
||||
├── Task 28: Playwright E2E tests — shift sign-up flow (depends: 20, 22) [unspecified-high]
|
||||
└── Task 29: Gitea CI workflow (backend + frontend + infra checks) (depends: 12, 17, 23, 24, 25) [unspecified-high]
|
||||
└── Task 29: Gitea CI/CD workflows (CI checks + image bootstrap + Kubernetes deploy) (depends: 12, 17, 23, 24, 25) [unspecified-high]
|
||||
|
||||
Wave FINAL (After ALL tasks — independent review, 4 parallel):
|
||||
├── Task F1: Plan compliance audit (oracle)
|
||||
@@ -2525,34 +2530,37 @@ Max Concurrent: 6 (Wave 1)
|
||||
- Files: `frontend/tests/e2e/shifts.spec.ts`
|
||||
- Pre-commit: `bunx playwright test tests/e2e/shifts.spec.ts`
|
||||
|
||||
- [x] 29. Gitea CI Pipeline — Backend + Frontend + Infra Validation
|
||||
- [x] 29. Gitea CI/CD Pipelines — CI Validation + Image Bootstrap + Kubernetes Deploy
|
||||
|
||||
**What to do**:
|
||||
- Create `.gitea/workflows/ci.yml` for repository `code.hal9000.damnserver.com/MasterMito/work-club-manager`
|
||||
- Configure triggers:
|
||||
- Maintain `.gitea/workflows/ci.yml` for repository `code.hal9000.damnserver.com/MasterMito/work-club-manager`
|
||||
- Maintain `.gitea/workflows/cd-bootstrap.yml` for manual multi-arch image publishing to private registry
|
||||
- Maintain `.gitea/workflows/cd-deploy.yml` for Kubernetes deployment using Kustomize overlays
|
||||
- Configure CI triggers:
|
||||
- `push` on `main` and feature branches
|
||||
- `pull_request` targeting `main`
|
||||
- `workflow_dispatch` for manual reruns
|
||||
- Structure pipeline into parallel jobs (fail-fast disabled so all diagnostics are visible):
|
||||
- CI workflow structure (parallel validation jobs):
|
||||
- `backend-ci`: setup .NET 10 SDK, restore, build, run backend unit/integration tests
|
||||
- `frontend-ci`: setup Bun, install deps, run lint, type-check, unit tests, production build
|
||||
- `infra-ci`: validate Docker Compose and Kustomize manifests
|
||||
- Add path filters so docs-only changes skip heavy jobs when possible
|
||||
- Add dependency caching:
|
||||
- NuGet cache keyed by `**/*.csproj` + lock/context
|
||||
- Bun cache keyed by `bun.lockb`
|
||||
- Add artifact upload on failure:
|
||||
- `backend-test-results` (trx/log output)
|
||||
- `frontend-test-results` (vitest output)
|
||||
- `infra-validation-output`
|
||||
- CD bootstrap workflow behavior:
|
||||
- Manual trigger with `image_tag` + build flags
|
||||
- Buildx multi-arch build (`linux/amd64,linux/arm64`) for `workclub-api` and `workclub-frontend`
|
||||
- Push image tags to `192.168.241.13:8080` and emit task-31/task-32/task-33 evidence artifacts
|
||||
- CD deploy workflow behavior:
|
||||
- Triggered by successful bootstrap (`workflow_run`) or manual dispatch (`image_tag` input)
|
||||
- Install kubectl + kustomize on runner
|
||||
- Run `kustomize edit set image` in `infra/k8s/overlays/dev`
|
||||
- Apply manifests with `kubectl apply -k infra/k8s/overlays/dev`
|
||||
- Ensure namespace `workclub-dev` exists and perform deployment diagnostics
|
||||
- Enforce branch protection expectation in plan notes:
|
||||
- Required checks: `backend-ci`, `frontend-ci`, `infra-ci`
|
||||
- Keep CD out-of-scope in this append (no image push, no deploy steps)
|
||||
|
||||
**Must NOT do**:
|
||||
- Do NOT add deployment jobs (Kubernetes apply/helm/kustomize deploy)
|
||||
- Do NOT add secrets for registry push in this CI-only iteration
|
||||
- Do NOT couple CI workflow to release-tag deployment behavior
|
||||
- Do NOT collapse bootstrap and deployment into one opaque pipeline stage
|
||||
- Do NOT bypass image-tag pinning in deployment
|
||||
- Do NOT remove CI validation gates (`backend-ci`, `frontend-ci`, `infra-ci`)
|
||||
|
||||
**Recommended Agent Profile**:
|
||||
- **Category**: `unspecified-high`
|
||||
@@ -2568,10 +2576,13 @@ Max Concurrent: 6 (Wave 1)
|
||||
**References**:
|
||||
|
||||
**Pattern References**:
|
||||
- `.gitea/workflows/ci.yml` — Source of truth for CI checks
|
||||
- `.gitea/workflows/cd-bootstrap.yml` — Source of truth for image publish bootstrap
|
||||
- `.gitea/workflows/cd-deploy.yml` — Source of truth for deployment apply logic
|
||||
- `docker-compose.yml` — Source of truth for `docker compose config` validation
|
||||
- `infra/k8s/base/kustomization.yaml` and `infra/k8s/overlays/dev/kustomization.yaml` — Kustomize build inputs used by infra-ci job
|
||||
- `infra/k8s/base/kustomization.yaml` and `infra/k8s/overlays/dev/kustomization.yaml` — Kustomize build/apply inputs
|
||||
- `backend/WorkClub.sln` — Backend restore/build/test entrypoint for .NET job
|
||||
- `frontend/package.json` + `frontend/bun.lockb` — Frontend scripts and cache key anchor
|
||||
- `frontend/package.json` + `frontend/bun.lock` — Frontend scripts and cache key anchor
|
||||
|
||||
**External References**:
|
||||
- Gitea Actions docs: workflow syntax and trigger model (`.gitea/workflows/*.yml`)
|
||||
@@ -2596,6 +2607,18 @@ Max Concurrent: 6 (Wave 1)
|
||||
Failure Indicators: Missing job, skipped required job, or non-success conclusion
|
||||
Evidence: .sisyphus/evidence/task-29-gitea-ci-success.json
|
||||
|
||||
Scenario: CD bootstrap and deploy workflows are present and wired
|
||||
Tool: Bash
|
||||
Preconditions: Repository contains workflow files
|
||||
Steps:
|
||||
1. Assert `.gitea/workflows/cd-bootstrap.yml` exists
|
||||
2. Assert `.gitea/workflows/cd-deploy.yml` exists
|
||||
3. Grep bootstrap workflow for buildx multi-arch publish step
|
||||
4. Grep deploy workflow for `workflow_run`, `kustomize edit set image`, and `kubectl apply -k`
|
||||
Expected Result: Both CD workflows exist with expected bootstrap and deploy steps
|
||||
Failure Indicators: Missing file, missing trigger, or missing deploy commands
|
||||
Evidence: .sisyphus/evidence/task-29-gitea-cd-workflows.txt
|
||||
|
||||
Scenario: Pipeline fails on intentional backend break
|
||||
Tool: Bash (git + Gitea API)
|
||||
Preconditions: Temporary branch available, ability to push test commit
|
||||
@@ -2611,8 +2634,8 @@ Max Concurrent: 6 (Wave 1)
|
||||
```
|
||||
|
||||
**Commit**: YES
|
||||
- Message: `ci(gitea): add parallel CI workflow for backend, frontend, and infra validation`
|
||||
- Files: `.gitea/workflows/ci.yml`
|
||||
- Message: `ci(cd): add CI validation plus bootstrap and Kubernetes deployment workflows`
|
||||
- Files: `.gitea/workflows/ci.yml`, `.gitea/workflows/cd-bootstrap.yml`, `.gitea/workflows/cd-deploy.yml`
|
||||
- Pre-commit: `docker compose config && kustomize build infra/k8s/overlays/dev > /dev/null`
|
||||
|
||||
---
|
||||
@@ -2662,7 +2685,7 @@ Max Concurrent: 6 (Wave 1)
|
||||
| 4 | T18-T21 | `feat(ui): add layout, club-switcher, login, task and shift pages` | frontend/src/app/**/*.tsx, frontend/src/components/**/*.tsx | `bun run build && bun run test` |
|
||||
| 5 | T22-T25 | `infra(deploy): add full Docker Compose stack, Dockerfiles, and Kustomize dev overlay` | docker-compose.yml, **/Dockerfile*, infra/k8s/overlays/dev/**/*.yaml | `docker compose config && kustomize build infra/k8s/overlays/dev` |
|
||||
| 6 | T26-T28 | `test(e2e): add Playwright E2E tests for auth, tasks, and shifts` | frontend/tests/e2e/**/*.spec.ts | `bunx playwright test` |
|
||||
| 6 | T29 | `ci(gitea): add parallel CI workflow for backend, frontend, and infra validation` | .gitea/workflows/ci.yml | `docker compose config && kustomize build infra/k8s/overlays/dev > /dev/null` |
|
||||
| 6 | T29 | `ci(cd): add CI validation plus bootstrap and Kubernetes deployment workflows` | .gitea/workflows/ci.yml, .gitea/workflows/cd-bootstrap.yml, .gitea/workflows/cd-deploy.yml | `docker compose config && kustomize build infra/k8s/overlays/dev > /dev/null` |
|
||||
|
||||
---
|
||||
|
||||
@@ -2699,6 +2722,12 @@ kustomize build infra/k8s/overlays/dev > /dev/null # Expected: Exit 0
|
||||
|
||||
# CI workflow file present and includes required jobs
|
||||
grep -E "backend-ci|frontend-ci|infra-ci" .gitea/workflows/ci.yml # Expected: all 3 job names present
|
||||
|
||||
# CD bootstrap workflow present with multi-arch publish
|
||||
grep -E "buildx|linux/amd64,linux/arm64|workclub-api|workclub-frontend" .gitea/workflows/cd-bootstrap.yml
|
||||
|
||||
# CD deploy workflow present with deploy trigger and apply step
|
||||
grep -E "workflow_run|kustomize edit set image|kubectl apply -k" .gitea/workflows/cd-deploy.yml
|
||||
```
|
||||
|
||||
### Final Checklist
|
||||
@@ -2710,6 +2739,7 @@ grep -E "backend-ci|frontend-ci|infra-ci" .gitea/workflows/ci.yml # Expected: a
|
||||
- [x] Docker Compose stack starts clean and healthy
|
||||
- [x] Kustomize manifests build without errors
|
||||
- [x] Gitea CI workflow exists and references backend-ci/frontend-ci/infra-ci
|
||||
- [x] Gitea CD bootstrap and deploy workflows exist and are wired to image publish/deploy steps
|
||||
- [x] RLS isolation proven at database level
|
||||
- [x] Cross-tenant access returns 403
|
||||
- [x] Task state machine rejects invalid transitions (422)
|
||||
|
||||
@@ -62,6 +62,22 @@ public class SeedDataService
|
||||
");
|
||||
|
||||
// Create admin bypass policies (idempotent)
|
||||
await context.Database.ExecuteSqlRawAsync(@"
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'app_admin') THEN
|
||||
CREATE ROLE app_admin;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
GRANT app_admin TO app;
|
||||
GRANT USAGE ON SCHEMA public TO app_admin;
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO app_admin;
|
||||
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO app_admin;
|
||||
ALTER DEFAULT PRIVILEGES FOR ROLE app IN SCHEMA public GRANT ALL ON TABLES TO app_admin;
|
||||
ALTER DEFAULT PRIVILEGES FOR ROLE app IN SCHEMA public GRANT ALL ON SEQUENCES TO app_admin;
|
||||
");
|
||||
|
||||
await context.Database.ExecuteSqlRawAsync(@"
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename='clubs' AND policyname='bypass_rls_policy') THEN
|
||||
|
||||
@@ -67,8 +67,13 @@ spec:
|
||||
secretKeyRef:
|
||||
name: workclub-secrets
|
||||
key: database-connection-string
|
||||
- name: Keycloak__Url
|
||||
- name: Keycloak__Authority
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: workclub-config
|
||||
key: keycloak-url
|
||||
key: keycloak-authority
|
||||
- name: Keycloak__Audience
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: workclub-config
|
||||
key: keycloak-audience
|
||||
|
||||
@@ -9,6 +9,8 @@ data:
|
||||
cors-origins: "http://localhost:3000"
|
||||
api-base-url: "http://workclub-api"
|
||||
keycloak-url: "http://workclub-keycloak"
|
||||
keycloak-authority: "http://workclub-keycloak/realms/workclub"
|
||||
keycloak-audience: "workclub-api"
|
||||
keycloak-realm: "workclub"
|
||||
|
||||
# Database configuration
|
||||
@@ -39,3 +41,18 @@ data:
|
||||
\c workclub
|
||||
GRANT ALL PRIVILEGES ON SCHEMA public TO app;
|
||||
ALTER SCHEMA public OWNER TO app;
|
||||
|
||||
-- App admin role for RLS bypass policies used by API startup seed
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'app_admin') THEN
|
||||
CREATE ROLE app_admin;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
GRANT app_admin TO app WITH INHERIT FALSE, SET TRUE;
|
||||
GRANT USAGE ON SCHEMA public TO app_admin;
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO app_admin;
|
||||
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO app_admin;
|
||||
ALTER DEFAULT PRIVILEGES FOR ROLE app IN SCHEMA public GRANT ALL ON TABLES TO app_admin;
|
||||
ALTER DEFAULT PRIVILEGES FOR ROLE app IN SCHEMA public GRANT ALL ON SEQUENCES TO app_admin;
|
||||
|
||||
@@ -7,6 +7,9 @@ metadata:
|
||||
component: auth
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
progressDeadlineSeconds: 1800
|
||||
selector:
|
||||
matchLabels:
|
||||
app: workclub-keycloak
|
||||
@@ -21,25 +24,37 @@ spec:
|
||||
image: quay.io/keycloak/keycloak:26.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- start
|
||||
- start-dev
|
||||
- --import-realm
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
- name: management
|
||||
containerPort: 9000
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health/ready
|
||||
port: http
|
||||
initialDelaySeconds: 150
|
||||
port: management
|
||||
initialDelaySeconds: 240
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 10
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health/ready
|
||||
port: management
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 120
|
||||
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health/live
|
||||
port: http
|
||||
initialDelaySeconds: 240
|
||||
port: management
|
||||
initialDelaySeconds: 420
|
||||
periodSeconds: 20
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
@@ -84,3 +99,11 @@ spec:
|
||||
value: "true"
|
||||
- name: KC_HEALTH_ENABLED
|
||||
value: "true"
|
||||
volumeMounts:
|
||||
- name: keycloak-realm-import
|
||||
mountPath: /opt/keycloak/data/import
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: keycloak-realm-import
|
||||
configMap:
|
||||
name: keycloak-realm-import
|
||||
|
||||
246
infra/k8s/base/keycloak-realm-import-configmap.yaml
Normal file
246
infra/k8s/base/keycloak-realm-import-configmap.yaml
Normal file
@@ -0,0 +1,246 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: keycloak-realm-import
|
||||
labels:
|
||||
app: workclub-keycloak
|
||||
data:
|
||||
realm-export.json: |
|
||||
{
|
||||
"realm": "workclub",
|
||||
"enabled": true,
|
||||
"displayName": "Work Club Manager",
|
||||
"registrationAllowed": false,
|
||||
"rememberMe": true,
|
||||
"verifyEmail": false,
|
||||
"loginWithEmailAllowed": true,
|
||||
"duplicateEmailsAllowed": false,
|
||||
"resetPasswordAllowed": true,
|
||||
"editUsernameAllowed": false,
|
||||
"bruteForceProtected": true,
|
||||
"clients": [
|
||||
{
|
||||
"clientId": "workclub-api",
|
||||
"name": "Work Club API",
|
||||
"enabled": true,
|
||||
"protocol": "openid-connect",
|
||||
"clientAuthenticatorType": "client-secret",
|
||||
"secret": "dev-secret-workclub-api-change-in-production",
|
||||
"redirectUris": [],
|
||||
"webOrigins": [],
|
||||
"publicClient": false,
|
||||
"directAccessGrantsEnabled": false,
|
||||
"serviceAccountsEnabled": false,
|
||||
"standardFlowEnabled": false,
|
||||
"implicitFlowEnabled": false,
|
||||
"fullScopeAllowed": true,
|
||||
"protocolMappers": [
|
||||
{
|
||||
"name": "audience-workclub-api",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-audience-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"included.client.audience": "workclub-api",
|
||||
"id.token.claim": "false",
|
||||
"access.token.claim": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "clubs-claim",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"user.attribute": "clubs",
|
||||
"claim.name": "clubs",
|
||||
"jsonType.label": "String",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"userinfo.token.claim": "true"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"clientId": "workclub-app",
|
||||
"name": "Work Club Frontend",
|
||||
"enabled": true,
|
||||
"protocol": "openid-connect",
|
||||
"publicClient": true,
|
||||
"redirectUris": [
|
||||
"http://localhost:3000/*",
|
||||
"http://localhost:3001/*",
|
||||
"http://workclub-frontend/*"
|
||||
],
|
||||
"webOrigins": [
|
||||
"http://localhost:3000",
|
||||
"http://localhost:3001",
|
||||
"http://workclub-frontend"
|
||||
],
|
||||
"directAccessGrantsEnabled": true,
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": false,
|
||||
"fullScopeAllowed": true,
|
||||
"protocolMappers": [
|
||||
{
|
||||
"name": "audience-workclub-api",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-audience-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"included.client.audience": "workclub-api",
|
||||
"id.token.claim": "false",
|
||||
"access.token.claim": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "clubs-claim",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"user.attribute": "clubs",
|
||||
"claim.name": "clubs",
|
||||
"jsonType.label": "String",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"userinfo.token.claim": "true"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"roles": {
|
||||
"realm": [
|
||||
{
|
||||
"name": "admin",
|
||||
"description": "Club admin"
|
||||
},
|
||||
{
|
||||
"name": "manager",
|
||||
"description": "Club manager"
|
||||
},
|
||||
{
|
||||
"name": "member",
|
||||
"description": "Club member"
|
||||
},
|
||||
{
|
||||
"name": "viewer",
|
||||
"description": "Club viewer"
|
||||
}
|
||||
]
|
||||
},
|
||||
"users": [
|
||||
{
|
||||
"username": "admin@test.com",
|
||||
"enabled": true,
|
||||
"email": "admin@test.com",
|
||||
"firstName": "Admin",
|
||||
"lastName": "User",
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "testpass123",
|
||||
"temporary": false
|
||||
}
|
||||
],
|
||||
"realmRoles": [
|
||||
"admin"
|
||||
],
|
||||
"attributes": {
|
||||
"clubs": [
|
||||
"64e05b5e-ef45-81d7-f2e8-3d14bd197383,Admin,3b4afcfa-1352-8fc7-b497-8ab52a0d5fda,Member"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"username": "manager@test.com",
|
||||
"enabled": true,
|
||||
"email": "manager@test.com",
|
||||
"firstName": "Manager",
|
||||
"lastName": "User",
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "testpass123",
|
||||
"temporary": false
|
||||
}
|
||||
],
|
||||
"realmRoles": [
|
||||
"manager"
|
||||
],
|
||||
"attributes": {
|
||||
"clubs": [
|
||||
"64e05b5e-ef45-81d7-f2e8-3d14bd197383,Manager"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"username": "member1@test.com",
|
||||
"enabled": true,
|
||||
"email": "member1@test.com",
|
||||
"firstName": "Member",
|
||||
"lastName": "One",
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "testpass123",
|
||||
"temporary": false
|
||||
}
|
||||
],
|
||||
"realmRoles": [
|
||||
"member"
|
||||
],
|
||||
"attributes": {
|
||||
"clubs": [
|
||||
"64e05b5e-ef45-81d7-f2e8-3d14bd197383,Member,3b4afcfa-1352-8fc7-b497-8ab52a0d5fda,Member"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"username": "member2@test.com",
|
||||
"enabled": true,
|
||||
"email": "member2@test.com",
|
||||
"firstName": "Member",
|
||||
"lastName": "Two",
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "testpass123",
|
||||
"temporary": false
|
||||
}
|
||||
],
|
||||
"realmRoles": [
|
||||
"member"
|
||||
],
|
||||
"attributes": {
|
||||
"clubs": [
|
||||
"64e05b5e-ef45-81d7-f2e8-3d14bd197383,Member"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"username": "viewer@test.com",
|
||||
"enabled": true,
|
||||
"email": "viewer@test.com",
|
||||
"firstName": "Viewer",
|
||||
"lastName": "User",
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "testpass123",
|
||||
"temporary": false
|
||||
}
|
||||
],
|
||||
"realmRoles": [
|
||||
"viewer"
|
||||
],
|
||||
"attributes": {
|
||||
"clubs": [
|
||||
"64e05b5e-ef45-81d7-f2e8-3d14bd197383,Viewer"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -9,6 +9,10 @@ resources:
|
||||
- postgres-statefulset.yaml
|
||||
- postgres-service.yaml
|
||||
- keycloak-deployment.yaml
|
||||
- keycloak-realm-import-configmap.yaml
|
||||
- keycloak-service.yaml
|
||||
- configmap.yaml
|
||||
- ingress.yaml
|
||||
|
||||
generatorOptions:
|
||||
disableNameSuffixHash: true
|
||||
|
||||
@@ -11,10 +11,10 @@ commonLabels:
|
||||
environment: development
|
||||
|
||||
images:
|
||||
- name: workclub-api
|
||||
- name: 192.168.241.13:8080/workclub-api
|
||||
newName: 192.168.241.13:8080/workclub-api
|
||||
newTag: dev
|
||||
- name: workclub-frontend
|
||||
- name: 192.168.241.13:8080/workclub-frontend
|
||||
newName: 192.168.241.13:8080/workclub-frontend
|
||||
newTag: dev
|
||||
|
||||
|
||||
Reference in New Issue
Block a user