From f83d1157b1c78a4897562b000c2466d5a4eff308 Mon Sep 17 00:00:00 2001 From: Prodiglagla <348945921@qq.com> Date: Sun, 14 Jun 2026 11:46:13 +0800 Subject: [PATCH] bootstrap ircs-prod gitops config --- .gitattributes | 3 + README.md | 20 + apps/ircs-prod-core-application.yaml | 24 + apps/ircs-prod-edge-application.yaml | 21 + docs/cutover-runbook.md | 22 + docs/data-migration-runbook.md | 20 + ircs-prod/core/00-namespace.yaml | 7 + ircs-prod/core/01-app-config.yaml | 25 + ircs-prod/core/02-resource-quota.yaml | 15 + ircs-prod/core/kustomization.yaml | 33 ++ .../core/manifests/aggregation-worker.yaml | 102 ++++ ircs-prod/core/manifests/catalog-service.yaml | 102 ++++ ircs-prod/core/manifests/config-service.yaml | 110 ++++ ircs-prod/core/manifests/content-service.yaml | 128 +++++ .../core/manifests/credential-service.yaml | 113 +++++ ircs-prod/core/manifests/elasticsearch.yaml | 143 ++++++ ircs-prod/core/manifests/frontend-bff.yaml | 233 +++++++++ .../core/manifests/frontend-portal-admin.yaml | 468 ++++++++++++++++++ .../core/manifests/identity-service.yaml | 149 ++++++ .../core/manifests/ingestion-worker.yaml | 96 ++++ .../core/manifests/interaction-service.yaml | 121 +++++ ircs-prod/core/manifests/magnet-service.yaml | 106 ++++ ircs-prod/core/manifests/metadata-worker.yaml | 116 +++++ ircs-prod/core/manifests/migrator-job.yaml | 53 ++ .../core/manifests/normalization-worker.yaml | 127 +++++ .../core/manifests/notification-worker.yaml | 138 ++++++ .../manifests/observability-monitoring.yaml | 70 +++ ircs-prod/core/manifests/ops-service.yaml | 141 ++++++ ircs-prod/core/manifests/portal-service.yaml | 119 +++++ ircs-prod/core/manifests/postgres.yaml | 95 ++++ ircs-prod/core/manifests/rabbitmq.yaml | 99 ++++ ircs-prod/core/manifests/scraper-service.yaml | 133 +++++ ircs-prod/core/manifests/search-service.yaml | 149 ++++++ ircs-prod/core/manifests/storage-service.yaml | 147 ++++++ ircs-prod/core/manifests/task-service.yaml | 152 ++++++ ircs-prod/core/manifests/valkey.yaml | 77 +++ ircs-prod/edge-cutover/httproutes.yaml | 55 ++ ircs-prod/edge-cutover/kustomization.yaml | 5 + scripts/cutover-httproute.ps1 | 26 + scripts/migrate-compatible-data.ps1 | 54 ++ scripts/prepare-prod-secrets.ps1 | 62 +++ 41 files changed, 3879 insertions(+) create mode 100644 .gitattributes create mode 100644 README.md create mode 100644 apps/ircs-prod-core-application.yaml create mode 100644 apps/ircs-prod-edge-application.yaml create mode 100644 docs/cutover-runbook.md create mode 100644 docs/data-migration-runbook.md create mode 100644 ircs-prod/core/00-namespace.yaml create mode 100644 ircs-prod/core/01-app-config.yaml create mode 100644 ircs-prod/core/02-resource-quota.yaml create mode 100644 ircs-prod/core/kustomization.yaml create mode 100644 ircs-prod/core/manifests/aggregation-worker.yaml create mode 100644 ircs-prod/core/manifests/catalog-service.yaml create mode 100644 ircs-prod/core/manifests/config-service.yaml create mode 100644 ircs-prod/core/manifests/content-service.yaml create mode 100644 ircs-prod/core/manifests/credential-service.yaml create mode 100644 ircs-prod/core/manifests/elasticsearch.yaml create mode 100644 ircs-prod/core/manifests/frontend-bff.yaml create mode 100644 ircs-prod/core/manifests/frontend-portal-admin.yaml create mode 100644 ircs-prod/core/manifests/identity-service.yaml create mode 100644 ircs-prod/core/manifests/ingestion-worker.yaml create mode 100644 ircs-prod/core/manifests/interaction-service.yaml create mode 100644 ircs-prod/core/manifests/magnet-service.yaml create mode 100644 ircs-prod/core/manifests/metadata-worker.yaml create mode 100644 ircs-prod/core/manifests/migrator-job.yaml create mode 100644 ircs-prod/core/manifests/normalization-worker.yaml create mode 100644 ircs-prod/core/manifests/notification-worker.yaml create mode 100644 ircs-prod/core/manifests/observability-monitoring.yaml create mode 100644 ircs-prod/core/manifests/ops-service.yaml create mode 100644 ircs-prod/core/manifests/portal-service.yaml create mode 100644 ircs-prod/core/manifests/postgres.yaml create mode 100644 ircs-prod/core/manifests/rabbitmq.yaml create mode 100644 ircs-prod/core/manifests/scraper-service.yaml create mode 100644 ircs-prod/core/manifests/search-service.yaml create mode 100644 ircs-prod/core/manifests/storage-service.yaml create mode 100644 ircs-prod/core/manifests/task-service.yaml create mode 100644 ircs-prod/core/manifests/valkey.yaml create mode 100644 ircs-prod/edge-cutover/httproutes.yaml create mode 100644 ircs-prod/edge-cutover/kustomization.yaml create mode 100644 scripts/cutover-httproute.ps1 create mode 100644 scripts/migrate-compatible-data.ps1 create mode 100644 scripts/prepare-prod-secrets.ps1 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..34d496c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.ps1 text eol=crlf +*.yaml text eol=lf +*.md text eol=lf diff --git a/README.md b/README.md new file mode 100644 index 0000000..15605ca --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# ircs-prod-config + +Independent GitOps repository for IRCS V3 production namespace `ircs-prod`. + +This repo intentionally separates production runtime state from the source repository: + +- source repo: `gitea-admin/ircs-project-v3`, builds and pushes service images. +- GitOps repo: `gitea-admin/ircs-prod-config`, declares Kubernetes runtime resources. + +Secrets are not stored here. Run `scripts/prepare-prod-secrets.ps1` before syncing the core ArgoCD application. + +Deployment order: + +1. Prepare `ircs-prod` namespace and secrets. +2. Apply `apps/ircs-prod-core-application.yaml` to ArgoCD and sync it. +3. Run V3 migrator and compatible data migration from `ircs-system`. +4. Verify portals and BFF through cluster endpoints. +5. Sync or apply `ircs-prod/edge-cutover` and remove old `ircs-system` routes. + +Edge cutover is isolated from core to avoid hostname conflict while the old `ircs-system` routes still own production domains. diff --git a/apps/ircs-prod-core-application.yaml b/apps/ircs-prod-core-application.yaml new file mode 100644 index 0000000..eae6d04 --- /dev/null +++ b/apps/ircs-prod-core-application.yaml @@ -0,0 +1,24 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: ircs-prod-core + namespace: argocd + labels: + app.kubernetes.io/part-of: ircs + environment: prod +spec: + project: default + source: + repoURL: https://gitea.mnnu.eu.org/gitea-admin/ircs-prod-config.git + targetRevision: main + path: ircs-prod/core + destination: + server: https://kubernetes.default.svc + namespace: ircs-prod + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/apps/ircs-prod-edge-application.yaml b/apps/ircs-prod-edge-application.yaml new file mode 100644 index 0000000..913da4a --- /dev/null +++ b/apps/ircs-prod-edge-application.yaml @@ -0,0 +1,21 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: ircs-prod-edge + namespace: argocd + labels: + app.kubernetes.io/part-of: ircs + environment: prod +spec: + project: default + source: + repoURL: https://gitea.mnnu.eu.org/gitea-admin/ircs-prod-config.git + targetRevision: main + path: ircs-prod/edge-cutover + destination: + server: https://kubernetes.default.svc + namespace: ircs-prod + syncPolicy: + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/docs/cutover-runbook.md b/docs/cutover-runbook.md new file mode 100644 index 0000000..c0d9e15 --- /dev/null +++ b/docs/cutover-runbook.md @@ -0,0 +1,22 @@ +# HTTPRoute cutover runbook + +Current production domains are owned by `ircs-system` routes: + +- `huawai.sophia.fr.eu.org` -> `ircs-system/huawai-svc:80` +- `ircs.sophia.fr.eu.org` -> `ircs-system/ircs-frontend-svc:80` + +V3 production routes are declared under `ircs-prod/edge-cutover`: + +- `huawai.sophia.fr.eu.org` -> `ircs-prod/ircs-frontend-gateway:80` +- `ircs.sophia.fr.eu.org` -> `ircs-prod/ircs-frontend-gateway:8080` + +Cutover order: + +1. Confirm `ircs-prod` pods are Ready. +2. Confirm cluster-internal portal/admin smoke is healthy. +3. Disable automated sync on old `argocd/ircs-app` so it does not recreate old routes. +4. Apply edge routes and delete old `ircs-system` business routes. +5. Verify Envoy Gateway accepts the new routes. +6. Verify external domains through the NLB/Cloudflare path. + +Use `scripts/cutover-httproute.ps1 -Execute` from this repo root when ready. diff --git a/docs/data-migration-runbook.md b/docs/data-migration-runbook.md new file mode 100644 index 0000000..1f548d6 --- /dev/null +++ b/docs/data-migration-runbook.md @@ -0,0 +1,20 @@ +# ircs-system to ircs-prod compatible data migration + +Goal: migrate old `ircs-system` business data into V3 `ircs-prod` while allowing incompatible runtime tables to be discarded. + +Required order: + +1. Back up old `ircs-system` PostgreSQL. +2. Prepare `ircs-prod` secrets with `scripts/prepare-prod-secrets.ps1`. +3. Sync `ircs-prod-core` and wait for PostgreSQL, RabbitMQ, Valkey, Elasticsearch, services, and migrator. +4. Run `scripts/migrate-compatible-data.ps1` once without `-Execute` to compare table presence. +5. Run `scripts/migrate-compatible-data.ps1 -Execute -TruncateTarget` only when `ircs-prod` has no valuable data. +6. Rebuild search/index derived state through V3 ops runners after migration. + +Migration policy: + +- Copy compatible V1 business tables only. +- Do not copy `databasechangelog` or `databasechangeloglock`. +- Do not copy V3 derived audit/outbox/maintenance tables. +- If a table or column becomes incompatible, prefer explicit table-level skip plus a written note over silent lossy conversion. +- Existing R2 bucket remains `ircs` so historical media URLs stay valid. diff --git a/ircs-prod/core/00-namespace.yaml b/ircs-prod/core/00-namespace.yaml new file mode 100644 index 0000000..b469b7f --- /dev/null +++ b/ircs-prod/core/00-namespace.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: ircs-prod + labels: + app.kubernetes.io/part-of: ircs + environment: prod diff --git a/ircs-prod/core/01-app-config.yaml b/ircs-prod/core/01-app-config.yaml new file mode 100644 index 0000000..f16abe6 --- /dev/null +++ b/ircs-prod/core/01-app-config.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: ircs-prod-app-config + namespace: ircs-prod + labels: + app.kubernetes.io/part-of: ircs + environment: prod +data: + APP_MAIL_ENABLED: "true" + DB_URL: jdbc:postgresql://postgres-svc.ircs-prod.svc.cluster.local:5432/ircs?connectionTimeZone=UTC + ELASTICSEARCH_URIS: http://elasticsearch-svc.ircs-prod.svc.cluster.local:9200 + MAIL_FROM: HuaWai System + MAIL_HOST: smtp.gmail.com + MAIL_PORT: "465" + MANAGEMENT_ENDPOINT_HEALTH_SHOW_COMPONENTS: always + MANAGEMENT_HEALTH_MAIL_ENABLED: "false" + OTEL_ENDPOINT: http://otel-collector.monitoring.svc.cluster.local:4318/v1/traces + R2_BUCKET_NAME: ircs + R2_PUBLIC_DOMAIN: img.mnnu.eu.org + RABBITMQ_HOST: rabbitmq-svc.ircs-prod.svc.cluster.local + SPRING_DATA_REDIS_HOST: valkey-svc.ircs-prod.svc.cluster.local + SPRING_DATA_REDIS_PORT: "6379" + VALKEY_HOST: valkey-svc.ircs-prod.svc.cluster.local + VALKEY_PORT: "6379" diff --git a/ircs-prod/core/02-resource-quota.yaml b/ircs-prod/core/02-resource-quota.yaml new file mode 100644 index 0000000..7e1bb92 --- /dev/null +++ b/ircs-prod/core/02-resource-quota.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ResourceQuota +metadata: + name: ircs-prod-quota + namespace: ircs-prod +spec: + hard: + pods: "34" + services: "30" + configmaps: "40" + secrets: "40" + requests.cpu: "6" + requests.memory: 12Gi + limits.cpu: "12" + limits.memory: 24Gi diff --git a/ircs-prod/core/kustomization.yaml b/ircs-prod/core/kustomization.yaml new file mode 100644 index 0000000..eea08bb --- /dev/null +++ b/ircs-prod/core/kustomization.yaml @@ -0,0 +1,33 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - 00-namespace.yaml + - 01-app-config.yaml + - 02-resource-quota.yaml + - manifests/aggregation-worker.yaml + - manifests/catalog-service.yaml + - manifests/config-service.yaml + - manifests/content-service.yaml + - manifests/credential-service.yaml + - manifests/elasticsearch.yaml + - manifests/frontend-bff.yaml + - manifests/frontend-portal-admin.yaml + - manifests/identity-service.yaml + - manifests/ingestion-worker.yaml + - manifests/interaction-service.yaml + - manifests/magnet-service.yaml + - manifests/metadata-worker.yaml + - manifests/migrator-job.yaml + - manifests/normalization-worker.yaml + - manifests/notification-worker.yaml + - manifests/observability-monitoring.yaml + - manifests/ops-service.yaml + - manifests/portal-service.yaml + - manifests/postgres.yaml + - manifests/rabbitmq.yaml + - manifests/scraper-service.yaml + - manifests/search-service.yaml + - manifests/storage-service.yaml + - manifests/task-service.yaml + - manifests/valkey.yaml + diff --git a/ircs-prod/core/manifests/aggregation-worker.yaml b/ircs-prod/core/manifests/aggregation-worker.yaml new file mode 100644 index 0000000..01fb3dc --- /dev/null +++ b/ircs-prod/core/manifests/aggregation-worker.yaml @@ -0,0 +1,102 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-aggregation-worker + namespace: ircs-prod + labels: + app: ircs-aggregation-worker + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-aggregation-worker + template: + metadata: + labels: + app: ircs-aggregation-worker + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-aggregation-worker@sha256:154db2f8da961cb300308f7d06337edc0ab11a3784a3fa432d23bf9cb2460e87 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-aggregation-worker + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_AGGREGATION_SCHEDULER_ENABLED + value: "false" + - name: APP_AGGREGATION_BATCH_SIZE + value: "1" + - name: APP_AGGREGATION_CONFIG_LISTENER_ENABLED + value: "true" + - name: APP_AGGREGATION_SCHEDULER_FIXED_DELAY_MS + value: "5000" + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi + diff --git a/ircs-prod/core/manifests/catalog-service.yaml b/ircs-prod/core/manifests/catalog-service.yaml new file mode 100644 index 0000000..e88f21c --- /dev/null +++ b/ircs-prod/core/manifests/catalog-service.yaml @@ -0,0 +1,102 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-catalog-service + namespace: ircs-prod + labels: + app: ircs-catalog-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-catalog-service + template: + metadata: + labels: + app: ircs-catalog-service + app.kubernetes.io/part-of: ircs + environment: prod + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-catalog-service@sha256:c9c4aed0785e8d9716268b1b9f8f34d7bcd66ec5e3f1389c206185f72fa765e3 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-catalog-service + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_CATALOG_CACHE_ENABLED + value: "true" + - name: APP_CATALOG_CACHE_STANDARD_DICTIONARY_TTL + value: PT10M + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-catalog-service + namespace: ircs-prod + labels: + app: ircs-catalog-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-catalog-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/config-service.yaml b/ircs-prod/core/manifests/config-service.yaml new file mode 100644 index 0000000..62e3e54 --- /dev/null +++ b/ircs-prod/core/manifests/config-service.yaml @@ -0,0 +1,110 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-config-service + namespace: ircs-prod + labels: + app: ircs-config-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-config-service + template: + metadata: + labels: + app: ircs-config-service + app.kubernetes.io/part-of: ircs + environment: prod + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-config-service@sha256:b19eeefe3dbac9483dbb01589afb79e89e43b702619186e6bb7ba988f1e7069e + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-config-service + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-config-service + namespace: ircs-prod + labels: + app: ircs-config-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-config-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/content-service.yaml b/ircs-prod/core/manifests/content-service.yaml new file mode 100644 index 0000000..d69b217 --- /dev/null +++ b/ircs-prod/core/manifests/content-service.yaml @@ -0,0 +1,128 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-content-service + namespace: ircs-prod + labels: + app: ircs-content-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-content-service + template: + metadata: + labels: + app: ircs-content-service + app.kubernetes.io/part-of: ircs + environment: prod + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-content-service@sha256:414245458ad96793c17e88a74c1aa702c8aa593331d64d217d53fa6234bcb617 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-content-service + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_CONTENT_LISTENER_ENABLED + value: "true" + - name: APP_CONTENT_CONFIG_LISTENER_ENABLED + value: "true" + - name: APP_CONTENT_MAINTENANCE_GATE_LISTENER_ENABLED + value: "true" + - name: APP_CONTENT_RESOLVER_PRESET_SEED_ENABLED + value: "true" + - name: APP_CONTENT_SCRAPER_BASE_URL + value: http://ircs-scraper-service.ircs-prod.svc.cluster.local:8080 + - name: IRCS_OUTBOUND_CIRCUIT_CONTENT_REFETCH_SCRAPER_ENABLED + value: "true" + - name: IRCS_OUTBOUND_CIRCUIT_CONTENT_REFETCH_SCRAPER_FAILURE_THRESHOLD + value: "5" + - name: IRCS_OUTBOUND_CIRCUIT_CONTENT_REFETCH_SCRAPER_OPEN_DURATION_MS + value: "30000" + - name: IRCS_OUTBOUND_CIRCUIT_CONTENT_REFETCH_SCRAPER_HALF_OPEN_MAX_CALLS + value: "1" + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-content-service + namespace: ircs-prod + labels: + app: ircs-content-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-content-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/credential-service.yaml b/ircs-prod/core/manifests/credential-service.yaml new file mode 100644 index 0000000..60be47a --- /dev/null +++ b/ircs-prod/core/manifests/credential-service.yaml @@ -0,0 +1,113 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-credential-service + namespace: ircs-prod + labels: + app: ircs-credential-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-credential-service + template: + metadata: + labels: + app: ircs-credential-service + app.kubernetes.io/part-of: ircs + environment: prod + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-credential-service@sha256:327c7307de0547d7d320010cffcee2f098cddb4ade6a94d8020c864809078eda + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-credential-service + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_CREDENTIAL_SERVICE_TOKEN + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: SERVICE_CREDENTIAL_TOKEN + - name: APP_CREDENTIAL_INITIALIZER_ENABLED + value: "true" + - name: APP_CREDENTIAL_INITIALIZER_FILE_PATH + value: /etc/ircs/init/credentials.json + - name: APP_CREDENTIAL_INITIALIZER_CLASSPATH_FALLBACK_ENABLED + value: "true" + - name: APP_CREDENTIAL_CACHE_ENABLED + value: "true" + - name: APP_CREDENTIAL_CACHE_SUMMARY_TTL + value: PT60S + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-credential-service + namespace: ircs-prod + labels: + app: ircs-credential-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-credential-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/elasticsearch.yaml b/ircs-prod/core/manifests/elasticsearch.yaml new file mode 100644 index 0000000..c71d445 --- /dev/null +++ b/ircs-prod/core/manifests/elasticsearch.yaml @@ -0,0 +1,143 @@ +apiVersion: v1 +kind: Service +metadata: + name: elasticsearch-svc + namespace: ircs-prod + labels: + app: elasticsearch + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: elasticsearch + ports: + - name: http + port: 9200 + targetPort: http + - name: transport + port: 9300 + targetPort: transport +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: elasticsearch + namespace: ircs-prod + labels: + app: elasticsearch + app.kubernetes.io/part-of: ircs + environment: prod +spec: + serviceName: elasticsearch-svc + replicas: 1 + selector: + matchLabels: + app: elasticsearch + template: + metadata: + labels: + app: elasticsearch + app.kubernetes.io/part-of: ircs + environment: prod + spec: + initContainers: + - name: install-plugins + image: alpine:3.19 + command: + - sh + - -c + - | + set -e + apk add --no-cache unzip wget + mkdir -p /plugins/ik /plugins/pinyin + + if [ ! -f /plugins/ik/plugin-descriptor.properties ]; then + rm -rf /plugins/ik/* + wget -O /tmp/ik.zip https://release.infinilabs.com/analysis-ik/stable/elasticsearch-analysis-ik-9.1.4.zip + unzip -q /tmp/ik.zip -d /plugins/ik + rm /tmp/ik.zip + fi + + if [ ! -f /plugins/pinyin/plugin-descriptor.properties ]; then + rm -rf /plugins/pinyin/* + wget -O /tmp/pinyin.zip https://release.infinilabs.com/analysis-pinyin/stable/elasticsearch-analysis-pinyin-9.1.4.zip + unzip -q /tmp/pinyin.zip -d /plugins/pinyin + rm /tmp/pinyin.zip + fi + + chown -R 1000:1000 /plugins + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 250m + memory: 256Mi + volumeMounts: + - name: plugins-volume + mountPath: /plugins + containers: + - name: elasticsearch + image: docker.elastic.co/elasticsearch/elasticsearch:9.1.4 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 9200 + - name: transport + containerPort: 9300 + env: + - name: discovery.type + value: single-node + - name: xpack.security.enabled + value: "true" + - name: xpack.security.http.ssl.enabled + value: "false" + - name: ELASTIC_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: ELASTICSEARCH_PASSWORD + - name: ES_JAVA_OPTS + value: "-Xms512m -Xmx512m" + startupProbe: + tcpSocket: + port: http + failureThreshold: 60 + periodSeconds: 10 + readinessProbe: + tcpSocket: + port: http + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: http + periodSeconds: 30 + resources: + requests: + cpu: 100m + memory: 1Gi + limits: + cpu: 1000m + memory: 2Gi + volumeMounts: + - name: elasticsearch-data + mountPath: /usr/share/elasticsearch/data + - name: plugins-volume + mountPath: /usr/share/elasticsearch/plugins + volumes: + - name: plugins-volume + emptyDir: {} + volumeClaimTemplates: + - metadata: + name: elasticsearch-data + labels: + app: elasticsearch + app.kubernetes.io/part-of: ircs + environment: prod + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 5Gi + diff --git a/ircs-prod/core/manifests/frontend-bff.yaml b/ircs-prod/core/manifests/frontend-bff.yaml new file mode 100644 index 0000000..ed72308 --- /dev/null +++ b/ircs-prod/core/manifests/frontend-bff.yaml @@ -0,0 +1,233 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-portal-bff + namespace: ircs-prod + labels: + app: ircs-portal-bff + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-portal-bff + template: + metadata: + labels: + app: ircs-portal-bff + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-portal-bff@sha256:713932a12c577f2dcb910d85f96a5f1c7489542d6cda8a2089efceb3195918d1 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-portal-bff + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: APP_IDENTITY_JWT_SECRET + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: APP_IDENTITY_JWT_SECRET + optional: true + - name: APP_BFF_AUDIT_ENABLED + value: "true" + - name: IRCS_OUTBOUND_CIRCUIT_PORTAL_BFF_PROXY_ENABLED + value: "true" + - name: IRCS_OUTBOUND_CIRCUIT_PORTAL_BFF_PROXY_FAILURE_THRESHOLD + value: "5" + - name: IRCS_OUTBOUND_CIRCUIT_PORTAL_BFF_PROXY_OPEN_DURATION_MS + value: "30000" + - name: IRCS_OUTBOUND_CIRCUIT_PORTAL_BFF_PROXY_HALF_OPEN_MAX_CALLS + value: "1" + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 20m + memory: 128Mi + limits: + cpu: 250m + memory: 384Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-portal-bff + namespace: ircs-prod + labels: + app: ircs-portal-bff + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-portal-bff + ports: + - name: http + port: 8080 + targetPort: http +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-admin-bff + namespace: ircs-prod + labels: + app: ircs-admin-bff + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-admin-bff + template: + metadata: + labels: + app: ircs-admin-bff + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-admin-bff@sha256:e0314abeba097d5f2a25809bf4c7691cdb720b524841e94c522a3f7270baf899 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-admin-bff + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: APP_IDENTITY_JWT_SECRET + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: APP_IDENTITY_JWT_SECRET + optional: true + - name: APP_BFF_AUDIT_ENABLED + value: "true" + - name: APP_BFF_SERVICE_ID + value: admin-bff + - name: APP_BFF_OPS_SERVICE_TOKEN + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: INTERNAL_CREDENTIAL_TOKEN + - name: APP_BFF_OPS_SERVICE_SCOPES + value: ops:read ops:run + - name: IRCS_OUTBOUND_CIRCUIT_ADMIN_BFF_PROXY_ENABLED + value: "true" + - name: IRCS_OUTBOUND_CIRCUIT_ADMIN_BFF_PROXY_FAILURE_THRESHOLD + value: "5" + - name: IRCS_OUTBOUND_CIRCUIT_ADMIN_BFF_PROXY_OPEN_DURATION_MS + value: "30000" + - name: IRCS_OUTBOUND_CIRCUIT_ADMIN_BFF_PROXY_HALF_OPEN_MAX_CALLS + value: "1" + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 20m + memory: 128Mi + limits: + cpu: 250m + memory: 384Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-admin-bff + namespace: ircs-prod + labels: + app: ircs-admin-bff + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-admin-bff + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/frontend-portal-admin.yaml b/ircs-prod/core/manifests/frontend-portal-admin.yaml new file mode 100644 index 0000000..f033802 --- /dev/null +++ b/ircs-prod/core/manifests/frontend-portal-admin.yaml @@ -0,0 +1,468 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: ircs-frontend-gateway-nginx + namespace: ircs-prod + labels: + app.kubernetes.io/part-of: ircs + environment: prod +data: + default.conf: | + upstream portal_frontend { + server ircs-portal-frontend.ircs-prod.svc.cluster.local:3000; + } + + upstream admin_frontend { + server ircs-admin-frontend.ircs-prod.svc.cluster.local:80; + } + + upstream portal_bff { + server ircs-portal-bff.ircs-prod.svc.cluster.local:8080; + } + + upstream admin_bff { + server ircs-admin-bff.ircs-prod.svc.cluster.local:8080; + } + + server { + listen 80; + server_name _; + client_max_body_size 50m; + + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Connection ""; + proxy_buffering off; + proxy_cache off; + proxy_read_timeout 3600s; + proxy_send_timeout 3600s; + location = /gateway-health { + access_log off; + return 204; + } + + location ^~ /api/backend { + proxy_pass http://portal_bff; + } + + location ^~ /api/backend/api/portal/auth { + proxy_pass http://portal_bff; + } + + location ^~ /api/backend/api/portal/profile { + proxy_pass http://portal_bff; + } + + location ^~ /api/backend/api/portal/interaction { + proxy_pass http://portal_bff; + } + + location ^~ /api/backend/api/portal/feedback { + proxy_pass http://portal_bff; + } + + location ^~ /api/backend/api/portal/search { + proxy_pass http://portal_bff; + } + + location ^~ /api/backend/api/portal { + proxy_pass http://portal_bff; + } + + location ^~ /api/portal/auth { + proxy_pass http://portal_bff; + } + + location ^~ /api/portal/profile { + proxy_pass http://portal_bff; + } + + location ^~ /api/portal/interaction { + proxy_pass http://portal_bff; + } + + location ^~ /api/portal/feedback { + proxy_pass http://portal_bff; + } + + location ^~ /api/portal/search { + proxy_pass http://portal_bff; + } + + location ^~ /api/portal { + proxy_pass http://portal_bff; + } + + location ^~ /media { + proxy_pass http://portal_bff; + } + + location / { + proxy_pass http://portal_frontend; + } + } + + server { + listen 8080; + server_name _; + client_max_body_size 50m; + + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Connection ""; + proxy_buffering off; + proxy_cache off; + proxy_read_timeout 3600s; + proxy_send_timeout 3600s; + location = /gateway-health { + access_log off; + return 204; + } + + location ^~ /api/v1 { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/auth { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/members { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/dashboard { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/ops { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/raw-videos { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/unified-videos { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/playlists { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/cover-images { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/collection-tasks { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/catalog { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/standard- { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/raw- { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/data-sources { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/configs { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/common { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/credentials { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/magnet-providers { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/magnets { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/scraper/manual { + proxy_pass http://admin_bff; + } + + location ^~ /api/v1/messages { + proxy_pass http://admin_bff; + } + + location ^~ /media { + proxy_pass http://admin_bff; + } + + location / { + proxy_pass http://admin_frontend; + } + } +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-portal-frontend + namespace: ircs-prod + labels: + app: ircs-portal-frontend + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-portal-frontend + ports: + - name: http + protocol: TCP + port: 3000 + targetPort: http +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-admin-frontend + namespace: ircs-prod + labels: + app: ircs-admin-frontend + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-admin-frontend + ports: + - name: http + protocol: TCP + port: 80 + targetPort: http +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-frontend-gateway + namespace: ircs-prod + labels: + app: ircs-frontend-gateway + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-frontend-gateway + ports: + - name: portal + protocol: TCP + port: 80 + targetPort: portal + - name: admin + protocol: TCP + port: 8080 + targetPort: admin +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-portal-frontend + namespace: ircs-prod + labels: + app: ircs-portal-frontend + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-portal-frontend + template: + metadata: + labels: + app: ircs-portal-frontend + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + ircs.prodigalgal.com/config-version: "bff-20260606-1" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: huawai + image: harbor.mnnu.eu.org/ircs/huawai@sha256:a411c3498cd2871093953b570616a6e89b3f0d1621308e175692dffd109b2751 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 3000 + env: + - name: BACKEND_URL + value: http://ircs-frontend-gateway.ircs-prod.svc.cluster.local:80 + resources: + requests: + cpu: 25m + memory: 192Mi + limits: + cpu: 250m + memory: 512Mi + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 3 + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 30 + periodSeconds: 20 + timeoutSeconds: 3 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-admin-frontend + namespace: ircs-prod + labels: + app: ircs-admin-frontend + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-admin-frontend + template: + metadata: + labels: + app: ircs-admin-frontend + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: ircs-admin-frontend + image: harbor.mnnu.eu.org/ircs/ircs-frontend@sha256:132b7d3bb073734ab8072769521e94885b25f8e9e319253e7c1c433d87c91302 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 80 + resources: + requests: + cpu: 10m + memory: 32Mi + limits: + cpu: 100m + memory: 128Mi + readinessProbe: + httpGet: + path: /login + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 3 + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 20 + periodSeconds: 20 + timeoutSeconds: 3 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-frontend-gateway + namespace: ircs-prod + labels: + app: ircs-frontend-gateway + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-frontend-gateway + template: + metadata: + labels: + app: ircs-frontend-gateway + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + ircs.prodigalgal.com/config-version: "bff-20260606-1" + spec: + containers: + - name: nginx + image: nginx:1.25-alpine + imagePullPolicy: IfNotPresent + ports: + - name: portal + containerPort: 80 + - name: admin + containerPort: 8080 + resources: + requests: + cpu: 10m + memory: 32Mi + limits: + cpu: 100m + memory: 128Mi + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/conf.d + readOnly: true + readinessProbe: + httpGet: + path: /gateway-health + port: portal + initialDelaySeconds: 3 + periodSeconds: 10 + timeoutSeconds: 3 + livenessProbe: + httpGet: + path: /gateway-health + port: portal + initialDelaySeconds: 15 + periodSeconds: 20 + timeoutSeconds: 3 + volumes: + - name: nginx-config + configMap: + name: ircs-frontend-gateway-nginx + diff --git a/ircs-prod/core/manifests/identity-service.yaml b/ircs-prod/core/manifests/identity-service.yaml new file mode 100644 index 0000000..ddd6125 --- /dev/null +++ b/ircs-prod/core/manifests/identity-service.yaml @@ -0,0 +1,149 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-identity-service + namespace: ircs-prod + labels: + app: ircs-identity-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-identity-service + template: + metadata: + labels: + app: ircs-identity-service + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-identity-service@sha256:adda80c8a9c0986a465da376eb527096e3c8ed0cb60fc914cf0df3968533ccb0 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-identity-service + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: APP_IDENTITY_JWT_SECRET + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: APP_IDENTITY_JWT_SECRET + optional: true + - name: SECURITY_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: ADMIN_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: APP_MAIL_ENABLED + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: APP_MAIL_ENABLED + - name: APP_IDENTITY_EMAIL_VERIFY_ENABLED + value: "false" + - name: APP_IDENTITY_CONFIG_LISTENER_ENABLED + value: "true" + - name: APP_IDENTITY_STORAGE_SERVICE_ID + value: identity-service + - name: APP_IDENTITY_STORAGE_SERVICE_TOKEN + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: INTERNAL_CREDENTIAL_TOKEN + - name: APP_IDENTITY_STORAGE_SERVICE_SCOPES + value: storage:avatar + - name: IRCS_OUTBOUND_CIRCUIT_IDENTITY_AVATAR_STORAGE_ENABLED + value: "true" + - name: IRCS_OUTBOUND_CIRCUIT_IDENTITY_AVATAR_STORAGE_FAILURE_THRESHOLD + value: "5" + - name: IRCS_OUTBOUND_CIRCUIT_IDENTITY_AVATAR_STORAGE_OPEN_DURATION_MS + value: "30000" + - name: IRCS_OUTBOUND_CIRCUIT_IDENTITY_AVATAR_STORAGE_HALF_OPEN_MAX_CALLS + value: "1" + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-identity-service + namespace: ircs-prod + labels: + app: ircs-identity-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-identity-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/ingestion-worker.yaml b/ircs-prod/core/manifests/ingestion-worker.yaml new file mode 100644 index 0000000..6fa367d --- /dev/null +++ b/ircs-prod/core/manifests/ingestion-worker.yaml @@ -0,0 +1,96 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-ingestion-worker + namespace: ircs-prod + labels: + app: ircs-ingestion-worker + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-ingestion-worker + template: + metadata: + labels: + app: ircs-ingestion-worker + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-ingestion-worker@sha256:7429f763a0c07e767018ea473836ff16546f4d91085f0e5c6c28af31f25093fc + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-ingestion-worker + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_INGESTION_LISTENER_ENABLED + value: "true" + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi + diff --git a/ircs-prod/core/manifests/interaction-service.yaml b/ircs-prod/core/manifests/interaction-service.yaml new file mode 100644 index 0000000..5e2d622 --- /dev/null +++ b/ircs-prod/core/manifests/interaction-service.yaml @@ -0,0 +1,121 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-interaction-service + namespace: ircs-prod + labels: + app: ircs-interaction-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-interaction-service + template: + metadata: + labels: + app: ircs-interaction-service + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-interaction-service@sha256:540f6edb8357fb30208a5fa9de957e25506dca9c49a66ff16833438d6eab3ac7 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-interaction-service + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_STORAGE_R2_PUBLIC_DOMAIN + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: R2_PUBLIC_DOMAIN + - name: APP_INTERACTION_LISTENER_ENABLED + value: "true" + - name: APP_INTERACTION_CONFIG_LISTENER_ENABLED + value: "true" + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-interaction-service + namespace: ircs-prod + labels: + app: ircs-interaction-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-interaction-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/magnet-service.yaml b/ircs-prod/core/manifests/magnet-service.yaml new file mode 100644 index 0000000..e86b2c7 --- /dev/null +++ b/ircs-prod/core/manifests/magnet-service.yaml @@ -0,0 +1,106 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-magnet-service + namespace: ircs-prod + labels: + app: ircs-magnet-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-magnet-service + template: + metadata: + labels: + app: ircs-magnet-service + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-magnet-service@sha256:190b98486dd4fd662d9433e1032a41c768d6b4cc4c11aeae91f1f7142ebf09b5 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-magnet-service + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_MAGNET_CACHE_ENABLED + value: "true" + - name: APP_MAGNET_CACHE_PROVIDER_TTL + value: PT5M + - name: APP_MAGNET_CACHE_APPROVED_LINKS_TTL + value: PT60S + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-magnet-service + namespace: ircs-prod + labels: + app: ircs-magnet-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-magnet-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/metadata-worker.yaml b/ircs-prod/core/manifests/metadata-worker.yaml new file mode 100644 index 0000000..8f09c78 --- /dev/null +++ b/ircs-prod/core/manifests/metadata-worker.yaml @@ -0,0 +1,116 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-metadata-worker + namespace: ircs-prod + labels: + app: ircs-metadata-worker + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-metadata-worker + template: + metadata: + labels: + app: ircs-metadata-worker + app.kubernetes.io/part-of: ircs + environment: prod + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-metadata-worker@sha256:556d9e0e90c3686974d42f9844d46c46684ce9e8c44cea8c3af653cbebdde5db + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-metadata-worker + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_METADATA_LISTENER_ENABLED + value: "true" + - name: APP_METADATA_CONFIG_LISTENER_ENABLED + value: "true" + - name: APP_METADATA_DISPATCHER_ENABLED + value: "true" + - name: APP_METADATA_DOUBAN_ENABLED + value: "false" + - name: APP_METADATA_TMDB_ENABLED + value: "false" + - name: APP_METADATA_TMDB_WORKER_ENABLED + value: "true" + - name: APP_METADATA_CREDENTIAL_SERVICE_BASE_URL + value: http://ircs-credential-service.ircs-prod.svc.cluster.local:8080 + - name: APP_METADATA_CREDENTIAL_SERVICE_TOKEN + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: SERVICE_CREDENTIAL_TOKEN + - name: APP_METADATA_RT_ENABLED + value: "false" + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 60 + periodSeconds: 5 + timeoutSeconds: 3 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + timeoutSeconds: 3 + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + timeoutSeconds: 3 + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi + diff --git a/ircs-prod/core/manifests/migrator-job.yaml b/ircs-prod/core/manifests/migrator-job.yaml new file mode 100644 index 0000000..c961a44 --- /dev/null +++ b/ircs-prod/core/manifests/migrator-job.yaml @@ -0,0 +1,53 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: ircs-migrator + namespace: ircs-prod + labels: + app: ircs-migrator + app.kubernetes.io/part-of: ircs + environment: prod +spec: + backoffLimit: 0 + ttlSecondsAfterFinished: 300 + template: + metadata: + labels: + app: ircs-migrator + app.kubernetes.io/part-of: ircs + environment: prod + spec: + restartPolicy: Never + imagePullSecrets: + - name: harbor-secret + containers: + - name: migrator + image: harbor.mnnu.eu.org/ircs/ircs-migrator@sha256:64223fa99f7c2793b0145cc539bafa4b0c70fa3cc0af0e9059a2fed3bf7a2437 + imagePullPolicy: IfNotPresent + env: + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi + diff --git a/ircs-prod/core/manifests/normalization-worker.yaml b/ircs-prod/core/manifests/normalization-worker.yaml new file mode 100644 index 0000000..6bc78d0 --- /dev/null +++ b/ircs-prod/core/manifests/normalization-worker.yaml @@ -0,0 +1,127 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-normalization-worker + namespace: ircs-prod + labels: + app: ircs-normalization-worker + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-normalization-worker + template: + metadata: + labels: + app: ircs-normalization-worker + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-normalization-worker@sha256:399ca4e645c20a8fef850499a5b1c4223fc6308ca36598f778641e1efbb8eaf8 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-normalization-worker + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_NORMALIZATION_LISTENER_ENABLED + value: "true" + - name: APP_NORMALIZATION_CONFIG_LISTENER_ENABLED + value: "true" + - name: APP_NORMALIZATION_INTERNAL_ACCESS_REQUIRE_TOKEN + value: "false" + - name: APP_NORMALIZATION_WATCHDOG_ENABLED + value: "false" + - name: APP_NORMALIZATION_WATCHDOG_BATCH_SIZE + value: "25" + - name: APP_NORMALIZATION_HANLP_PREWARM_ENABLED + value: "true" + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 120 + periodSeconds: 5 + timeoutSeconds: 3 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + timeoutSeconds: 3 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + timeoutSeconds: 3 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-normalization-worker + namespace: ircs-prod + labels: + app: ircs-normalization-worker + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-normalization-worker + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/notification-worker.yaml b/ircs-prod/core/manifests/notification-worker.yaml new file mode 100644 index 0000000..42f1120 --- /dev/null +++ b/ircs-prod/core/manifests/notification-worker.yaml @@ -0,0 +1,138 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-notification-worker + namespace: ircs-prod + labels: + app: ircs-notification-worker + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-notification-worker + template: + metadata: + labels: + app: ircs-notification-worker + app.kubernetes.io/part-of: ircs + environment: prod + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-notification-worker@sha256:c0234ec40b13b3a24925ec2bcfb5b6298622335f44284003d12f09199de3fdd3 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-notification-worker + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_MAIL_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: MAIL_HOST + - name: APP_MAIL_PORT + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: MAIL_PORT + - name: APP_MAIL_FROM + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: MAIL_FROM + - name: APP_MAIL_ENABLED + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: APP_MAIL_ENABLED + - name: APP_MAIL_SEND_HISTORY_CLEANUP_ENABLED + value: "false" + - name: APP_MAIL_SEND_HISTORY_CLEANUP_DRY_RUN + value: "true" + - name: APP_MAIL_SEND_HISTORY_CLEANUP_EXECUTE_ENABLED + value: "false" + - name: APP_MAIL_SEND_HISTORY_CLEANUP_RATE_LIMIT_DELAY_MS + value: "0" + - name: APP_NOTIFICATION_CONFIG_LISTENER_ENABLED + value: "true" + - name: APP_WORKER_AUDIT_ENABLED + value: "true" + - name: APP_WORKER_AUDIT_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: APP_WORKER_AUDIT_USERNAME + value: postgres + - name: APP_WORKER_AUDIT_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: APP_WORKER_AUDIT_SOURCE + value: ircs-notification-worker + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi + diff --git a/ircs-prod/core/manifests/observability-monitoring.yaml b/ircs-prod/core/manifests/observability-monitoring.yaml new file mode 100644 index 0000000..2a1a5a4 --- /dev/null +++ b/ircs-prod/core/manifests/observability-monitoring.yaml @@ -0,0 +1,70 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: ircs-prod-service-monitor + namespace: ircs-prod + labels: + app.kubernetes.io/part-of: ircs + environment: prod + release: prometheus-stack +spec: + namespaceSelector: + matchNames: + - ircs-prod + selector: + matchExpressions: + - key: app + operator: In + values: + - ircs-admin-bff + - ircs-catalog-service + - ircs-config-service + - ircs-content-service + - ircs-credential-service + - ircs-identity-service + - ircs-interaction-service + - ircs-magnet-service + - ircs-normalization-worker + - ircs-ops-service + - ircs-portal-bff + - ircs-portal-service + - ircs-scraper-service + - ircs-search-service + - ircs-storage-service + - ircs-task-service + endpoints: + - port: http + path: /actuator/prometheus + interval: 30s + scrapeTimeout: 10s + honorLabels: true +--- +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: ircs-prod-worker-pod-monitor + namespace: ircs-prod + labels: + app.kubernetes.io/part-of: ircs + environment: prod + release: prometheus-stack +spec: + namespaceSelector: + matchNames: + - ircs-prod + selector: + matchExpressions: + - key: app + operator: In + values: + - ircs-aggregation-worker + - ircs-ingestion-worker + - ircs-metadata-worker + - ircs-notification-worker + podMetricsEndpoints: + - port: http + path: /actuator/prometheus + interval: 30s + scrapeTimeout: 10s + honorLabels: true + diff --git a/ircs-prod/core/manifests/ops-service.yaml b/ircs-prod/core/manifests/ops-service.yaml new file mode 100644 index 0000000..6e5eda0 --- /dev/null +++ b/ircs-prod/core/manifests/ops-service.yaml @@ -0,0 +1,141 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-ops-service + namespace: ircs-prod + labels: + app: ircs-ops-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-ops-service + template: + metadata: + labels: + app: ircs-ops-service + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-ops-service@sha256:ec5a8ec36286e45fa4d85e07b861c7e349dd914017e1b0a03639833ab20b686f + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-ops-service + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: APP_OPS_CONFIG_LISTENER_ENABLED + value: "true" + - name: APP_OPS_INTERNAL_ACCESS_REQUIRE_TOKEN + value: "true" + - name: APP_OPS_INTERNAL_ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: INTERNAL_CREDENTIAL_TOKEN + - name: APP_OPS_INTERNAL_ACCESS_READ_SCOPE + value: ops:read + - name: APP_OPS_INTERNAL_ACCESS_RUN_SCOPE + value: ops:run + - name: OPS_MAINTENANCE_REINDEX_DEV_LIMIT + value: "5" + - name: APP_OPS_MAINTENANCE_SCHEDULER_ENABLED + value: "false" + - name: APP_OPS_MAINTENANCE_SCHEDULER_DRY_RUN + value: "true" + - name: APP_OPS_MAINTENANCE_SCHEDULER_EXECUTE_ENABLED + value: "true" + - name: APP_OPS_MAINTENANCE_SCHEDULER_TASKS + value: search-reindex-unified + - name: APP_OPS_SEARCH_SERVICE_BASE_URL + value: http://ircs-search-service.ircs-prod.svc.cluster.local:8080 + - name: APP_OPS_NORMALIZATION_WORKER_BASE_URL + value: http://ircs-normalization-worker.ircs-prod.svc.cluster.local:8080 + - name: APP_OPS_NORMALIZATION_LLM_REQUEST_TIMEOUT + value: 5m + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-ops-service + namespace: ircs-prod + labels: + app: ircs-ops-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-ops-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/portal-service.yaml b/ircs-prod/core/manifests/portal-service.yaml new file mode 100644 index 0000000..1044465 --- /dev/null +++ b/ircs-prod/core/manifests/portal-service.yaml @@ -0,0 +1,119 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-portal-service + namespace: ircs-prod + labels: + app: ircs-portal-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-portal-service + template: + metadata: + labels: + app: ircs-portal-service + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-portal-service@sha256:13273b98a366bf5690fb372316248d91711f41afb4906de0cf8e737ce76fc59c + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-portal-service + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_STORAGE_R2_PUBLIC_DOMAIN + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: R2_PUBLIC_DOMAIN + - name: APP_PORTAL_CONFIG_LISTENER_ENABLED + value: "true" + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 20m + memory: 128Mi + limits: + cpu: 200m + memory: 384Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-portal-service + namespace: ircs-prod + labels: + app: ircs-portal-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-portal-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/postgres.yaml b/ircs-prod/core/manifests/postgres.yaml new file mode 100644 index 0000000..2a01160 --- /dev/null +++ b/ircs-prod/core/manifests/postgres.yaml @@ -0,0 +1,95 @@ +apiVersion: v1 +kind: Service +metadata: + name: postgres-svc + namespace: ircs-prod + labels: + app: postgres + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: postgres + ports: + - name: postgres + port: 5432 + targetPort: postgres +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: postgres + namespace: ircs-prod + labels: + app: postgres + app.kubernetes.io/part-of: ircs + environment: prod +spec: + serviceName: postgres-svc + replicas: 1 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + app.kubernetes.io/part-of: ircs + environment: prod + spec: + containers: + - name: postgres + image: postgres:18-alpine + imagePullPolicy: IfNotPresent + ports: + - name: postgres + containerPort: 5432 + env: + - name: POSTGRES_DB + value: ircs + - name: POSTGRES_USER + value: postgres + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + startupProbe: + exec: + command: ["pg_isready", "-U", "postgres", "-d", "ircs"] + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + exec: + command: ["pg_isready", "-U", "postgres", "-d", "ircs"] + periodSeconds: 10 + livenessProbe: + exec: + command: ["pg_isready", "-U", "postgres", "-d", "ircs"] + periodSeconds: 30 + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + volumeMounts: + - name: postgres-data + mountPath: /var/lib/postgresql/data + volumeClaimTemplates: + - metadata: + name: postgres-data + labels: + app: postgres + app.kubernetes.io/part-of: ircs + environment: prod + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 2Gi + diff --git a/ircs-prod/core/manifests/rabbitmq.yaml b/ircs-prod/core/manifests/rabbitmq.yaml new file mode 100644 index 0000000..a4f88d8 --- /dev/null +++ b/ircs-prod/core/manifests/rabbitmq.yaml @@ -0,0 +1,99 @@ +apiVersion: v1 +kind: Service +metadata: + name: rabbitmq-svc + namespace: ircs-prod + labels: + app: rabbitmq + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: rabbitmq + ports: + - name: amqp + port: 5672 + targetPort: amqp + - name: management + port: 15672 + targetPort: management +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: rabbitmq + namespace: ircs-prod + labels: + app: rabbitmq + app.kubernetes.io/part-of: ircs + environment: prod +spec: + serviceName: rabbitmq-svc + replicas: 1 + selector: + matchLabels: + app: rabbitmq + template: + metadata: + labels: + app: rabbitmq + app.kubernetes.io/part-of: ircs + environment: prod + spec: + containers: + - name: rabbitmq + image: rabbitmq:4.1.8-management + imagePullPolicy: IfNotPresent + ports: + - name: amqp + containerPort: 5672 + - name: management + containerPort: 15672 + env: + - name: RABBITMQ_DEFAULT_USER + value: admin + - name: RABBITMQ_DEFAULT_PASS + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + startupProbe: + exec: + command: ["rabbitmq-diagnostics", "-q", "ping"] + failureThreshold: 30 + periodSeconds: 10 + timeoutSeconds: 10 + readinessProbe: + exec: + command: ["rabbitmq-diagnostics", "-q", "ping"] + periodSeconds: 10 + timeoutSeconds: 10 + livenessProbe: + exec: + command: ["rabbitmq-diagnostics", "-q", "ping"] + periodSeconds: 30 + timeoutSeconds: 10 + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 768Mi + volumeMounts: + - name: rabbitmq-data + mountPath: /var/lib/rabbitmq + volumeClaimTemplates: + - metadata: + name: rabbitmq-data + labels: + app: rabbitmq + app.kubernetes.io/part-of: ircs + environment: prod + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi + diff --git a/ircs-prod/core/manifests/scraper-service.yaml b/ircs-prod/core/manifests/scraper-service.yaml new file mode 100644 index 0000000..3ff879e --- /dev/null +++ b/ircs-prod/core/manifests/scraper-service.yaml @@ -0,0 +1,133 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-scraper-service + namespace: ircs-prod + labels: + app: ircs-scraper-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-scraper-service + template: + metadata: + labels: + app: ircs-scraper-service + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-scraper-service@sha256:57d7a63db890dd5be03d3981f428f23a56c46ea367ddcdcebc9d018e873ce457 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-scraper-service + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: APP_SCRAPER_DIRECT_ITEMS_ENABLED + value: "true" + - name: APP_SCRAPER_TASK_QUEUE_LISTENER_ENABLED + value: "true" + - name: APP_SCRAPER_TASK_QUEUE_RETRY_MAX_RETRIES + value: "3" + - name: IRCS_MESSAGING_RABBIT_TOPOLOGY_RETRY_DELAY_MS + value: "30000" + - name: APP_SCRAPER_TREND_SYNC_MAX_PROVIDER_ITEMS + value: "10" + - name: APP_SCRAPER_TREND_DISCOVERY_MAX_DATA_SOURCES + value: "1" + - name: APP_SCRAPER_CREDENTIAL_SERVICE_BASE_URL + value: http://ircs-credential-service.ircs-prod.svc.cluster.local:8080 + - name: APP_SCRAPER_CREDENTIAL_SERVICE_TOKEN + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: SERVICE_CREDENTIAL_TOKEN + - name: APP_SCRAPER_TASK_SERVICE_BASE_URL + value: http://ircs-task-service.ircs-prod.svc.cluster.local:8080 + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-scraper-service + namespace: ircs-prod + labels: + app: ircs-scraper-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-scraper-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/search-service.yaml b/ircs-prod/core/manifests/search-service.yaml new file mode 100644 index 0000000..4c1d191 --- /dev/null +++ b/ircs-prod/core/manifests/search-service.yaml @@ -0,0 +1,149 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-search-service + namespace: ircs-prod + labels: + app: ircs-search-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-search-service + template: + metadata: + labels: + app: ircs-search-service + app.kubernetes.io/part-of: ircs + environment: prod + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-search-service@sha256:b935a800abe3c92320408f3410c1883f6367736117e92dd574edced6bb3434e0 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-search-service + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: SPRING_ELASTICSEARCH_URIS + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: ELASTICSEARCH_URIS + - name: SPRING_ELASTICSEARCH_USERNAME + value: elastic + - name: SPRING_ELASTICSEARCH_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: ELASTICSEARCH_PASSWORD + - name: APP_STORAGE_R2_PUBLIC_DOMAIN + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: R2_PUBLIC_DOMAIN + - name: APP_SEARCH_LISTENER_ENABLED + value: "true" + - name: APP_SEARCH_CONFIG_LISTENER_ENABLED + value: "true" + - name: APP_SEARCH_CACHE_ENABLED + value: "true" + - name: APP_SEARCH_CACHE_PORTAL_SUGGEST_TTL + value: PT60S + - name: APP_SEARCH_CACHE_PORTAL_RECOMMEND_TTL + value: PT60S + - name: APP_SEARCH_OUTBOX_RELAY_ENABLED + value: "true" + - name: APP_SEARCH_OUTBOX_RELAY_BATCH_SIZE + value: "50" + - name: APP_SEARCH_OUTBOX_RELAY_INITIAL_DELAY_MS + value: "10000" + - name: APP_SEARCH_OUTBOX_RELAY_FIXED_DELAY_MS + value: "2000" + - name: APP_SEARCH_OUTBOX_RELAY_WORKER_ID + valueFrom: + fieldRef: + fieldPath: metadata.name + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-search-service + namespace: ircs-prod + labels: + app: ircs-search-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-search-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/storage-service.yaml b/ircs-prod/core/manifests/storage-service.yaml new file mode 100644 index 0000000..a2c2e63 --- /dev/null +++ b/ircs-prod/core/manifests/storage-service.yaml @@ -0,0 +1,147 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-storage-service + namespace: ircs-prod + labels: + app: ircs-storage-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-storage-service + template: + metadata: + labels: + app: ircs-storage-service + app.kubernetes.io/part-of: ircs + environment: prod + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-storage-service@sha256:d84e61ee19b84a77a0cd1c608eb51cf673b0d8fc47571366742542ff5a00b88c + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-storage-service + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_STORAGE_BASE_PATH + value: /app/storage + - name: APP_STORAGE_LISTENER_ENABLED + value: "true" + - name: APP_STORAGE_CONFIG_LISTENER_ENABLED + value: "true" + - name: APP_STORAGE_INTERNAL_ACCESS_REQUIRE_TOKEN + value: "true" + - name: APP_STORAGE_INTERNAL_ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: INTERNAL_CREDENTIAL_TOKEN + - name: APP_STORAGE_INTERNAL_ACCESS_AVATAR_SCOPE + value: storage:avatar + - name: APP_STORAGE_R2_ENABLED + value: "false" + - name: APP_STORAGE_IMAGE_MAX_UPLOAD_BYTES + value: "10485760" + - name: APP_STORAGE_R2_WATCHDOG_ENABLED + value: "false" + - name: APP_STORAGE_R2_BUCKET_NAME + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: R2_BUCKET_NAME + - name: APP_STORAGE_R2_PUBLIC_DOMAIN + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: R2_PUBLIC_DOMAIN + volumeMounts: + - name: storage-volume + mountPath: /app/storage + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi + volumes: + - name: storage-volume + emptyDir: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-storage-service + namespace: ircs-prod + labels: + app: ircs-storage-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-storage-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/task-service.yaml b/ircs-prod/core/manifests/task-service.yaml new file mode 100644 index 0000000..b7af617 --- /dev/null +++ b/ircs-prod/core/manifests/task-service.yaml @@ -0,0 +1,152 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ircs-task-service + namespace: ircs-prod + labels: + app: ircs-task-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: ircs-task-service + template: + metadata: + labels: + app: ircs-task-service + app.kubernetes.io/part-of: ircs + environment: prod + annotations: + ircs.prodigalgal.com/no-public-route: "true" + spec: + imagePullSecrets: + - name: harbor-secret + containers: + - name: app + image: harbor.mnnu.eu.org/ircs/ircs-task-service@sha256:74482cc394083003bb3dc52d9290e3473d3f17b1e5bad01ad91123facf31709f + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + envFrom: + - configMapRef: + name: ircs-prod-app-config + env: + - name: SPRING_APPLICATION_NAME + value: ircs-task-service + - name: SPRING_DATASOURCE_URL + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: DB_URL + - name: SPRING_DATASOURCE_USERNAME + value: postgres + - name: SPRING_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: DB_PASSWORD + - name: SPRING_RABBITMQ_HOST + valueFrom: + configMapKeyRef: + name: ircs-prod-app-config + key: RABBITMQ_HOST + - name: SPRING_RABBITMQ_USERNAME + value: admin + - name: SPRING_RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + name: ircs-prod-secrets + key: RABBITMQ_PASSWORD + - name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE + value: "2" + - name: SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE + value: "0" + - name: SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT + value: "30000" + - name: APP_TASK_DEFAULT_SEED_ENABLED + value: "true" + - name: APP_TASK_SCHEDULER_ENABLED + value: "false" + - name: APP_TASK_WATCHDOG_ENABLED + value: "false" + - name: APP_TASK_RUNNER_QUEUE_CAPACITY + value: "500" + - name: APP_TASK_QUEUE_ENABLED + value: "true" + - name: APP_TASK_QUEUE_LISTENER_ENABLED + value: "true" + - name: APP_TASK_QUEUE_INITIAL_PAGE_WINDOW + value: "1" + - name: APP_TASK_QUEUE_MAX_PAGES_PER_RUN + value: "1" + - name: APP_TASK_QUEUE_RETRY_MAX_RETRIES + value: "3" + - name: IRCS_MESSAGING_RABBIT_TOPOLOGY_RETRY_DELAY_MS + value: "30000" + - name: APP_TASK_SNAPSHOT_TTL + value: "PT24H" + - name: APP_TASK_SNAPSHOT_FLUSH_ENABLED + value: "true" + - name: APP_TASK_SNAPSHOT_FLUSH_DELAY_MS + value: "30000" + - name: APP_TASK_SNAPSHOT_FLUSH_BATCH_SIZE + value: "100" + - name: APP_TASK_TREND_DISCOVERY_MAX_KEYWORDS + value: "3" + - name: APP_TASK_TREND_DISCOVERY_MAX_DATA_SOURCES + value: "1" + - name: IRCS_OUTBOUND_CIRCUIT_TASK_SCRAPER_EXECUTION_ENABLED + value: "true" + - name: IRCS_OUTBOUND_CIRCUIT_TASK_SCRAPER_EXECUTION_FAILURE_THRESHOLD + value: "5" + - name: IRCS_OUTBOUND_CIRCUIT_TASK_SCRAPER_EXECUTION_OPEN_DURATION_MS + value: "30000" + - name: IRCS_OUTBOUND_CIRCUIT_TASK_SCRAPER_EXECUTION_HALF_OPEN_MAX_CALLS + value: "1" + startupProbe: + httpGet: + path: /actuator/health/liveness + port: http + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: http + periodSeconds: 10 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: http + periodSeconds: 30 + resources: + requests: + cpu: 25m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: ircs-task-service + namespace: ircs-prod + labels: + app: ircs-task-service + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: ircs-task-service + ports: + - name: http + port: 8080 + targetPort: http + diff --git a/ircs-prod/core/manifests/valkey.yaml b/ircs-prod/core/manifests/valkey.yaml new file mode 100644 index 0000000..234f68b --- /dev/null +++ b/ircs-prod/core/manifests/valkey.yaml @@ -0,0 +1,77 @@ +apiVersion: v1 +kind: Service +metadata: + name: valkey-svc + namespace: ircs-prod + labels: + app: valkey + app.kubernetes.io/part-of: ircs + environment: prod +spec: + type: ClusterIP + selector: + app: valkey + ports: + - name: valkey + port: 6379 + targetPort: valkey +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: valkey + namespace: ircs-prod + labels: + app: valkey + app.kubernetes.io/part-of: ircs + environment: prod +spec: + replicas: 1 + selector: + matchLabels: + app: valkey + template: + metadata: + labels: + app: valkey + app.kubernetes.io/part-of: ircs + environment: prod + spec: + containers: + - name: valkey + image: valkey/valkey:8-alpine + imagePullPolicy: IfNotPresent + ports: + - name: valkey + containerPort: 6379 + args: + - valkey-server + - --save + - "" + - --appendonly + - "no" + - --maxmemory + - 96mb + - --maxmemory-policy + - allkeys-lru + startupProbe: + exec: + command: ["valkey-cli", "ping"] + failureThreshold: 30 + periodSeconds: 5 + readinessProbe: + exec: + command: ["valkey-cli", "ping"] + periodSeconds: 10 + livenessProbe: + exec: + command: ["valkey-cli", "ping"] + periodSeconds: 30 + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 250m + memory: 256Mi + diff --git a/ircs-prod/edge-cutover/httproutes.yaml b/ircs-prod/edge-cutover/httproutes.yaml new file mode 100644 index 0000000..e2088ed --- /dev/null +++ b/ircs-prod/edge-cutover/httproutes.yaml @@ -0,0 +1,55 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: huawai-route + namespace: ircs-prod + labels: + app.kubernetes.io/part-of: ircs + environment: prod +spec: + hostnames: + - huawai.sophia.fr.eu.org + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: production-gateway + namespace: envoy-gateway-system + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - group: "" + kind: Service + name: ircs-frontend-gateway + port: 80 + weight: 1 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: ircs-route + namespace: ircs-prod + labels: + app.kubernetes.io/part-of: ircs + environment: prod +spec: + hostnames: + - ircs.sophia.fr.eu.org + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: production-gateway + namespace: envoy-gateway-system + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - group: "" + kind: Service + name: ircs-frontend-gateway + port: 8080 + weight: 1 diff --git a/ircs-prod/edge-cutover/kustomization.yaml b/ircs-prod/edge-cutover/kustomization.yaml new file mode 100644 index 0000000..11613f8 --- /dev/null +++ b/ircs-prod/edge-cutover/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - httproutes.yaml + diff --git a/scripts/cutover-httproute.ps1 b/scripts/cutover-httproute.ps1 new file mode 100644 index 0000000..25a9258 --- /dev/null +++ b/scripts/cutover-httproute.ps1 @@ -0,0 +1,26 @@ +param( + [string]$OldNamespace = "ircs-system", + [string]$NewNamespace = "ircs-prod", + [string]$OldApplication = "ircs-app", + [string]$ArgoNamespace = "argocd", + [switch]$Execute +) + +$ErrorActionPreference = "Stop" + +if (-not $Execute) { + Write-Host "Dry run only. Planned actions:" + Write-Host "1. Patch ArgoCD application $OldApplication to disable automated sync." + Write-Host "2. Apply ircs-prod/edge-cutover HTTPRoutes." + Write-Host "3. Delete old $OldNamespace huawai-route and ircs-route to avoid hostname/path conflicts." + Write-Host "4. Wait for new routes to be Accepted and ResolvedRefs." + Write-Host "Add -Execute to perform cutover." + exit 0 +} + +kubectl -n $ArgoNamespace patch application $OldApplication --type merge -p '{"spec":{"syncPolicy":null}}' | Out-Null +kubectl apply -k ircs-prod/edge-cutover | Out-Null +kubectl -n $OldNamespace delete httproute huawai-route ircs-route --ignore-not-found | Out-Null +kubectl -n $NewNamespace wait --for=condition=Accepted httproute/huawai-route --timeout=120s +kubectl -n $NewNamespace wait --for=condition=Accepted httproute/ircs-route --timeout=120s +kubectl -n $NewNamespace get httproute huawai-route ircs-route diff --git a/scripts/migrate-compatible-data.ps1 b/scripts/migrate-compatible-data.ps1 new file mode 100644 index 0000000..a567c4a --- /dev/null +++ b/scripts/migrate-compatible-data.ps1 @@ -0,0 +1,54 @@ +param( + [string]$OldNamespace = "ircs-system", + [string]$NewNamespace = "ircs-prod", + [string]$Database = "ircs", + [switch]$Execute, + [switch]$TruncateTarget +) + +$ErrorActionPreference = "Stop" + +$tables = @( + 'actors', 'collection_tasks', 'cover_images', 'data_sources', 'directors', 'episodes', + 'failed_messages', 'magnet_links', 'magnet_provider_runs', 'magnet_providers', 'magnet_search_jobs', + 'member_favorites', 'member_watch_histories', 'members', 'playlists', 'raw_areas', 'raw_category', + 'raw_genres', 'raw_languages', 'raw_video_unified_video', 'raw_videos', 'request_audit_logs', + 'search_sync_tasks', 'source_domains', 'standard_areas', 'standard_category', 'standard_genre', + 'standard_languages', 'sys_credentials', 'system_configs', 'unified_video_actors', + 'unified_video_directors', 'unified_video_genres', 'unified_video_standard_areas', + 'unified_video_standard_languages', 'unified_videos', 'user_messages', 'video_actors', + 'video_directors', 'video_raw_areas', 'video_raw_genres', 'video_raw_languages', + 'video_resolver_sources' +) + +function Invoke-Postgres($Namespace, $Sql) { + $escapedSql = $Sql.Replace("'", "'\''") + kubectl -n $Namespace exec statefulset/postgres -- sh -lc "PGPASSWORD=\`$POSTGRES_PASSWORD psql -U postgres -d $Database -Atc '$escapedSql'" +} + +Write-Host "Compatible business tables planned for migration: $($tables.Count)" +Write-Host "Excluded tables: databasechangelog, databasechangeloglock, V3 runtime audit/outbox/maintenance derived tables." + +$oldTables = Invoke-Postgres $OldNamespace "select tablename from pg_tables where schemaname='public' order by tablename" +$newTables = Invoke-Postgres $NewNamespace "select tablename from pg_tables where schemaname='public' order by tablename" +$missingOld = $tables | Where-Object { $_ -notin $oldTables } +$missingNew = $tables | Where-Object { $_ -notin $newTables } +if ($missingOld) { throw "Old namespace is missing expected tables: $($missingOld -join ', ')" } +if ($missingNew) { throw "New namespace is missing expected tables. Run ircs-prod core migrator first: $($missingNew -join ', ')" } + +if (-not $Execute) { + Write-Host "Dry run only. Add -Execute to stream data from $OldNamespace to $NewNamespace." + exit 0 +} + +if ($TruncateTarget) { + $quoted = ($tables | ForEach-Object { 'public."' + $_ + '"' }) -join ', ' + Invoke-Postgres $NewNamespace "truncate table $quoted restart identity cascade" | Out-Null +} + +$tableArgs = ($tables | ForEach-Object { "--table=public.$_" }) -join ' ' +$dumpCmd = "PGPASSWORD=\`$POSTGRES_PASSWORD pg_dump -U postgres -d $Database --data-only --column-inserts --disable-triggers $tableArgs" +$loadCmd = "PGPASSWORD=\`$POSTGRES_PASSWORD psql -U postgres -d $Database -v ON_ERROR_STOP=1" + +kubectl -n $OldNamespace exec statefulset/postgres -- sh -lc $dumpCmd | kubectl -n $NewNamespace exec -i statefulset/postgres -- sh -lc $loadCmd +Write-Host "Compatible data migration stream finished." diff --git a/scripts/prepare-prod-secrets.ps1 b/scripts/prepare-prod-secrets.ps1 new file mode 100644 index 0000000..477c4c6 --- /dev/null +++ b/scripts/prepare-prod-secrets.ps1 @@ -0,0 +1,62 @@ +param( + [string]$OldNamespace = "ircs-system", + [string]$NewNamespace = "ircs-prod", + [string]$OldSecret = "ircs-backend-secrets", + [string]$NewSecret = "ircs-prod-secrets", + [string]$OldPullSecret = "harbor-secret", + [string]$NewPullSecret = "harbor-secret" +) + +$ErrorActionPreference = "Stop" + +function New-Base64SecretValue([int]$Bytes = 48) { + $buffer = [byte[]]::new($Bytes) + [System.Security.Cryptography.RandomNumberGenerator]::Fill($buffer) + return [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes([Convert]::ToBase64String($buffer))) +} + +kubectl get namespace $NewNamespace *> $null +if ($LASTEXITCODE -ne 0) { + kubectl create namespace $NewNamespace | Out-Null +} + +$old = kubectl -n $OldNamespace get secret $OldSecret -o json | ConvertFrom-Json +$data = @{} +foreach ($prop in $old.data.PSObject.Properties) { + $data[$prop.Name] = $prop.Value +} + +foreach ($key in @('APP_IDENTITY_JWT_SECRET', 'INTERNAL_CREDENTIAL_TOKEN', 'SERVICE_CREDENTIAL_TOKEN', 'SERVICE_SEARCH_TOKEN')) { + if (-not $data.ContainsKey($key)) { + $data[$key] = New-Base64SecretValue 48 + } +} + +$secret = [ordered]@{ + apiVersion = 'v1' + kind = 'Secret' + metadata = [ordered]@{ + name = $NewSecret + namespace = $NewNamespace + labels = [ordered]@{ + 'app.kubernetes.io/part-of' = 'ircs' + environment = 'prod' + } + } + type = 'Opaque' + data = $data +} + +$secret | ConvertTo-Json -Depth 20 | kubectl apply -f - | Out-Null + +$pull = kubectl -n $OldNamespace get secret $OldPullSecret -o json | ConvertFrom-Json +$pull.metadata.namespace = $NewNamespace +$pull.metadata.name = $NewPullSecret +$pull.metadata.PSObject.Properties.Remove('creationTimestamp') +$pull.metadata.PSObject.Properties.Remove('resourceVersion') +$pull.metadata.PSObject.Properties.Remove('uid') +$pull.metadata.PSObject.Properties.Remove('managedFields') +$pull.metadata.PSObject.Properties.Remove('annotations') +$pull | ConvertTo-Json -Depth 20 | kubectl apply -f - | Out-Null + +Write-Host "Prepared namespace, runtime secret, and image pull secret for $NewNamespace. Secret values were not printed."