diff --git a/clusters/dev/apps/bff-cli/values.yaml b/clusters/dev/apps/bff-cli/values.yaml index 20f16ed..a3102e5 100644 --- a/clusters/dev/apps/bff-cli/values.yaml +++ b/clusters/dev/apps/bff-cli/values.yaml @@ -48,7 +48,6 @@ bff-cli-service: CORE_ZONE_LABEL: "Core" GREEN_ZONE_LABEL: "Greenroom" - # TODO: fill when these services are deployed on OVH AUDIT_TRAIL_SERVICE: "" HPC_SERVICE: "" KG_SERVICE: "" @@ -59,7 +58,6 @@ bff-cli-service: # Guacamole CLI auth CLI_PUBLIC_KEY_PATH: "/var/run/secrets/guacamole/jwt-key.pub" - # TODO: replace with OVH pod CIDR when JupyterHub is deployed JUPYTER_IP_LOWER: "10.0.0.0" JUPYTER_IP_UPPER: "10.255.255.255" diff --git a/clusters/dev/apps/kong-postgresql/application.yaml b/clusters/dev/apps/kong-postgresql/application.yaml index 3c60a00..e3ba652 100644 --- a/clusters/dev/apps/kong-postgresql/application.yaml +++ b/clusters/dev/apps/kong-postgresql/application.yaml @@ -15,10 +15,6 @@ spec: helm: valueFiles: - ../../registry.yaml - # TODO: versions.yaml has pg_cron tag for main utility postgres only. - # Proper fix: add postgresql-standard key to versions.yaml with standard - # bitnami tag, then reference it here. For now, using chart default. - # - ../../versions.yaml - values.yaml destination: server: https://kubernetes.default.svc diff --git a/clusters/prod/apps/approval/Chart.yaml b/clusters/prod/apps/approval/Chart.yaml new file mode 100644 index 0000000..9fdb260 --- /dev/null +++ b/clusters/prod/apps/approval/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: approval +version: 0.1.0 +dependencies: + - name: approval-service + version: "0.3.1" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/approval/application.yaml b/clusters/prod/apps/approval/application.yaml new file mode 100644 index 0000000..d9a391d --- /dev/null +++ b/clusters/prod/apps/approval/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: approval + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/approval + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/approval/templates/external-secret.yaml b/clusters/prod/apps/approval/templates/external-secret.yaml new file mode 100644 index 0000000..972dd07 --- /dev/null +++ b/clusters/prod/apps/approval/templates/external-secret.yaml @@ -0,0 +1,25 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: approval-credentials + namespace: utility +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: approval-credentials + data: + - secretKey: db-uri + remoteRef: + key: secret/data/approval + property: db-uri + - secretKey: rds-password + remoteRef: + key: secret/data/postgresql + property: approval-user-password + - secretKey: redis-password + remoteRef: + key: secret/data/redis + property: password diff --git a/clusters/prod/apps/approval/values.yaml b/clusters/prod/apps/approval/values.yaml new file mode 100644 index 0000000..15d4031 --- /dev/null +++ b/clusters/prod/apps/approval/values.yaml @@ -0,0 +1,88 @@ +approval-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/approval + pullPolicy: IfNotPresent + # tag from versions.yaml via valueFile merge + + fullnameOverride: approval + replicaCount: 1 + + container: + port: 8000 + + service: + type: ClusterIP + port: 8000 + + imagePullSecrets: + - name: docker-registry-secret + + appConfig: + env: prod + config_center_enabled: "false" + config_center_base_url: "http://common.utility:5062/" + + extraEnv: + CORE_ZONE_LABEL: "Core" + GREENROOM_ZONE_LABEL: "Greenroom" + META_SERVICE: "http://metadata.utility:5066" + RDS_SCHEMA_DEFAULT: "pilot_approval" + AUTH_SERVICE: "http://auth.utility:5061" + DATAOPS_SERVICE: "http://dataops.utility:5063" + EMAIL_SERVICE: "http://notification.utility:5065" + METADATA_SERVICE: "http://metadata.utility:5066" + PROJECT_SERVICE: "http://project.utility:5064" + NOTIFICATION_SERVICE: "http://notification.utility:5065" + REDIS_DB: "0" + REDIS_HOST: "redis-master.redis" + REDIS_PORT: "6379" + RDS_DB: "approval" + RDS_HOST: "postgres.utility" + RDS_USER: "approval_user" + RDS_PORT: "5432" + + extraEnvYaml: + - name: DB_URI + valueFrom: + secretKeyRef: + name: approval-credentials + key: db-uri + - name: RDS_PASSWORD + valueFrom: + secretKeyRef: + name: approval-credentials + key: rds-password + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: approval-credentials + key: redis-password + + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 500m + memory: 500Mi + + readinessProbe: + tcpSocket: + port: 8000 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + + livenessProbe: + httpGet: + path: /v1/health + port: 8000 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 3 + + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 diff --git a/clusters/prod/apps/auth/Chart.yaml b/clusters/prod/apps/auth/Chart.yaml new file mode 100644 index 0000000..16c3780 --- /dev/null +++ b/clusters/prod/apps/auth/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: auth +version: 0.1.0 +dependencies: + - name: auth-service + version: "1.0.9" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/auth/application.yaml b/clusters/prod/apps/auth/application.yaml new file mode 100644 index 0000000..b3c8e67 --- /dev/null +++ b/clusters/prod/apps/auth/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: auth + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "7" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/auth + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/auth/templates/external-secret.yaml b/clusters/prod/apps/auth/templates/external-secret.yaml new file mode 100644 index 0000000..0ff8471 --- /dev/null +++ b/clusters/prod/apps/auth/templates/external-secret.yaml @@ -0,0 +1,29 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: auth-credentials + namespace: utility +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: auth-credentials + data: + - secretKey: auth-user-password + remoteRef: + key: secret/data/postgresql + property: auth-user-password + - secretKey: redis-password + remoteRef: + key: secret/data/redis + property: password + - secretKey: keycloak-client-secret + remoteRef: + key: secret/data/auth + property: keycloak-client-secret + - secretKey: freeipa-password + remoteRef: + key: secret/data/auth + property: freeipa-password diff --git a/clusters/prod/apps/auth/values.yaml b/clusters/prod/apps/auth/values.yaml new file mode 100644 index 0000000..4b6a0c3 --- /dev/null +++ b/clusters/prod/apps/auth/values.yaml @@ -0,0 +1,103 @@ +auth-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/auth + pullPolicy: IfNotPresent + + fullnameOverride: auth + replicaCount: 3 + + container: + port: 5061 + + service: + type: ClusterIP + port: 5061 + targetPort: 5061 + + imagePullSecrets: + - name: docker-registry-secret + + appConfig: + env: prod + WORKERS: 2 + RDS_HOST: postgres.utility + RDS_USER: auth_user + RDS_DBNAME: auth + RDS_SCHEMA_PREFIX: pilot + LDAP_PREFIX: hdc + LDAP_COMMON_NAME_PREFIX: hdc + AD_USER_GROUP: hdc-users + IDENTITY_BACKEND: keycloak + KEYCLOAK_SERVER_URL: "https://iam.hdc.ebrains.eu/" + KEYCLOAK_CLIENT_ID: kong + KEYCLOAK_REALM: hdc + KEYCLOAK_ID: hdc + REDIS_HOST: redis-master.redis + REDIS_PORT: "6379" + FREEIPA_URL: "ldap.hdc.ebrains.eu" + ENABLE_ACTIVE_DIRECTORY: "false" + DOMAIN_NAME: "https://portal.hdc.ebrains.eu" + START_PATH: hdc + GUIDE_PATH: "" + EMAIL_SUPPORT: support@hdc.ebrains.eu + EMAIL_ADMIN: admin@hdc.ebrains.eu + EMAIL_HELPDESK: helpdesk@hdc.ebrains.eu + PLATFORM_NAME: HDC + PROJECT_NAME: HDC + OPEN_TELEMETRY_ENABLED: "false" + config_center_enabled: "false" + + resources: + limits: + cpu: 500m + memory: 500Mi + requests: + cpu: 25m + memory: 10Mi + + extraEnvYaml: + - name: RDS_PWD + valueFrom: + secretKeyRef: + name: auth-credentials + key: auth-user-password + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: auth-credentials + key: redis-password + - name: KEYCLOAK_SECRET + valueFrom: + secretKeyRef: + name: auth-credentials + key: keycloak-client-secret + - name: FREEIPA_PASSWORD + valueFrom: + secretKeyRef: + name: auth-credentials + key: freeipa-password + + extraEnv: + REDIS_DB: "0" + RDS_PRE_PING: "true" + + readinessProbe: + tcpSocket: + port: 5061 + initialDelaySeconds: 10 + periodSeconds: 10 + failureThreshold: 3 + + livenessProbe: + httpGet: + path: /v1/health + port: 5061 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 3 + + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 diff --git a/clusters/prod/apps/dataops/Chart.yaml b/clusters/prod/apps/dataops/Chart.yaml new file mode 100644 index 0000000..865bd27 --- /dev/null +++ b/clusters/prod/apps/dataops/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: dataops +version: 0.1.0 +dependencies: + - name: dataops-service + version: "0.2.1" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/dataops/application.yaml b/clusters/prod/apps/dataops/application.yaml new file mode 100644 index 0000000..236e675 --- /dev/null +++ b/clusters/prod/apps/dataops/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: dataops + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/dataops + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/dataops/templates/external-secret.yaml b/clusters/prod/apps/dataops/templates/external-secret.yaml new file mode 100644 index 0000000..14c942e --- /dev/null +++ b/clusters/prod/apps/dataops/templates/external-secret.yaml @@ -0,0 +1,21 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: dataops-credentials + namespace: utility +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: dataops-credentials + data: + - secretKey: rds-password + remoteRef: + key: secret/data/postgresql + property: dataops-user-password + - secretKey: redis-password + remoteRef: + key: secret/data/redis + property: password diff --git a/clusters/prod/apps/dataops/values.yaml b/clusters/prod/apps/dataops/values.yaml new file mode 100644 index 0000000..f1b93bd --- /dev/null +++ b/clusters/prod/apps/dataops/values.yaml @@ -0,0 +1,84 @@ +dataops-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/dataops + pullPolicy: IfNotPresent + # tag comes from versions.yaml via valueFile merge + + fullnameOverride: dataops + replicaCount: 1 + + container: + port: 5063 + + service: + type: ClusterIP + port: 5063 + + imagePullSecrets: + - name: docker-registry-secret + + appConfig: + env: prod + config_center_enabled: "false" + config_center_base_url: "" + + extraEnv: + HOST: "0.0.0.0" + RDS_HOST: "postgres.utility" + RDS_PORT: "5432" + RDS_NAME: "dataops" + RDS_USERNAME: "dataops_user" + RDS_SCHEMA: "public" + RDS_ECHO_SQL_QUERIES: "false" + REDIS_HOST: "redis-master.redis" + REDIS_PORT: "6379" + REDIS_DB: "0" + WORKERS: "2" + LINEAGE_SERVICE: "http://lineage.utility:5064" + QUEUE_SERVICE: "http://queue-producer.greenroom:6060" + METADATA_SERVICE: "http://metadata.utility:5066" + AUTH_SERVICE: "http://auth.utility:5061" + MINIO_HOST: "http://minio.minio" + MINIO_PORT: "9000" + RSA_PUBLIC_KEY: "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFvQkNRQUpRbnpDK1UwN2h3NGliYWNLaWNMbWtTOFR0Mmp6MkFIcVFhWG1sOWUzeCsrZzh5TCtOaDNJSDAzLzdUV2xnbEFSNWRDcEU2cS9LaVpKS1dxU3RCcnlmOHk1UEhaUTJua1YxWXViajRPSThzMklKRFgyNU9XaUNvZFFDRkNwTkNyY1ZmSGpjbnJvRy9icGJoTTBBZ0RFc054UDlpd3NrZ2h3RVFGTDVuc1JWWkpyUEJ0T0dNRWJ4N0xNY3kyeFI2YmlySWFYTmNWSUlyd1g4MVB5bzZENlZRRzlkNkJSUmwvWlVDNGZ5SzZpNGxKUVJvUUV0SW0xNm9PNUFsUGpzYloxd0NXVStlazJJek9aNGRrRnhtUWlwdUpsbjI5TE1jZGdCMlFGZFRNcXBQTXlxWXc3ZmplWmhOL3FoZDFKbUVEeUZOVHVKcEt5Ymd2Y2VnNXdJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0t" + + extraEnvYaml: + - name: RDS_PASSWORD + valueFrom: + secretKeyRef: + name: dataops-credentials + key: rds-password + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: dataops-credentials + key: redis-password + + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 500m + memory: 500Mi + + readinessProbe: + tcpSocket: + port: 5063 + initialDelaySeconds: 10 + periodSeconds: 10 + failureThreshold: 3 + + livenessProbe: + httpGet: + path: /v1/health + port: 5063 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 3 + + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 diff --git a/clusters/prod/apps/dataset/Chart.yaml b/clusters/prod/apps/dataset/Chart.yaml new file mode 100644 index 0000000..c2f28f6 --- /dev/null +++ b/clusters/prod/apps/dataset/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: dataset +version: 0.1.0 +dependencies: + - name: base-chart-hdc + version: "1.0.1" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/dataset/application.yaml b/clusters/prod/apps/dataset/application.yaml new file mode 100644 index 0000000..3368266 --- /dev/null +++ b/clusters/prod/apps/dataset/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: dataset + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/dataset + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/dataset/templates/external-secret.yaml b/clusters/prod/apps/dataset/templates/external-secret.yaml new file mode 100644 index 0000000..1fe8b3e --- /dev/null +++ b/clusters/prod/apps/dataset/templates/external-secret.yaml @@ -0,0 +1,36 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: dataset-credentials + namespace: utility +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: dataset-credentials + data: + # PostgreSQL credentials + - secretKey: db-username + remoteRef: + key: secret/data/postgresql + property: dataset-user + - secretKey: db-password + remoteRef: + key: secret/data/postgresql + property: dataset-user-password + # MinIO credentials + - secretKey: minio-access-key + remoteRef: + key: secret/data/minio + property: access_key + - secretKey: minio-secret-key + remoteRef: + key: secret/data/minio + property: secret_key + # Redis + - secretKey: redis-password + remoteRef: + key: secret/data/redis + property: password diff --git a/clusters/prod/apps/dataset/values.yaml b/clusters/prod/apps/dataset/values.yaml new file mode 100644 index 0000000..3bed0b8 --- /dev/null +++ b/clusters/prod/apps/dataset/values.yaml @@ -0,0 +1,143 @@ +base-chart-hdc: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/dataset + tag: "2.3.41" + tagPrefix: "dataset" + pullPolicy: IfNotPresent + initContainers: + enabled: true + image: + tagPrefix: alembic + fullnameOverride: dataset + labels: + app: dataset + instance: dataset-service + replicaCount: 1 + container: + name: dataset + ports: + - name: http + containerPort: 5081 + protocol: TCP + service: + type: ClusterIP + ports: + - port: 5081 + targetPort: 5081 + protocol: TCP + name: http + imagePullSecrets: + - name: docker-registry-secret + appConfig: + env: prod + config_center_enabled: false + extraEnv: + # Telemetry + OPEN_TELEMETRY_ENABLED: "true" + ENABLE_PROMETHEUS_METRICS: "false" + # Dataset config + DATASET_FILE_FOLDER: "data" + DATASET_SCHEMA_FOLDER: "schema" + DATASET_CODE_REGEX: "^[a-z0-9]{3,32}$" + ROOT_PATH: "/data/core-storage" + CORE_ZONE_LABEL: "Core" + GREEN_ZONE_LABEL: "Greenroom" + # MinIO + MINIO_OPENID_CLIENT: "react-app" + MINIO_ENDPOINT: "minio.minio:9000" + MINIO_HTTPS: "False" + S3_GATEWAY: "True" + S3_INTERNAL: "minio.minio:9000" + S3_INTERNAL_HTTPS: "False" + S3_HOST: "minio.minio" + S3_PORT: "9000" + S3_HTTPS_ENABLED: "false" + S3_GATEWAY_ENABLED: "true" + S3_BUCKET_ENCRYPTION_ENABLED: "false" + S3_PUBLIC: "object.hdc.ebrains.eu" + S3_PUBLIC_HTTPS: "TRUE" + # Keycloak + KEYCLOAK_URL: "http://keycloak.keycloak/auth/realms/hdc/protocol/openid-connect/token" + # Services + METADATA_SERVICE: "http://metadata.utility:5066" + PROJECT_SERVICE: "http://project.utility:5064" + QUEUE_SERVICE: "http://queue-producer.greenroom:6060" + # Kafka + KAFKA_URL: "kafka-headless.utility:9092" + # Queue + gm_queue_endpoint: "message-bus-greenroom.greenroom" + # Database + RDS_HOST: "postgres.utility" + RDS_PORT: "5432" + RDS_DBNAME: "dataset" + RDS_SCHEMA_DEFAULT: "dataset" + OPSDB_UTILITY_HOST: "postgres.utility" + OPSDB_UTILITY_PORT: "5432" + RUN_MIGRATIONS_ON_BUILD: "false" + ALEMBIC_CONFIG: "migrations/alembic.ini" + # Redis + REDIS_HOST: "redis-master.redis" + REDIS_PORT: "6379" + REDIS_DB: "0" + DATA_OPS_UTIL: "http://dataops.utility:5063" + # Misc + DOWNLOAD_TOKEN_EXPIRE_AT: "5" + MAX_PREVIEW_SIZE: "500000" + ESSENTIALS_NAME: "essential.schema.json" + ESSENTIALS_TPL_NAME: "Essential" + extraEnvYaml: + - name: OPSDB_UTILITY_USERNAME + valueFrom: + secretKeyRef: + name: dataset-credentials + key: db-username + - name: OPSDB_UTILITY_PASSWORD + valueFrom: + secretKeyRef: + name: dataset-credentials + key: db-password + - name: MINIO_USERNAME + valueFrom: + secretKeyRef: + name: dataset-credentials + key: minio-access-key + - name: MINIO_PASSWORD + valueFrom: + secretKeyRef: + name: dataset-credentials + key: minio-secret-key + - name: S3_ACCESS_KEY + valueFrom: + secretKeyRef: + name: dataset-credentials + key: minio-access-key + - name: S3_SECRET_KEY + valueFrom: + secretKeyRef: + name: dataset-credentials + key: minio-secret-key + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: dataset-credentials + key: redis-password + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 500m + memory: 500Mi + readinessProbe: + tcpSocket: + port: 5081 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + livenessProbe: + httpGet: + path: /v1/health + port: 5081 + periodSeconds: 10 + failureThreshold: 3 + timeoutSeconds: 3 diff --git a/clusters/prod/apps/download-core/Chart.yaml b/clusters/prod/apps/download-core/Chart.yaml new file mode 100644 index 0000000..66a3566 --- /dev/null +++ b/clusters/prod/apps/download-core/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: download-core +version: 0.1.0 +dependencies: + - name: download-service + version: "1.0.6" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/download-core/application.yaml b/clusters/prod/apps/download-core/application.yaml new file mode 100644 index 0000000..82c5c8b --- /dev/null +++ b/clusters/prod/apps/download-core/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: download-core + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/download-core + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: core + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/download-core/templates/external-secret.yaml b/clusters/prod/apps/download-core/templates/external-secret.yaml new file mode 100644 index 0000000..38d9986 --- /dev/null +++ b/clusters/prod/apps/download-core/templates/external-secret.yaml @@ -0,0 +1,29 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: download-credentials + namespace: core +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: download-credentials + data: + - secretKey: download-key + remoteRef: + key: secret/data/download + property: download-key + - secretKey: redis-password + remoteRef: + key: secret/data/redis + property: password + - secretKey: minio-access-key + remoteRef: + key: secret/data/minio + property: access_key + - secretKey: minio-secret-key + remoteRef: + key: secret/data/minio + property: secret_key diff --git a/clusters/prod/apps/download-core/values.yaml b/clusters/prod/apps/download-core/values.yaml new file mode 100644 index 0000000..7182a5a --- /dev/null +++ b/clusters/prod/apps/download-core/values.yaml @@ -0,0 +1,94 @@ +download-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/download + pullPolicy: IfNotPresent + + + fullnameOverride: download + replicaCount: 1 + + container: + port: 5077 + + service: + type: ClusterIP + port: 5077 + targetPort: 5077 + + imagePullSecrets: + - name: docker-registry-secret + + appConfig: + port: 5077 + env: prod + config_center_enabled: false + ROOT_PATH: "/data/core-storage" + OPEN_TELEMETRY_ENABLED: "False" + + extraEnv: + HOST: "0.0.0.0" + namespace: "core" + S3_INTERNAL: "minio.minio:9000" + S3_INTERNAL_HTTPS: "FALSE" + S3_PUBLIC: "object.hdc.ebrains.eu" + S3_PUBLIC_HTTPS: "TRUE" + + extraEnvYaml: + - name: DOWNLOAD_KEY + valueFrom: + secretKeyRef: + name: download-credentials + key: download-key + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: download-credentials + key: redis-password + - name: S3_ACCESS_KEY + valueFrom: + secretKeyRef: + name: download-credentials + key: minio-access-key + - name: S3_SECRET_KEY + valueFrom: + secretKeyRef: + name: download-credentials + key: minio-secret-key + + extraVolumeMounts: + - name: download-storage + mountPath: /data/core-storage + readOnly: false + + extraVolumes: + - name: download-storage + persistentVolumeClaim: + claimName: core-storage + + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 500m + memory: 500Mi + + readinessProbe: + tcpSocket: + port: 5077 + initialDelaySeconds: 5 + periodSeconds: 10 + + livenessProbe: + httpGet: + path: /v1/health + port: 5077 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 3 + + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 diff --git a/clusters/prod/apps/download-greenroom/Chart.yaml b/clusters/prod/apps/download-greenroom/Chart.yaml new file mode 100644 index 0000000..3c017df --- /dev/null +++ b/clusters/prod/apps/download-greenroom/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: download-greenroom +version: 0.1.0 +dependencies: + - name: download-service + version: "1.0.6" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/download-greenroom/application.yaml b/clusters/prod/apps/download-greenroom/application.yaml new file mode 100644 index 0000000..6a579dc --- /dev/null +++ b/clusters/prod/apps/download-greenroom/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: download-greenroom + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/download-greenroom + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: greenroom + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/download-greenroom/templates/external-secret.yaml b/clusters/prod/apps/download-greenroom/templates/external-secret.yaml new file mode 100644 index 0000000..6f2e804 --- /dev/null +++ b/clusters/prod/apps/download-greenroom/templates/external-secret.yaml @@ -0,0 +1,29 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: download-credentials + namespace: greenroom +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: download-credentials + data: + - secretKey: download-key + remoteRef: + key: secret/data/download + property: download-key + - secretKey: redis-password + remoteRef: + key: secret/data/redis + property: password + - secretKey: minio-access-key + remoteRef: + key: secret/data/minio + property: access_key + - secretKey: minio-secret-key + remoteRef: + key: secret/data/minio + property: secret_key diff --git a/clusters/prod/apps/download-greenroom/values.yaml b/clusters/prod/apps/download-greenroom/values.yaml new file mode 100644 index 0000000..88b4a7d --- /dev/null +++ b/clusters/prod/apps/download-greenroom/values.yaml @@ -0,0 +1,94 @@ +download-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/download + pullPolicy: IfNotPresent + + + fullnameOverride: download + replicaCount: 1 + + container: + port: 5077 + + service: + type: ClusterIP + port: 5077 + targetPort: 5077 + + imagePullSecrets: + - name: docker-registry-secret + + appConfig: + port: 5077 + env: prod + config_center_enabled: false + ROOT_PATH: "/data/greenroom-storage" + OPEN_TELEMETRY_ENABLED: "False" + + extraEnv: + HOST: "0.0.0.0" + namespace: "greenroom" + S3_INTERNAL: "minio.minio:9000" + S3_INTERNAL_HTTPS: "FALSE" + S3_PUBLIC: "object.hdc.ebrains.eu" + S3_PUBLIC_HTTPS: "TRUE" + + extraEnvYaml: + - name: DOWNLOAD_KEY + valueFrom: + secretKeyRef: + name: download-credentials + key: download-key + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: download-credentials + key: redis-password + - name: S3_ACCESS_KEY + valueFrom: + secretKeyRef: + name: download-credentials + key: minio-access-key + - name: S3_SECRET_KEY + valueFrom: + secretKeyRef: + name: download-credentials + key: minio-secret-key + + extraVolumeMounts: + - name: download-storage + mountPath: /data/greenroom-storage + readOnly: false + + extraVolumes: + - name: download-storage + persistentVolumeClaim: + claimName: greenroom-storage + + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 500m + memory: 500Mi + + readinessProbe: + tcpSocket: + port: 5077 + initialDelaySeconds: 5 + periodSeconds: 10 + + livenessProbe: + httpGet: + path: /v1/health + port: 5077 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 3 + + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 diff --git a/clusters/prod/apps/keycloak/Chart.yaml b/clusters/prod/apps/keycloak/Chart.yaml new file mode 100644 index 0000000..d8cb845 --- /dev/null +++ b/clusters/prod/apps/keycloak/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: keycloak +version: 0.1.0 +dependencies: + - name: keycloak + version: "13.2.0" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/keycloak/application.yaml b/clusters/prod/apps/keycloak/application.yaml new file mode 100644 index 0000000..e270e5b --- /dev/null +++ b/clusters/prod/apps/keycloak/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: keycloak + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "6" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/keycloak + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: keycloak + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/keycloak/templates/external-secret.yaml b/clusters/prod/apps/keycloak/templates/external-secret.yaml new file mode 100644 index 0000000..497b48a --- /dev/null +++ b/clusters/prod/apps/keycloak/templates/external-secret.yaml @@ -0,0 +1,53 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: keycloak-credentials + namespace: keycloak +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: keycloak-credentials + data: + - secretKey: admin-password + remoteRef: + key: secret/data/keycloak + property: admin-password +--- +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: keycloak-db-credentials + namespace: keycloak +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: keycloak-db-credentials + data: + - secretKey: password + remoteRef: + key: secret/data/keycloak + property: keycloak-user-password +--- +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: github-access-token + namespace: keycloak +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: github-access-token + data: + - secretKey: GITHUB_TOKEN + remoteRef: + key: secret/data/keycloak + property: github-token diff --git a/clusters/prod/apps/keycloak/templates/keycloak-antd-pvc.yaml b/clusters/prod/apps/keycloak/templates/keycloak-antd-pvc.yaml new file mode 100644 index 0000000..6ef116a --- /dev/null +++ b/clusters/prod/apps/keycloak/templates/keycloak-antd-pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: keycloak-antd + namespace: keycloak +spec: + accessModes: + - ReadWriteOnce + storageClassName: csi-cinder-high-speed + resources: + requests: + storage: 1Gi diff --git a/clusters/prod/apps/keycloak/templates/theme-configmap.yaml b/clusters/prod/apps/keycloak/templates/theme-configmap.yaml new file mode 100644 index 0000000..39cd43f --- /dev/null +++ b/clusters/prod/apps/keycloak/templates/theme-configmap.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: keycloak-antd-theme + namespace: keycloak +data: + login.ftl: | +{{ .Files.Get "theme/login/login.ftl" | indent 4 }} + template.ftl: | +{{ .Files.Get "theme/login/template.ftl" | indent 4 }} + theme.properties: | +{{ .Files.Get "theme/login/theme.properties" | indent 4 }} + login.css: | +{{ .Files.Get "theme/login/resources/css/login.css" | indent 4 }} + jquery.min.js: | +{{ .Files.Get "theme/login/resources/js/jquery.min.js" | indent 4 }} + login.js: | +{{ .Files.Get "theme/login/resources/js/login.js" | indent 4 }} +binaryData: + error.png: {{ .Files.Get "theme/login/resources/img/error.png" | b64enc | quote }} + favicon.ico: {{ .Files.Get "theme/login/resources/img/favicon.ico" | b64enc | quote }} + feedback-error-arrow-down.png: {{ .Files.Get "theme/login/resources/img/feedback-error-arrow-down.png" | b64enc | quote }} + feedback-error-sign.png: {{ .Files.Get "theme/login/resources/img/feedback-error-sign.png" | b64enc | quote }} + feedback-success-arrow-down.png: {{ .Files.Get "theme/login/resources/img/feedback-success-arrow-down.png" | b64enc | quote }} + feedback-success-sign.png: {{ .Files.Get "theme/login/resources/img/feedback-success-sign.png" | b64enc | quote }} + feedback-warning-arrow-down.png: {{ .Files.Get "theme/login/resources/img/feedback-warning-arrow-down.png" | b64enc | quote }} + feedback-warning-sign.png: {{ .Files.Get "theme/login/resources/img/feedback-warning-sign.png" | b64enc | quote }} + HDC-logo.png: {{ .Files.Get "theme/login/resources/img/HDC-logo.png" | b64enc | quote }} + keycloak-bg.png: {{ .Files.Get "theme/login/resources/img/keycloak-bg.png" | b64enc | quote }} + keycloak-logo.png: {{ .Files.Get "theme/login/resources/img/keycloak-logo.png" | b64enc | quote }} + keycloak-logo-text.png: {{ .Files.Get "theme/login/resources/img/keycloak-logo-text.png" | b64enc | quote }} + lock.png: {{ .Files.Get "theme/login/resources/img/lock.png" | b64enc | quote }} + user.png: {{ .Files.Get "theme/login/resources/img/user.png" | b64enc | quote }} diff --git a/clusters/prod/apps/keycloak/theme/login/login.ftl b/clusters/prod/apps/keycloak/theme/login/login.ftl new file mode 100644 index 0000000..5e5e8b3 --- /dev/null +++ b/clusters/prod/apps/keycloak/theme/login/login.ftl @@ -0,0 +1,74 @@ +<#import "template.ftl" as layout> +<@layout.registrationLayout displayInfo=social.displayInfo displayWide=(realm.password && social.providers??); section> + <#if section = "header"> + <#-- ${msg("doLogIn")} --> + + <#elseif section = "form"> + +
class="${properties.kcContentWrapperClass!}"> +
class="${properties.kcFormSocialAccountContentClass!} ${properties.kcFormSocialAccountClass!}"> + <#if realm.password> +
+
+ + <#if usernameEditDisabled??> + + <#else> + + +
+
+ + +
+
+
+ <#if realm.rememberMe && !usernameEditDisabled??> +
+ +
+ +
+
+ <#if realm.resetPasswordAllowed> + + +
+ +
+ +
+ value="${auth.selectedCredential}"/> + +
+
+
+ or login with username and password +
+ +
+ <#if realm.password && social.providers??> +
+ +
+ +
+ <#elseif section = "info" > + <#if realm.password && realm.registrationAllowed && !registrationDisabled??> +
+ ${msg("noAccount")} ${msg("doRegister")} +
+ + + + diff --git a/clusters/prod/apps/keycloak/theme/login/resources/css/login.css b/clusters/prod/apps/keycloak/theme/login/resources/css/login.css new file mode 100644 index 0000000..c92a780 --- /dev/null +++ b/clusters/prod/apps/keycloak/theme/login/resources/css/login.css @@ -0,0 +1,687 @@ +.login-pf body { + background: none; + background-color: #f0f2f5; + background-size: cover; + height: 100%; +} + +.label-icon{ + width:15px; margin-top:-5px; +} + +.label-text{ + margin-left: 8px; +} + +.forget-password{ + margin-bottom: 8px; +} + +.login-pf-page-header{ + display: none; +} + +.login-pf-page{ + padding-top: 117px; +} + +/* .card-pf{ + position: absolute ; + margin: auto ; +} */ + +.form-div{ + padding-top: 30px; +} + +.btn { + line-height: 1.5715; + position: relative; + display: inline-block; + font-weight: 400; + white-space: nowrap; + text-align: center; + background-image: none; + border: 1px solid transparent; + -webkit-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015); + box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015); + cursor: pointer; + -webkit-transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); + transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -ms-touch-action: manipulation; + touch-action: manipulation; + height: 32px; + padding: 4px 15px; + font-size: 14px; + border-radius: 2px; + color: rgba(0, 0, 0, 0.65); + background-color: #fff; + border-color: #d9d9d9; + } + + .btn-primary { + color: #fff; + background-color: #5bab58; + border-color: #5bab58; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12); + -webkit-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045); + box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045); + } + + .alert { + -webkit-box-sizing: border-box; + box-sizing: border-box; + margin: 0; + padding: 0; + color: rgba(0, 0, 0, 0.65); + font-size: 14px; + font-variant: tabular-nums; + line-height: 1.5715; + list-style: none; + -webkit-font-feature-settings: 'tnum'; + font-feature-settings: 'tnum'; + position: relative; + padding: 8px 15px 8px 15px; + word-wrap: break-word; + border-radius: 2px; + } +.alert-error { + background-color: #fff2f0; + border: 1px solid #ffccc7; +} + +.alert-success{ + background-color: #f6ffed; + border: 1px solid #b7eb8f; + color: #52c41a; +} + +.alert-warning{ + background-color: #fffbe6; + border: 1px solid #ffe58f; +} + +.alert-info{ + background-color: #e6f7ff; + border: 1px solid #91d5ff; +} + +#kc-locale ul { + display: none; + position: absolute; + background-color: #fff; + list-style: none; + right: 0; + top: 20px; + min-width: 100px; + padding: 2px 0; + border: solid 1px #bbb; +} + +#kc-locale:hover ul { + display: block; + margin: 0; +} + +#kc-locale ul li a { + display: block; + padding: 5px 14px; + color: #000 !important; + text-decoration: none; + line-height: 20px; +} + +#kc-locale ul li a:hover { + color: #4d5258; + background-color: #d4edfa; +} + +#kc-locale-dropdown a { + color: #4d5258; + background: 0 0; + padding: 0 15px 0 0; + font-weight: 300; +} + +#kc-locale-dropdown a:hover { + text-decoration: none; +} + +a#kc-current-locale-link { + display: block; + padding: 0 5px; +} + +/* a#kc-current-locale-link:hover { + background-color: rgba(0,0,0,0.2); +} */ + +a#kc-current-locale-link::after { + content: "\2c5"; + margin-left: 4px; +} + +.login-pf .container { + padding-top: 40px; +} + +.login-pf a:hover { + color: #5bab58; +} + +#kc-logo { + width: 100%; +} + +#kc-logo-wrapper { + background-image: url(../img/keycloak-logo-2.png); + background-repeat: no-repeat; + height: 63px; + width: 300px; + margin: 62px auto 0; +} + +div.kc-logo-text { + background-image: url(../img/keycloak-logo-text.png); + background-repeat: no-repeat; + height: 63px; + width: 300px; + margin: 0 auto; +} + +div.kc-logo-text span { + display: none; +} + +#kc-header { + color: #ededed; + overflow: visible; + white-space: nowrap; +} + +#kc-header-wrapper { + display: none; + font-size: 29px; + text-transform: uppercase; + letter-spacing: 3px; + line-height: 1.2em; + padding: 62px 10px 20px; + white-space: normal; +} + +#kc-content { + width: 100%; +} + +#kc-attempted-username{ + font-size: 20px; + font-family:inherit; + font-weight: normal; + padding-right:10px; +} + +#kc-username{ + text-align: center; +} + +#kc-webauthn-settings-form{ + padding-top:8px; +} + +/* #kc-content-wrapper { + overflow-y: hidden; +} */ + +#kc-info { + padding-bottom: 200px; + margin-bottom: -200px; +} + +#kc-info-wrapper { + font-size: 13px; +} + +#kc-form-options span { + display: block; +} + +#kc-form-options .checkbox { + margin-top: 0; + color: #72767b; +} + +#kc-terms-text { + margin-bottom: 20px; +} + +#kc-registration { + margin-bottom: 15px; +} + +/* TOTP */ + +.subtitle { + text-align: right; + margin-top: 30px; + color: #909090; +} + +.required { + color: #CB2915; +} + +ol#kc-totp-settings { + margin: 0; + padding-left: 20px; +} + +ul#kc-totp-supported-apps { + margin-bottom: 10px; +} + +#kc-totp-secret-qr-code { + max-width:150px; + max-height:150px; +} + +#kc-totp-secret-key { + background-color: #fff; + color: #333333; + font-size: 16px; + padding: 10px 0; +} + +/* OAuth */ + +#kc-oauth h3 { + margin-top: 0; +} + +#kc-oauth ul { + list-style: none; + padding: 0; + margin: 0; +} + +#kc-oauth ul li { + border-top: 1px solid rgba(255, 255, 255, 0.1); + font-size: 12px; + padding: 10px 0; +} + +#kc-oauth ul li:first-of-type { + border-top: 0; +} + +#kc-oauth .kc-role { + display: inline-block; + width: 50%; +} + +/* Code */ +#kc-code textarea { + width: 100%; + height: 8em; +} + +/* Social */ + +#kc-social-providers ul { + padding: 0; +} + +#kc-social-providers li { + display: block; +} + +#kc-social-providers li:first-of-type { + margin-top: 0; +} + +.kc-login-tooltip{ + position:relative; + display: inline-block; +} + +.kc-login-tooltip .kc-tooltip-text{ + top:-3px; + left:160%; + background-color: black; + visibility: hidden; + color: #fff; + + min-width:130px; + text-align: center; + border-radius: 2px; + box-shadow:0 1px 8px rgba(0,0,0,0.6); + padding: 5px; + + position: absolute; + opacity:0; + transition:opacity 0.5s; +} + +/* Show tooltip */ +.kc-login-tooltip:hover .kc-tooltip-text { + visibility: visible; + opacity:0.7; +} + +/* Arrow for tooltip */ +.kc-login-tooltip .kc-tooltip-text::after { + content: " "; + position: absolute; + top: 15px; + right: 100%; + margin-top: -5px; + border-width: 5px; + border-style: solid; + border-color: transparent black transparent transparent; +} + +.zocial, +a.zocial { + width: 100%; + font-weight: normal; + font-size: 14px; + text-shadow: none; + border: 0; + background: #f5f5f5; + color: #72767b; + border-radius: 0; + white-space: normal; +} +.zocial:before { + border-right: 0; + margin-right: 0; +} +.zocial span:before { + padding: 7px 10px; + font-size: 14px; +} +.zocial:hover { + background: #ededed !important; +} + +.zocial.facebook, +.zocial.github, +.zocial.google, +.zocial.microsoft, +.zocial.stackoverflow, +.zocial.linkedin, +.zocial.twitter { + background-image: none; + border: 0; + + box-shadow: none; + text-shadow: none; +} + +/* Copy of zocial windows classes to be used for microsoft's social provider button */ +.zocial.microsoft:before{ content: "\f15d"; } +.zocial.stackoverflow:before{ color: inherit; } + + +@media (min-width: 768px) { + #kc-container-wrapper { + position: absolute; + width: 100%; + } + + .login-pf .container { + padding-right: 80px; + } + + #kc-locale { + position: relative; + text-align: right; + z-index: 9999; + } +} + +@media (max-width: 767px) { + + .login-pf body { + background: white; + } + + #kc-header { + padding-left: 15px; + padding-right: 15px; + float: none; + text-align: left; + } + + #kc-header-wrapper { + font-size: 16px; + font-weight: bold; + padding: 20px 60px 0 0; + color: #72767b; + letter-spacing: 0; + } + + div.kc-logo-text { + margin: 0; + width: 150px; + height: 32px; + background-size: 100%; + } + + #kc-form { + float: none; + } + + #kc-info-wrapper { + border-top: 1px solid rgba(255, 255, 255, 0.1); + margin-top: 15px; + padding-top: 15px; + padding-left: 0px; + padding-right: 15px; + } + + #kc-social-providers li { + display: block; + margin-right: 5px; + } + + .login-pf .container { + padding-top: 15px; + padding-bottom: 15px; + } + + #kc-locale { + position: absolute; + width: 200px; + top: 20px; + right: 20px; + text-align: right; + z-index: 9999; + } + + #kc-logo-wrapper { + background-size: 100px 21px; + height: 21px; + width: 100px; + margin: 20px 0 0 20px; + } + +} + +@media (min-height: 646px) { + #kc-container-wrapper { + bottom: 12%; + } +} + +@media (max-height: 645px) { + #kc-container-wrapper { + padding-top: 50px; + top: 20%; + } +} + +.card-pf form.form-actions .btn { + float: right; + margin-left: 10px; +} + +.login-pf-page .login-pf-brand { + margin-top: 20px; + max-width: 360px; + width: 40%; +} + +.card-pf { + background: #fff; + margin: 0 auto; + padding: 0 20px; + max-width: 500px; + border-top: 0; + box-shadow: 0px 0px 15px rgba(90, 90, 90, 0.459); + + -webkit-box-sizing: border-box; + box-sizing: border-box; + padding: 0; + color: rgba(0, 0, 0, 0.65); + font-size: 14px; + font-variant: tabular-nums; + line-height: 1.5715; + list-style: none; + -webkit-font-feature-settings: 'tnum'; + font-feature-settings: 'tnum'; + position: relative; + background: #fff; + border-radius: 2px; + -webkit-transition: all 0.3s; + transition: all 0.3s; +} + +/*tablet*/ +@media (max-width: 840px) { + .login-pf-page .card-pf{ + max-width: none; + margin-left: 20px; + margin-right: 20px; + padding: 20px 20px 30px 20px; + } +} +@media (max-width: 767px) { + .login-pf-page .card-pf{ + max-width: none; + margin-left: 0; + margin-right: 0; + padding-top: 0; + } + .card-pf.login-pf-accounts{ + max-width: none; + } +} + +.login-pf-page .login-pf-signup { + font-size: 15px; + color: #72767b; +} +#kc-content-wrapper .row { + margin-left: 0; + margin-right: 0; +} + +@media (min-width: 768px) { + + .login-pf-page .login-pf-social-section .login-pf-social-link:last-of-type { + margin-bottom: 0; + } +} + +.login-pf-page .login-pf-social-link { + margin-bottom: 25px; +} +.login-pf-page .login-pf-social-link a { + padding: 2px 0; + background-color: #5bab58; + color: white; + padding-top: 5px; + padding-bottom: 5px; +} + +.login-pf-page.login-pf-page-accounts { + margin-left: auto; + margin-right: auto; +} + +.login-pf-page .btn-primary { + margin-top: 0; +} + +.login-pf-page .list-view-pf .list-group-item { + border-bottom: 1px solid #ededed; +} + +.login-pf-page .list-view-pf-description { + width: 100%; +} + +.login-pf-page .card-pf{ + margin-bottom: 10px; +} + +#kc-form-login div.form-group:last-of-type, +#kc-register-form div.form-group:last-of-type, +#kc-update-profile-form div.form-group:last-of-type { + margin-bottom: 0px; +} + +#kc-back { + margin-top: 5px; +} + +form#kc-select-back-form div.login-pf-social-section { + padding-left: 0px; + border-left: 0px; +} + +#kc-form{ + display: flex; + flex-direction: column-reverse; +} +.login-pf-page .login-pf-social-section{ + width: 100%!important; + max-width: 100%!important; +} +.login-pf-page .login-pf-social-section:last-of-type{ + padding-left: 0px; + padding-right: 0px; + border-left: 0; +} +.login-pf-page .login-pf-social-section:first-of-type{ + padding-left: 40px; + padding-right: 40px; +} +#kc-social-providers{ + width: 100%!important; + padding-bottom: 40px; + border-bottom: 1px solid #d1d1d1; +} +#kc-form-wrapper{ + padding-top: 40px; +} +#login-username-button{ + position: absolute; + top: -10px; + z-index: 100; + padding: 0 20px; + background: white; + left: 50%; + transform: translate(-50%, 0); +} +#login-username-button:hover{ + color: #5bab58; + cursor: pointer; +} +#kc-form-login{ + display: none; +} \ No newline at end of file diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/HDC-logo.png b/clusters/prod/apps/keycloak/theme/login/resources/img/HDC-logo.png new file mode 100644 index 0000000..f360463 Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/HDC-logo.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/error.png b/clusters/prod/apps/keycloak/theme/login/resources/img/error.png new file mode 100644 index 0000000..3c6b7e5 Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/error.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/favicon.ico b/clusters/prod/apps/keycloak/theme/login/resources/img/favicon.ico new file mode 100644 index 0000000..48188de Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/favicon.ico differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-error-arrow-down.png b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-error-arrow-down.png new file mode 100644 index 0000000..6f2d9d2 Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-error-arrow-down.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-error-sign.png b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-error-sign.png new file mode 100644 index 0000000..0dd5004 Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-error-sign.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-success-arrow-down.png b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-success-arrow-down.png new file mode 100644 index 0000000..03cc0c4 Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-success-arrow-down.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-success-sign.png b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-success-sign.png new file mode 100644 index 0000000..640bd71 Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-success-sign.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-warning-arrow-down.png b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-warning-arrow-down.png new file mode 100644 index 0000000..6f2d9d2 Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-warning-arrow-down.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-warning-sign.png b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-warning-sign.png new file mode 100644 index 0000000..f9392a3 Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/feedback-warning-sign.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/keycloak-bg.png b/clusters/prod/apps/keycloak/theme/login/resources/img/keycloak-bg.png new file mode 100644 index 0000000..4004db4 Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/keycloak-bg.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/keycloak-logo-text.png b/clusters/prod/apps/keycloak/theme/login/resources/img/keycloak-logo-text.png new file mode 100644 index 0000000..63f3b9f Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/keycloak-logo-text.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/keycloak-logo.png b/clusters/prod/apps/keycloak/theme/login/resources/img/keycloak-logo.png new file mode 100644 index 0000000..ffa5b0b Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/keycloak-logo.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/lock.png b/clusters/prod/apps/keycloak/theme/login/resources/img/lock.png new file mode 100644 index 0000000..697845b Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/lock.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/img/user.png b/clusters/prod/apps/keycloak/theme/login/resources/img/user.png new file mode 100644 index 0000000..c0f4d0a Binary files /dev/null and b/clusters/prod/apps/keycloak/theme/login/resources/img/user.png differ diff --git a/clusters/prod/apps/keycloak/theme/login/resources/js/jquery.min.js b/clusters/prod/apps/keycloak/theme/login/resources/js/jquery.min.js new file mode 100644 index 0000000..2c69bc9 --- /dev/null +++ b/clusters/prod/apps/keycloak/theme/login/resources/js/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),v={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&v(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!y||!y.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ve(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ye(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],y=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||y.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||y.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||y.push(".#.+[+~]"),e.querySelectorAll("\\\f"),y.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),y=y.length&&new RegExp(y.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),v=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&v(p,e)?-1:t==C||t.ownerDocument==p&&v(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!y||!y.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),v.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",v.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",v.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return B(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=_e(v.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return B(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 + + + + + + + + + <#if properties.meta?has_content> + <#list properties.meta?split(' ') as meta> + + + + ${msg("loginTitle",(realm.displayName!''))} + + <#if properties.styles?has_content> + <#list properties.styles?split(' ') as style> + + + + <#if properties.scripts?has_content> + <#list properties.scripts?split(' ') as script> + + + + <#if scripts??> + <#list scripts as script> + + + + + + +
+
+
${kcSanitize(msg("loginTitleHtml",(realm.displayNameHtml!'')))?no_esc}
+
+
+
+ <#if realm.internationalizationEnabled && locale.supported?size gt 1> +
+
+
+ ${locale.current} +
    + <#list locale.supported as l> +
  • ${l.label}
  • + +
+
+
+
+ + <#if !(auth?has_content && auth.showUsername() && !auth.showResetCredentials())> + <#if displayRequiredFields> +
+
+ * ${msg("requiredFields")} +
+
+

<#nested "header">

+
+
+ <#else> +

<#nested "header">

+ + <#else> + <#if displayRequiredFields> +
+
+ * ${msg("requiredFields")} +
+
+ <#nested "show-username"> +
+
+ + + + +
+
+
+
+ <#else> + <#nested "show-username"> +
+
+ + + + +
+
+ + +
+
+
+ + <#-- App-initiated actions should not see warning messages about the need to complete the action --> + <#-- during login. --> + <#if displayMessage && message?has_content && (message.type != 'warning' || !isAppInitiatedAction??)> +
+ <#if message.type = 'success'> + <#if message.type = 'warning'> + <#if message.type = 'error'> + <#if message.type = 'info'> + +
+ + + <#nested "form"> + + <#if auth?has_content && auth.showTryAnotherWayLink() && showAnotherWayIfPresent> +
class="${properties.kcContentWrapperClass!}"> +
class="${properties.kcFormSocialAccountContentClass!} ${properties.kcFormSocialAccountClass!}"> + +
+
+ + + <#if displayInfo> +
+
+ <#nested "info"> +
+
+ +
+
+ +
+
+ + + diff --git a/clusters/prod/apps/keycloak/theme/login/theme.properties b/clusters/prod/apps/keycloak/theme/login/theme.properties new file mode 100644 index 0000000..36a1d41 --- /dev/null +++ b/clusters/prod/apps/keycloak/theme/login/theme.properties @@ -0,0 +1,95 @@ +parent=base +import=common/keycloak + +styles=node_modules/patternfly/dist/css/patternfly.min.css node_modules/patternfly/dist/css/patternfly-additions.min.css lib/zocial/zocial.css css/login.css?v=3 +scripts=js/jquery.min.js js/login.js +meta=viewport==width=device-width,initial-scale=1 + +kcHtmlClass=login-pf +kcLoginClass=login-pf-page + +kcLogoLink=http://www.keycloak.org + +kcLogoClass=login-pf-brand + +kcContainerClass=container-fluid +kcContentClass=col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 col-lg-6 col-lg-offset-3 +kcContentWrapperClass=row + +kcHeaderClass=login-pf-page-header +kcFeedbackAreaClass=col-md-12 +kcLocaleClass=col-xs-12 col-sm-1 +kcAlertIconClasserror=pficon pficon-error-circle-o + +kcFormAreaClass=col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2 +kcFormCardClass=card-pf +kcFormCardAccountClass=login-pf-accounts +kcFormSocialAccountClass=login-pf-social-section +kcFormSocialAccountContentClass=col-xs-12 col-sm-6 +kcFormSocialAccountListClass=login-pf-social list-unstyled login-pf-social-all +kcFormSocialAccountDoubleListClass=login-pf-social-double-col +kcFormSocialAccountListLinkClass=login-pf-social-link +kcFormHeaderClass=login-pf-header + +kcFeedbackErrorIcon=pficon pficon-error-circle-o +kcFeedbackWarningIcon=pficon pficon-warning-triangle-o +kcFeedbackSuccessIcon=pficon pficon-ok +kcFeedbackInfoIcon=pficon pficon-info + +kcResetFlowIcon=pficon pficon-arrow fa-2x +kcWebAuthnKeyIcon=pficon pficon-key + +kcFormClass=form-horizontal +kcFormGroupClass=form-group +kcFormGroupErrorClass=has-error +kcLabelClass=control-label +kcLabelWrapperClass=col-xs-12 col-sm-12 col-md-12 col-lg-12 +kcInputClass=form-control +kcInputWrapperClass=col-xs-12 col-sm-12 col-md-12 col-lg-12 +kcFormOptionsClass=col-xs-12 col-sm-12 col-md-12 col-lg-12 +kcFormButtonsClass=col-xs-12 col-sm-12 col-md-12 col-lg-12 +kcFormSettingClass=login-pf-settings +kcTextareaClass=form-control +kcSignUpClass=login-pf-signup + + +kcInfoAreaClass=col-xs-12 col-sm-4 col-md-4 col-lg-5 details + +##### css classes for form buttons +# main class used for all buttons +kcButtonClass=btn +# classes defining priority of the button - primary or default (there is typically only one priority button for the form) +kcButtonPrimaryClass=btn-primary +kcButtonDefaultClass=btn-default +# classes defining size of the button +kcButtonLargeClass=btn-lg +kcButtonBlockClass=btn-block + +##### css classes for input +kcInputLargeClass=input-lg + +##### css classes for form accessability +kcSrOnlyClass=sr-only + +##### css classes for select-authenticator form +kcSelectAuthListClass=list-group list-view-pf +kcSelectAuthListItemClass=list-group-item list-view-pf-stacked +kcSelectAuthListItemInfoClass=list-view-pf-main-info +kcSelectAuthListItemLeftClass=list-view-pf-left +kcSelectAuthListItemBodyClass=list-view-pf-body +kcSelectAuthListItemDescriptionClass=list-view-pf-description +kcSelectAuthListItemHeadingClass=list-group-item-heading +kcSelectAuthListItemHelpTextClass=list-group-item-text + +##### css classes for the authenticators +kcAuthenticatorDefaultClass=fa list-view-pf-icon-lg +kcAuthenticatorPasswordClass=fa fa-unlock list-view-pf-icon-lg +kcAuthenticatorOTPClass=fa fa-mobile list-view-pf-icon-lg +kcAuthenticatorWebAuthnClass=fa fa-key list-view-pf-icon-lg +kcAuthenticatorWebAuthnPasswordlessClass=fa fa-key list-view-pf-icon-lg + +##### css classes for the OTP Login Form +kcSelectOTPListClass=card-pf card-pf-view card-pf-view-select card-pf-view-single-select +kcSelectOTPListItemClass=card-pf-body card-pf-top-element +kcAuthenticatorOtpCircleClass=fa fa-mobile card-pf-icon-circle +kcSelectOTPItemHeadingClass=card-pf-title text-center \ No newline at end of file diff --git a/clusters/prod/apps/keycloak/values.yaml b/clusters/prod/apps/keycloak/values.yaml new file mode 100644 index 0000000..8669c7a --- /dev/null +++ b/clusters/prod/apps/keycloak/values.yaml @@ -0,0 +1,135 @@ +keycloak: + global: + imagePullSecrets: + - docker-registry-secret + + image: + repository: hdc-services-external/bitnami/keycloak + + auth: + existingSecret: keycloak-credentials + passwordSecretKey: "admin-password" + adminUser: user + + service: + type: ClusterIP + + postgresql: + enabled: false + + externalDatabase: + host: "keycloak-postgresql.keycloak" + port: 5432 + user: bn_keycloak + database: bitnami_keycloak + existingSecret: keycloak-db-credentials + existingSecretPasswordKey: password + + extraEnvVars: + - name: KEYCLOAK_LOGLEVEL + value: INFO + - name: KEYCLOAK_PROXY_ADDRESS_FORWARDING + value: "true" + - name: JAVA_OPTS + value: >- + -Dkeycloak.profile.feature.scripts=enabled + -Dkeycloak.profile.feature.upload_scripts=enabled + -Dkeycloak.profile.feature.token_exchange=enabled + -Dkeycloak.adminUrl=https://iam.hdc.ebrains.eu + -Dkeycloak.frontendUrl=https://iam.hdc.ebrains.eu + + extraVolumes: + - name: antd + persistentVolumeClaim: + claimName: keycloak-antd + - name: theme-cm + configMap: + name: keycloak-antd-theme + + extraVolumeMounts: + - name: antd + mountPath: /opt/bitnami/keycloak/themes/keycloak-antd/ + + initContainers: + - name: download-plugins + image: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-external/alpine:3.21 + imagePullPolicy: IfNotPresent + securityContext: + # Root required to chown downloaded plugins to uid 1001 (keycloak) + runAsUser: 0 + runAsGroup: 0 + allowPrivilegeEscalation: false + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi + volumeMounts: + - mountPath: /opt/bitnami/keycloak/themes/keycloak-antd/ + name: antd + - mountPath: /tmp/theme + name: theme-cm + envFrom: + - secretRef: + name: github-access-token + command: ["/bin/sh", "-c"] + args: + - > + set -e; + THEME_DIR=/opt/bitnami/keycloak/themes/keycloak-antd; + echo "=== Installing theme files ===" && + mkdir -p $THEME_DIR/login/resources/css \ + $THEME_DIR/login/resources/js \ + $THEME_DIR/login/resources/img && + cp /tmp/theme/login.ftl $THEME_DIR/login/ && + cp /tmp/theme/template.ftl $THEME_DIR/login/ && + cp /tmp/theme/theme.properties $THEME_DIR/login/ && + cp /tmp/theme/login.css $THEME_DIR/login/resources/css/ && + cp /tmp/theme/jquery.min.js $THEME_DIR/login/resources/js/ && + cp /tmp/theme/login.js $THEME_DIR/login/resources/js/ && + cp /tmp/theme/error.png /tmp/theme/favicon.ico \ + /tmp/theme/feedback-error-arrow-down.png /tmp/theme/feedback-error-sign.png \ + /tmp/theme/feedback-success-arrow-down.png /tmp/theme/feedback-success-sign.png \ + /tmp/theme/feedback-warning-arrow-down.png /tmp/theme/feedback-warning-sign.png \ + /tmp/theme/HDC-logo.png /tmp/theme/keycloak-bg.png \ + /tmp/theme/keycloak-logo.png /tmp/theme/keycloak-logo-text.png \ + /tmp/theme/lock.png /tmp/theme/user.png \ + $THEME_DIR/login/resources/img/ && + echo "=== Downloading plugins ===" && + apk add --no-cache wget ca-certificates && + mkdir -p $THEME_DIR/plugins && + rm -fv $THEME_DIR/plugins/keycloak-last-login-* $THEME_DIR/plugins/keycloak-auth-require-group-* && + wget --header "Authorization: token $GITHUB_TOKEN" + https://maven.pkg.github.com/PilotDataPlatform/keycloak-extensions/org/indocresearch/pilot/keycloak-last-login/1.0.1/keycloak-last-login-1.0.1.jar + -P $THEME_DIR/plugins && + wget --header "Authorization: token $GITHUB_TOKEN" + https://maven.pkg.github.com/PilotDataPlatform/keycloak-extensions/com/github/thomasdarimont/keycloak/keycloak-auth-require-group/1.0.0/keycloak-auth-require-group-1.0.0.jar + -P $THEME_DIR/plugins && + chown -R 1001:1001 $THEME_DIR + + initdbScripts: + move_plugins.sh: | + #!/bin/bash + echo "Checking plugins folder..." + ls -trl /opt/bitnami/keycloak/themes/keycloak-antd/plugins + echo "Copying plugins to providers..." + cp -r /opt/bitnami/keycloak/themes/keycloak-antd/plugins/* /opt/bitnami/keycloak/providers/ + echo "Done!" + ls -trl /opt/bitnami/keycloak/providers + + ingress: + enabled: true + ingressClassName: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/proxy-buffer-size: "128k" + hostname: iam.hdc.ebrains.eu + pathType: Prefix + path: / + servicePort: http + tls: true + + logging: + level: INFO diff --git a/clusters/prod/apps/kg-integration/Chart.yaml b/clusters/prod/apps/kg-integration/Chart.yaml new file mode 100644 index 0000000..c1ed776 --- /dev/null +++ b/clusters/prod/apps/kg-integration/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: kg-integration +version: 0.1.0 +dependencies: + - name: base-chart + version: "0.1.0" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/kg-integration/application.yaml b/clusters/prod/apps/kg-integration/application.yaml new file mode 100644 index 0000000..3453fb7 --- /dev/null +++ b/clusters/prod/apps/kg-integration/application.yaml @@ -0,0 +1,27 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: kg-integration + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "9" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/kg-integration + helm: + valueFiles: + - ../../registry.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/kg-integration/templates/external-secret.yaml b/clusters/prod/apps/kg-integration/templates/external-secret.yaml new file mode 100644 index 0000000..af6edd7 --- /dev/null +++ b/clusters/prod/apps/kg-integration/templates/external-secret.yaml @@ -0,0 +1,21 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: kg-integration-credentials + namespace: utility +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: kg-integration-credentials + data: + - secretKey: db-password + remoteRef: + key: secret/data/postgresql + property: kg-integration-user-password + - secretKey: account-secret + remoteRef: + key: secret/data/kg-integration + property: account-secret diff --git a/clusters/prod/apps/kg-integration/values.yaml b/clusters/prod/apps/kg-integration/values.yaml new file mode 100644 index 0000000..d7d5f9b --- /dev/null +++ b/clusters/prod/apps/kg-integration/values.yaml @@ -0,0 +1,73 @@ +base-chart: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/kg-integration + tag: "1.3.34" + pullPolicy: IfNotPresent + fullnameOverride: kg-integration + replicaCount: 1 + container: + port: 8000 + service: + type: ClusterIP + port: 8000 + imagePullSecrets: + - name: docker-registry-secret + appConfig: + env: prod + srv_namespace: service_kg + config_center_enabled: "false" + config_center_base_url: "" + port: "8000" + extraEnv: + HOST: "0.0.0.0" + PORT: "8000" + SRV_NAMESPACE: "utility" + # Database + RDS_SCHEMA_DEFAULT: "kg_integration" + RDS_DB: "kg_integration" + RDS_HOST: "postgres.utility" + RDS_USER: "kg_integration_user" + RDS_PORT: "5432" + KG_ENV: "prod" + KG_PREFIX: "collab-" + KG_SERVICE_ACCOUNT_ID: "hdcclient-kg" + # Collaboratory + COLLAB_ENV: "prod" + COLLAB_PREFIX: "hdc-" + # Keycloak + KEYCLOAK_URL: "http://keycloak.keycloak/auth/" + KEYCLOAK_REALM: "hdc" + KEYCLOAK_BROKER: "ebrains-keycloak" + # Deployed services + AUTH_SERVICE: "http://auth.utility:5061" + DATASET_SERVICE: "http://dataset.utility:5081" + PROJECT_SERVICE: "http://project.utility:5064" + # Kafka + KAFKA_URL: "kafka-headless.utility:9092" + # Telemetry + OPEN_TELEMETRY_ENABLED: "false" + extraEnvYaml: + - name: RDS_PASSWORD + valueFrom: + secretKeyRef: + name: kg-integration-credentials + key: db-password + - name: KG_SERVICE_ACCOUNT_SECRET + valueFrom: + secretKeyRef: + name: kg-integration-credentials + key: account-secret + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 500m + memory: 500Mi + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + tcpSocket: + port: 8000 diff --git a/clusters/prod/apps/kong-postgresql/Chart.yaml b/clusters/prod/apps/kong-postgresql/Chart.yaml new file mode 100644 index 0000000..6336bd8 --- /dev/null +++ b/clusters/prod/apps/kong-postgresql/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: kong-postgresql +version: 0.1.0 +dependencies: + - name: postgresql + version: "15.5.17" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/kong-postgresql/application.yaml b/clusters/prod/apps/kong-postgresql/application.yaml new file mode 100644 index 0000000..59bbe24 --- /dev/null +++ b/clusters/prod/apps/kong-postgresql/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: kong-postgresql + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" + # NO finalizer — StatefulSet with PVC +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/kong-postgresql + helm: + valueFiles: + - ../../registry.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/kong-postgresql/templates/external-secret.yaml b/clusters/prod/apps/kong-postgresql/templates/external-secret.yaml new file mode 100644 index 0000000..413ccf4 --- /dev/null +++ b/clusters/prod/apps/kong-postgresql/templates/external-secret.yaml @@ -0,0 +1,21 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: kong-postgresql-credentials + namespace: utility +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: kong-postgresql-credentials + data: + - secretKey: password + remoteRef: + key: secret/data/kong + property: postgresql-password + - secretKey: postgres-password + remoteRef: + key: secret/data/kong + property: postgres-password diff --git a/clusters/prod/apps/kong-postgresql/values.yaml b/clusters/prod/apps/kong-postgresql/values.yaml new file mode 100644 index 0000000..79c1854 --- /dev/null +++ b/clusters/prod/apps/kong-postgresql/values.yaml @@ -0,0 +1,40 @@ +postgresql: + fullnameOverride: kong-postgresql + + global: + imagePullSecrets: + - docker-registry-secret + postgresql: + auth: + database: kong + username: kong + existingSecret: kong-postgresql-credentials + secretKeys: + adminPasswordKey: postgres-password + userPasswordKey: password + + image: + repository: hdc-services-external/bitnami/postgresql + + architecture: standalone + + primary: + pgHbaConfiguration: |- + local all all trust + host all all 127.0.0.1/32 trust + host all all ::1/128 trust + host all all 0.0.0.0/0 md5 + host all all ::/0 md5 + extendedConfiguration: |- + password_encryption = md5 + persistence: + size: 5Gi + storageClass: "csi-cinder-high-speed" + + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 10m + memory: 64Mi diff --git a/clusters/prod/apps/kong/Chart.yaml b/clusters/prod/apps/kong/Chart.yaml new file mode 100644 index 0000000..0b6f2bc --- /dev/null +++ b/clusters/prod/apps/kong/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: kong +version: 0.1.0 +dependencies: + - name: kong + version: "9.1.8" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/kong/application.yaml b/clusters/prod/apps/kong/application.yaml new file mode 100644 index 0000000..ed853ea --- /dev/null +++ b/clusters/prod/apps/kong/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: kong + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "9" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/kong + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/kong/values.yaml b/clusters/prod/apps/kong/values.yaml new file mode 100644 index 0000000..de87baf --- /dev/null +++ b/clusters/prod/apps/kong/values.yaml @@ -0,0 +1,76 @@ +kong: + migration: + annotations: + helm.sh/hook: post-install, pre-upgrade + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + # Chart bug: postgresql.external.database not mapped to KONG_PG_DATABASE + extraEnvVars: + - name: KONG_PG_DATABASE + value: "kong" + + global: + imagePullSecrets: + - docker-registry-secret + + image: + repository: hdc-services-external/kong-with-oidc + pullPolicy: IfNotPresent + debug: false + + database: postgresql + replicaCount: 1 + + # Disable bundled PostgreSQL — using external kong-postgresql app (wave 8) + postgresql: + enabled: false + external: + host: kong-postgresql + port: 5432 + user: kong + database: kong + existingSecret: kong-postgresql-credentials + existingSecretPasswordKey: password + + ingress: + enabled: true + hostname: api.hdc.ebrains.eu + path: / + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + kubernetes.io/ingress.class: nginx + nginx.ingress.kubernetes.io/affinity: cookie + nginx.ingress.kubernetes.io/proxy-body-size: 20m + nginx.ingress.kubernetes.io/proxy-buffer-size: 512k + nginx.ingress.kubernetes.io/proxy-buffering: "on" + nginx.ingress.kubernetes.io/proxy-buffers-number: "8" + nginx.ingress.kubernetes.io/proxy-connect-timeout: 180s + nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "0" + nginx.ingress.kubernetes.io/proxy-read-timeout: 180s + nginx.ingress.kubernetes.io/proxy-send-timeout: 180s + tls: true + + ingressController: + enabled: false + + kong: + extraEnvVars: + - name: KONG_LOG_LEVEL + value: "info" + - name: KONG_PLUGINS + value: "bundled,oidc" + - name: KONG_LUA_SSL_TRUSTED_CERTIFICATE + value: "/etc/ssl/certs/ca-certificates.crt" + # Chart bug: postgresql.external.database not mapped to KONG_PG_DATABASE + - name: KONG_PG_DATABASE + value: "kong" + + service: + exposeAdmin: true + + resources: + requests: + memory: "256Mi" + cpu: "100m" + limits: + memory: "512Mi" + cpu: "500m" diff --git a/clusters/prod/apps/metadata-event-handler/Chart.yaml b/clusters/prod/apps/metadata-event-handler/Chart.yaml new file mode 100644 index 0000000..99519fb --- /dev/null +++ b/clusters/prod/apps/metadata-event-handler/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: metadata-event-handler +version: 0.1.0 +dependencies: + - name: metadata-event-handler + version: "0.1.1" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/metadata-event-handler/application.yaml b/clusters/prod/apps/metadata-event-handler/application.yaml new file mode 100644 index 0000000..a48961c --- /dev/null +++ b/clusters/prod/apps/metadata-event-handler/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: metadata-event-handler + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "9" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/metadata-event-handler + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/metadata-event-handler/values.yaml b/clusters/prod/apps/metadata-event-handler/values.yaml new file mode 100644 index 0000000..e7d9904 --- /dev/null +++ b/clusters/prod/apps/metadata-event-handler/values.yaml @@ -0,0 +1,57 @@ +metadata-event-handler: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/metadata_event_handler + pullPolicy: IfNotPresent + + fullnameOverride: metadata-event-handler + replicaCount: 1 + + container: + port: 5069 + + service: + type: ClusterIP + port: 5069 + targetPort: 5069 + + imagePullSecrets: + - name: docker-registry-secret + + # appConfig: only KAFKA_SERVICE and ELASTICSEARCH_SERVICE are rendered by the chart template + appConfig: + KAFKA_SERVICE: "kafka.utility:9092" + ELASTICSEARCH_SERVICE: "http://elasticsearch-master.utility:9200" + + extraEnv: + KAFKA_TOPICS: '["metadata.items", "metadata.items.activity", "dataset.activity"]' + METADATA_SERVICE: "http://metadata.utility:5066" + PROJECT_SERVICE: "http://project.utility:5064" + APP_NAME: "metadata-event-handler" + VERSION: "1.0.0" + HOST: "0.0.0.0" + PORT: "5069" + WORKERS: "1" + + resources: + limits: + cpu: "1" + memory: 100Mi + requests: + cpu: 10m + memory: 10Mi + + livenessProbe: + failureThreshold: 3 + httpGet: + path: /v1/health/ + port: 5069 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 3 + + updateStrategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 33% + type: RollingUpdate diff --git a/clusters/prod/apps/metadata/Chart.yaml b/clusters/prod/apps/metadata/Chart.yaml new file mode 100644 index 0000000..dc72443 --- /dev/null +++ b/clusters/prod/apps/metadata/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: metadata +version: 0.1.0 +dependencies: + - name: metadata-service + version: "1.0.0" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/metadata/application.yaml b/clusters/prod/apps/metadata/application.yaml new file mode 100644 index 0000000..d1a7ac0 --- /dev/null +++ b/clusters/prod/apps/metadata/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: metadata + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/metadata + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/metadata/templates/external-secret.yaml b/clusters/prod/apps/metadata/templates/external-secret.yaml new file mode 100644 index 0000000..46b7832 --- /dev/null +++ b/clusters/prod/apps/metadata/templates/external-secret.yaml @@ -0,0 +1,17 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: metadata-credentials + namespace: utility +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: metadata-credentials + data: + - secretKey: metadata-user-password + remoteRef: + key: secret/data/postgresql + property: metadata-user-password diff --git a/clusters/prod/apps/metadata/values.yaml b/clusters/prod/apps/metadata/values.yaml new file mode 100644 index 0000000..9c980fb --- /dev/null +++ b/clusters/prod/apps/metadata/values.yaml @@ -0,0 +1,75 @@ +metadata-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/metadata + pullPolicy: IfNotPresent + + fullnameOverride: metadata + replicaCount: 1 + + container: + port: 5066 + + service: + type: ClusterIP + port: 5066 + targetPort: 5066 + + imagePullSecrets: + - name: docker-registry-secret + + appConfig: + port: 5066 + env: prod + srv_namespace: metadata + config_center_enabled: false + METADATA_SCHEMA: metadata + OPSDB_UTILITY_HOST: postgres.utility + OPSDB_UTILITY_PORT: "5432" + OPSDB_UTILITY_USERNAME: metadata_user + DCM_PROJECT_ID: generate_id + RUN_MIGRATIONS: "true" + AUTH_HOST: "http://auth.utility:5061" + KAFKA_URL: "kafka.utility:9092" + KAFKA_TOPIC: "metadata.items" + + extraEnv: + RSA_PUBLIC_KEY: "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFvQkNRQUpRbnpDK1UwN2h3NGliYWNLaWNMbWtTOFR0Mmp6MkFIcVFhWG1sOWUzeCsrZzh5TCtOaDNJSDAzLzdUV2xnbEFSNWRDcEU2cS9LaVpKS1dxU3RCcnlmOHk1UEhaUTJua1YxWXViajRPSThzMklKRFgyNU9XaUNvZFFDRkNwTkNyY1ZmSGpjbnJvRy9icGJoTTBBZ0RFc054UDlpd3NrZ2h3RVFGTDVuc1JWWkpyUEJ0T0dNRWJ4N0xNY3kyeFI2YmlySWFYTmNWSUlyd1g4MVB5bzZENlZRRzlkNkJSUmwvWlVDNGZ5SzZpNGxKUVJvUUV0SW0xNm9PNUFsUGpzYloxd0NXVStlazJJek9aNGRrRnhtUWlwdUpsbjI5TE1jZGdCMlFGZFRNcXBQTXlxWXc3ZmplWmhOL3FoZDFKbUVEeUZOVHVKcEt5Ymd2Y2VnNXdJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0t" + + extraEnvYaml: + - name: OPSDB_UTILITY_PASSWORD + valueFrom: + secretKeyRef: + name: metadata-credentials + key: metadata-user-password + + resources: + limits: + cpu: "1" + memory: 500Mi + requests: + cpu: 10m + memory: 50Mi + + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + tcpSocket: + port: 5066 + + livenessProbe: + failureThreshold: 3 + httpGet: + path: /v1/health + port: 5066 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 3 + + updateStrategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 33% + type: RollingUpdate diff --git a/clusters/prod/apps/notification/Chart.yaml b/clusters/prod/apps/notification/Chart.yaml new file mode 100644 index 0000000..8dd8fef --- /dev/null +++ b/clusters/prod/apps/notification/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: notification +version: 0.1.0 +dependencies: + - name: notification-service + version: "0.3.2" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/notification/application.yaml b/clusters/prod/apps/notification/application.yaml new file mode 100644 index 0000000..447ba05 --- /dev/null +++ b/clusters/prod/apps/notification/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: notification + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/notification + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/notification/templates/external-secret.yaml b/clusters/prod/apps/notification/templates/external-secret.yaml new file mode 100644 index 0000000..c960f52 --- /dev/null +++ b/clusters/prod/apps/notification/templates/external-secret.yaml @@ -0,0 +1,17 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: notification-credentials + namespace: utility +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: notification-credentials + data: + - secretKey: notification-user-password + remoteRef: + key: secret/data/postgresql + property: notification-user-password diff --git a/clusters/prod/apps/notification/values.yaml b/clusters/prod/apps/notification/values.yaml new file mode 100644 index 0000000..d938aac --- /dev/null +++ b/clusters/prod/apps/notification/values.yaml @@ -0,0 +1,78 @@ +notification-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/notification + pullPolicy: IfNotPresent + # tag 2.2.10 from versions.yaml + # chart prefixes: notification-{tag} (main), alembic-{tag} (init) + + fullnameOverride: notification + replicaCount: 1 + + container: + port: 5065 + + service: + type: ClusterIP + port: 5065 + targetPort: 5065 + + imagePullSecrets: + - name: docker-registry-secret + + # appConfig: only the 5 vars the chart template renders explicitly + appConfig: + port: 5065 + env: prod + config_center_enabled: "false" + config_center_base_url: "http://common.utility:5062/" + srv_namespace: service_notification + + # All other config via extraEnv (applied to BOTH init + main containers) + extraEnv: + # App + HOST: "0.0.0.0" + WORKERS: "2" + PLATFORM_NAME: PILOT + namespace: utility + OPEN_TELEMETRY_ENABLED: "false" + POSTFIX: TODO-PROD-SMTP-RELAY # TODO: replace with prod SMTP relay + SMTP_PORT: "25" + SMTP_USER: "" + SMTP_PASS: "" + EMAIL_ATTACHMENT_MAX_SIZE_BYTES: "2097152" + # Database + RDS_HOST: postgres.utility + RDS_PORT: "5432" + RDS_USER: notification_user + RDS_DB_NAME: notifications + + # Secret env vars (applied to BOTH init + main containers) + extraEnvYaml: + - name: RDS_PWD + valueFrom: + secretKeyRef: + name: notification-credentials + key: notification-user-password + + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 500m + memory: 500Mi + + readinessProbe: + tcpSocket: + port: 5065 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + + livenessProbe: + httpGet: + path: /v1/health + port: 5065 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 3 diff --git a/clusters/prod/apps/pipelinewatch/Chart.yaml b/clusters/prod/apps/pipelinewatch/Chart.yaml new file mode 100644 index 0000000..f18fb1a --- /dev/null +++ b/clusters/prod/apps/pipelinewatch/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: pipelinewatch +version: 0.1.0 +dependencies: + - name: pipelinewatch-service + version: "0.4.2" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/pipelinewatch/application.yaml b/clusters/prod/apps/pipelinewatch/application.yaml new file mode 100644 index 0000000..3e3b943 --- /dev/null +++ b/clusters/prod/apps/pipelinewatch/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: pipelinewatch + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/pipelinewatch + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: greenroom + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/pipelinewatch/templates/rbac.yaml b/clusters/prod/apps/pipelinewatch/templates/rbac.yaml new file mode 100644 index 0000000..61cd432 --- /dev/null +++ b/clusters/prod/apps/pipelinewatch/templates/rbac.yaml @@ -0,0 +1,21 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: pipelinewatch-job-watcher +rules: + - apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get", "list", "watch", "delete"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: pipelinewatch-job-watcher +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: pipelinewatch-job-watcher +subjects: + - kind: ServiceAccount + name: pipelinewatch + namespace: greenroom diff --git a/clusters/prod/apps/pipelinewatch/values.yaml b/clusters/prod/apps/pipelinewatch/values.yaml new file mode 100644 index 0000000..9606c3c --- /dev/null +++ b/clusters/prod/apps/pipelinewatch/values.yaml @@ -0,0 +1,46 @@ +pipelinewatch-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/pipelinewatch + pullPolicy: IfNotPresent + + fullnameOverride: pipelinewatch-k8s-job + replicaCount: 1 + + container: + port: 6063 + command: /app/worker_k8s_job_watch.py + + service: + type: ClusterIP + port: 6063 + targetPort: 6063 + + imagePullSecrets: + - name: docker-registry-secret + + serviceAccount: + create: true + name: pipelinewatch + + appConfig: + env: prod + config_center_enabled: "false" + + extraEnv: + GR_ZONE_LABEL: "Greenroom" + CORE_ZONE_LABEL: "Core" + METADATA_SERVICE: "http://metadata.utility:5066" + DATAOPS_SERVICE: "http://dataops.utility:5063" + + volumes: + name: nfsvol + mountPath: /data/core-storage + claimName: greenroom-storage + + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 1 + memory: 1000Mi diff --git a/clusters/prod/apps/project/Chart.yaml b/clusters/prod/apps/project/Chart.yaml new file mode 100644 index 0000000..d3fff92 --- /dev/null +++ b/clusters/prod/apps/project/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: project +version: 0.1.0 +dependencies: + - name: project-service + version: "0.2.1" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/project/application.yaml b/clusters/prod/apps/project/application.yaml new file mode 100644 index 0000000..b622b7a --- /dev/null +++ b/clusters/prod/apps/project/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: project + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/project + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/project/templates/external-secret.yaml b/clusters/prod/apps/project/templates/external-secret.yaml new file mode 100644 index 0000000..faf5e08 --- /dev/null +++ b/clusters/prod/apps/project/templates/external-secret.yaml @@ -0,0 +1,25 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: project-credentials + namespace: utility +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: project-credentials + data: + - secretKey: project-user-password + remoteRef: + key: secret/data/postgresql + property: project-user-password + - secretKey: minio-access-key + remoteRef: + key: secret/data/minio + property: access_key + - secretKey: minio-secret-key + remoteRef: + key: secret/data/minio + property: secret_key diff --git a/clusters/prod/apps/project/values.yaml b/clusters/prod/apps/project/values.yaml new file mode 100644 index 0000000..31e42b4 --- /dev/null +++ b/clusters/prod/apps/project/values.yaml @@ -0,0 +1,102 @@ +project-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/project + pullPolicy: IfNotPresent + + fullnameOverride: project + replicaCount: 1 + + container: + port: 5064 + + service: + type: ClusterIP + port: 5064 + + imagePullSecrets: + - name: docker-registry-secret + + appConfig: + port: 5064 + env: prod + srv_namespace: service_project + config_center_enabled: false + config_center_base_url: http://common.utility:5062/ + + extraEnv: + APP_NAME: "project" + HOST: "0.0.0.0" + PORT: "5064" + WORKERS: "1" + RDS_DB_HOST: postgres.utility + RDS_DB_PORT: "5432" + RDS_DB_USERNAME: project_user + RDS_DB_NAME: project + RDS_ECHO_SQL_QUERIES: "false" + DCM_PROJECT_ID: generate_id + RUN_MIGRATIONS: "true" + AUTH_SERVICE: "http://auth.utility:5061" + METADATA_SERVICE: "http://metadata.utility:5066" + S3_HOST: minio.minio + S3_PORT: "9000" + S3_HTTPS_ENABLED: "false" + S3_GATEWAY_ENABLED: "false" + S3_BUCKET_ENCRYPTION_ENABLED: "false" + S3_BUCKET_FOR_PROJECT_LOGOS: project-logos + S3_PREFIX_FOR_PROJECT_IMAGE_URLS: "https://object.hdc.ebrains.eu/project-logos" + OBJECT_STORAGE_PROVIDER: S3 + OPEN_TELEMETRY_ENABLED: "false" + LOG_LEVEL_DEFAULT: "30" + LOG_LEVEL_STDOUT: "30" + LOG_LEVEL_STDERR: "40" + SERVICE_CLIENT_TIMEOUT: "5" + ICON_SIZE_LIMIT: "16777216" + + extraEnvYaml: + - name: RDS_DB_PASSWORD + valueFrom: + secretKeyRef: + name: project-credentials + key: project-user-password + - name: S3_ACCESS_KEY + valueFrom: + secretKeyRef: + name: project-credentials + key: minio-access-key + - name: S3_SECRET_KEY + valueFrom: + secretKeyRef: + name: project-credentials + key: minio-secret-key + + resources: + limits: + cpu: "1" + memory: 500Mi + requests: + cpu: 10m + memory: 50Mi + + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + tcpSocket: + port: 5064 + + livenessProbe: + failureThreshold: 3 + httpGet: + path: /v1/health/ + port: 5064 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 3 + + updateStrategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 33% + type: RollingUpdate diff --git a/clusters/prod/apps/queue-consumer/Chart.yaml b/clusters/prod/apps/queue-consumer/Chart.yaml new file mode 100644 index 0000000..bc88288 --- /dev/null +++ b/clusters/prod/apps/queue-consumer/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: queue-consumer +version: 0.1.0 +dependencies: + - name: queue-service + version: "0.3.0" # synced from versions.yaml via make sync-versions + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/queue-consumer/application.yaml b/clusters/prod/apps/queue-consumer/application.yaml new file mode 100644 index 0000000..93dbb4c --- /dev/null +++ b/clusters/prod/apps/queue-consumer/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: queue-consumer + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/queue-consumer + helm: + valueFiles: + - ../../registry.yaml + # no versions.yaml — image tag is in values.yaml (prefixed per sub-service) + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: greenroom + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/queue-consumer/templates/external-secret.yaml b/clusters/prod/apps/queue-consumer/templates/external-secret.yaml new file mode 100644 index 0000000..4a26c84 --- /dev/null +++ b/clusters/prod/apps/queue-consumer/templates/external-secret.yaml @@ -0,0 +1,33 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: queue-consumer-credentials + namespace: greenroom +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: queue-consumer-credentials + data: + - secretKey: rabbitmq-username + remoteRef: + key: secret/data/rabbitmq + property: username + - secretKey: rabbitmq-password + remoteRef: + key: secret/data/rabbitmq + property: password + - secretKey: redis-password + remoteRef: + key: secret/data/redis + property: password + - secretKey: minio-access-key + remoteRef: + key: secret/data/minio + property: access_key + - secretKey: minio-secret-key + remoteRef: + key: secret/data/minio + property: secret_key diff --git a/clusters/prod/apps/queue-consumer/templates/rbac.yaml b/clusters/prod/apps/queue-consumer/templates/rbac.yaml new file mode 100644 index 0000000..365f768 --- /dev/null +++ b/clusters/prod/apps/queue-consumer/templates/rbac.yaml @@ -0,0 +1,23 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: queue-consumer-job-creator + namespace: greenroom +rules: + - apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: queue-consumer-job-creator + namespace: greenroom +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: queue-consumer-job-creator +subjects: + - kind: ServiceAccount + name: queue-consumer + namespace: greenroom diff --git a/clusters/prod/apps/queue-consumer/values.yaml b/clusters/prod/apps/queue-consumer/values.yaml new file mode 100644 index 0000000..147098d --- /dev/null +++ b/clusters/prod/apps/queue-consumer/values.yaml @@ -0,0 +1,104 @@ +queue-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/queue/consumer + pullPolicy: IfNotPresent + tag: "consumer-2.2.16" # prefixed tag — NOT from versions.yaml + fullnameOverride: queue-consumer + replicaCount: 1 + container: + port: 6060 + service: + type: ClusterIP + port: 6060 + targetPort: 6060 + imagePullSecrets: + - name: docker-registry-secret + serviceAccount: + create: true + name: queue-consumer + appConfig: + env: prod + config_center_enabled: "false" + config_center_base_url: "" + extraEnv: + # -- Pipeline config -- + bids_validate_pipeline: "bids_validate" + copy_pipeline: "data_transfer" + copy_pipeline_folder: "data_transfer_folder" + move_pipeline: "data_delete" + move_pipeline_folder: "data_delete_folder" + # -- Pipeline images (OVH registry) -- + bids_validate_image: "n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/pipelines/bids-validator:bids-validator-2.2.15" + data_transfer_image: "n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/pipelines/filecopy:filecopy-2.2.16" + # -- Storage (pass-through to spawned Jobs — consumer doesn't touch FS itself) -- + data_lake: "/data/core-storage" + claim_name: "greenroom-storage" + NFS_MOUNT: "nfsvol" + # -- Zone labels -- + GREEN_ZONE_LABEL: "Greenroom" + CORE_ZONE_LABEL: "Core" + # -- Database (pass-through to spawned Jobs — consumer has NO DB driver) -- + RDS_DBNAME: "approval" + RDS_HOST: "postgres.utility" + RDS_PORT: "5432" + # -- S3 / MinIO -- + S3_HOST: "minio.minio" + S3_PORT: "9000" + S3_INTERNAL_HTTPS: "false" + # -- RabbitMQ -- + gm_queue_endpoint: "message-bus-greenroom.greenroom" + # -- Queue config -- + gr_queue: "gr_queue" + gr_exchange: "gr_exchange" + # -- Inter-service URLs -- + DATAOPS_SERVICE: "http://dataops.utility:5063" + DATASET_SERVICE: "http://dataset.utility:5081" + QUEUE_SERVICE: "http://queue-producer.greenroom:6060" + METADATA_SERVICE: "http://metadata.utility:5066" + PROJECT_SERVICE: "http://project.utility:5064" + APPROVAL_SERVICE: "http://approval.utility:8000" + NOTIFICATION_SERVICE: "http://notification.utility:5065" + KAFKA_URL: "kafka.utility:9092" + REDIS_HOST: "redis-master.redis" + REDIS_PORT: "6379" + ATLAS_HOST: "atlas.utility" + ATLAS_PORT: "21000" + # Secrets — all pass-through to spawned Jobs (consumer itself uses none except RabbitMQ creds) + extraEnvYaml: + - name: gm_username + valueFrom: + secretKeyRef: + name: queue-consumer-credentials + key: rabbitmq-username + - name: gm_password + valueFrom: + secretKeyRef: + name: queue-consumer-credentials + key: rabbitmq-password + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: queue-consumer-credentials + key: redis-password + - name: S3_ACCESS_KEY + valueFrom: + secretKeyRef: + name: queue-consumer-credentials + key: minio-access-key + - name: S3_SECRET_KEY + valueFrom: + secretKeyRef: + name: queue-consumer-credentials + key: minio-secret-key + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 1 + memory: 1000Mi + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: "33%" diff --git a/clusters/prod/apps/queue-producer/Chart.yaml b/clusters/prod/apps/queue-producer/Chart.yaml new file mode 100644 index 0000000..fd222d1 --- /dev/null +++ b/clusters/prod/apps/queue-producer/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: queue-producer +version: 0.1.0 +dependencies: + - name: queue-service + version: "0.3.0" # synced from versions.yaml via make sync-versions + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/queue-producer/application.yaml b/clusters/prod/apps/queue-producer/application.yaml new file mode 100644 index 0000000..96ce9dd --- /dev/null +++ b/clusters/prod/apps/queue-producer/application.yaml @@ -0,0 +1,27 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: queue-producer + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/queue-producer + helm: + valueFiles: + - ../../registry.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: greenroom + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/queue-producer/templates/external-secret.yaml b/clusters/prod/apps/queue-producer/templates/external-secret.yaml new file mode 100644 index 0000000..cb6cb15 --- /dev/null +++ b/clusters/prod/apps/queue-producer/templates/external-secret.yaml @@ -0,0 +1,21 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: queue-producer-credentials + namespace: greenroom +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: queue-producer-credentials + data: + - secretKey: rabbitmq-username + remoteRef: + key: secret/data/rabbitmq + property: username + - secretKey: rabbitmq-password + remoteRef: + key: secret/data/rabbitmq + property: password diff --git a/clusters/prod/apps/queue-producer/values.yaml b/clusters/prod/apps/queue-producer/values.yaml new file mode 100644 index 0000000..8d134e3 --- /dev/null +++ b/clusters/prod/apps/queue-producer/values.yaml @@ -0,0 +1,57 @@ +queue-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/queue/producer + pullPolicy: IfNotPresent + tag: "producer-2.2.16" + fullnameOverride: queue-producer + replicaCount: 1 + container: + port: 6060 + service: + type: ClusterIP + port: 6060 + targetPort: 6060 + imagePullSecrets: + - name: docker-registry-secret + appConfig: + env: prod + config_center_enabled: "false" + config_center_base_url: "" + extraEnv: + copy_pipeline: "data_transfer" + data_storage: "/core-data" + gr_queue: "gr_queue" + gr_exchange: "gr_exchange" + LOG_PATH: "/tmp/logs" + move_pipeline: "data_delete" + WORK_PATH: "/tmp/workdir" + # -- RabbitMQ -- + gm_queue_endpoint: "message-bus-greenroom.greenroom" + extraEnvYaml: + - name: gm_username + valueFrom: + secretKeyRef: + name: queue-producer-credentials + key: rabbitmq-username + - name: gm_password + valueFrom: + secretKeyRef: + name: queue-producer-credentials + key: rabbitmq-password + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 1 + memory: 1000Mi + readinessProbe: + tcpSocket: + port: 6060 + initialDelaySeconds: 5 + periodSeconds: 10 + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: "33%" diff --git a/clusters/prod/apps/queue-socketio/Chart.yaml b/clusters/prod/apps/queue-socketio/Chart.yaml new file mode 100644 index 0000000..a4965b1 --- /dev/null +++ b/clusters/prod/apps/queue-socketio/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: queue-socketio +version: 0.1.0 +dependencies: + - name: queue-service + version: "0.4.1" # synced from versions.yaml (queue-service-socketio) via make sync-versions + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/queue-socketio/application.yaml b/clusters/prod/apps/queue-socketio/application.yaml new file mode 100644 index 0000000..5589084 --- /dev/null +++ b/clusters/prod/apps/queue-socketio/application.yaml @@ -0,0 +1,27 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: queue-socketio + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/queue-socketio + helm: + valueFiles: + - ../../registry.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: greenroom + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/queue-socketio/templates/external-secret.yaml b/clusters/prod/apps/queue-socketio/templates/external-secret.yaml new file mode 100644 index 0000000..f920b68 --- /dev/null +++ b/clusters/prod/apps/queue-socketio/templates/external-secret.yaml @@ -0,0 +1,21 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: queue-socketio-credentials + namespace: greenroom +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: queue-socketio-credentials + data: + - secretKey: rabbitmq-username + remoteRef: + key: secret/data/rabbitmq + property: username + - secretKey: rabbitmq-password + remoteRef: + key: secret/data/rabbitmq + property: password diff --git a/clusters/prod/apps/queue-socketio/values.yaml b/clusters/prod/apps/queue-socketio/values.yaml new file mode 100644 index 0000000..023d43e --- /dev/null +++ b/clusters/prod/apps/queue-socketio/values.yaml @@ -0,0 +1,64 @@ +queue-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/queue/socketio + pullPolicy: IfNotPresent + tag: "socketio-2.2.16" + fullnameOverride: queue-socketio + replicaCount: 1 + container: + port: 6062 + service: + type: ClusterIP + port: 6062 + targetPort: 6062 + imagePullSecrets: + - name: docker-registry-secret + appConfig: + env: prod + config_center_enabled: "false" + config_center_base_url: "" + extraEnv: + # -- RabbitMQ -- + gm_queue_endpoint: "message-bus-greenroom.greenroom" + extraEnvYaml: + - name: gm_username + valueFrom: + secretKeyRef: + name: queue-socketio-credentials + key: rabbitmq-username + - name: gm_password + valueFrom: + secretKeyRef: + name: queue-socketio-credentials + key: rabbitmq-password + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 1 + memory: 1000Mi + readinessProbe: + tcpSocket: + port: 6062 + initialDelaySeconds: 5 + periodSeconds: 10 + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: "33%" + ingress: + enabled: true + hostname: hdc.ebrains.eu + path: /socket.io/ + pathType: ImplementationSpecific + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + kubernetes.io/ingress.class: nginx + nginx.ingress.kubernetes.io/proxy-body-size: 25m + nginx.ingress.kubernetes.io/ssl-redirect: "true" + # WebSocket support + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + tls: true diff --git a/clusters/prod/apps/search/Chart.yaml b/clusters/prod/apps/search/Chart.yaml new file mode 100644 index 0000000..52abf81 --- /dev/null +++ b/clusters/prod/apps/search/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: search +version: 0.1.0 +dependencies: + - name: search-service + version: "0.2.2" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/search/application.yaml b/clusters/prod/apps/search/application.yaml new file mode 100644 index 0000000..82c3578 --- /dev/null +++ b/clusters/prod/apps/search/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: search + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/search + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/search/values.yaml b/clusters/prod/apps/search/values.yaml new file mode 100644 index 0000000..7321ad1 --- /dev/null +++ b/clusters/prod/apps/search/values.yaml @@ -0,0 +1,47 @@ +search-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/search + pullPolicy: IfNotPresent + + fullnameOverride: search + replicaCount: 1 + + container: + port: 5064 + + service: + type: ClusterIP + port: 5064 + targetPort: 5064 + + imagePullSecrets: + - name: docker-registry-secret + + appConfig: + env: prod + port: 5064 + config_center_enabled: false + config_center_base_url: http://common.utility:5062/ + srv_namespace: service_search + + extraEnv: + HOST: "0.0.0.0" + PORT: "5064" + ELASTICSEARCH_URI: "http://elasticsearch-master.utility:9200" + WORKSERS: "2" + + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 500m + memory: 500Mi + + readinessProbe: + tcpSocket: + port: 5064 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + successThreshold: 1 diff --git a/clusters/prod/apps/upload-core/Chart.yaml b/clusters/prod/apps/upload-core/Chart.yaml new file mode 100644 index 0000000..1f2c615 --- /dev/null +++ b/clusters/prod/apps/upload-core/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: upload-core +version: 0.1.0 +dependencies: + - name: upload-service + version: "0.3.1" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/upload-core/application.yaml b/clusters/prod/apps/upload-core/application.yaml new file mode 100644 index 0000000..1c80377 --- /dev/null +++ b/clusters/prod/apps/upload-core/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: upload-core + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/upload-core + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: core + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/upload-core/templates/external-secret.yaml b/clusters/prod/apps/upload-core/templates/external-secret.yaml new file mode 100644 index 0000000..4254aca --- /dev/null +++ b/clusters/prod/apps/upload-core/templates/external-secret.yaml @@ -0,0 +1,25 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: upload-credentials + namespace: core +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: upload-credentials + data: + - secretKey: redis-password + remoteRef: + key: secret/data/redis + property: password + - secretKey: minio-access-key + remoteRef: + key: secret/data/minio + property: access_key + - secretKey: minio-secret-key + remoteRef: + key: secret/data/minio + property: secret_key diff --git a/clusters/prod/apps/upload-core/values.yaml b/clusters/prod/apps/upload-core/values.yaml new file mode 100644 index 0000000..6425753 --- /dev/null +++ b/clusters/prod/apps/upload-core/values.yaml @@ -0,0 +1,96 @@ +upload-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/upload + pullPolicy: IfNotPresent + + + fullnameOverride: upload + replicaCount: 1 + + container: + port: 5079 + + service: + type: ClusterIP + port: 5079 + targetPort: 5079 + + imagePullSecrets: + - name: docker-registry-secret + + appConfig: + port: 5079 + env: prod + + extraEnv: + HOST: "0.0.0.0" + namespace: "core" + ROOT_PATH: "/data/core-storage" + CORE_ZONE_LABEL: "Core" + GREEN_ZONE_LABEL: "Greenroom" + DATAOPS_SERVICE: "http://dataops.utility:5063" + METADATA_SERVICE: "http://metadata.utility:5066" + PROJECT_SERVICE: "http://project.utility:5064" + S3_INTERNAL: "minio.minio:9000" + S3_INTERNAL_HTTPS: "False" + S3_PUBLIC: "object.hdc.ebrains.eu" + S3_PUBLIC_HTTPS: "True" + REDIS_HOST: "redis-master.redis" + REDIS_PORT: "6379" + REDIS_DB: "0" + KAFKA_URL: "kafka.utility:9092" + KAFKA_ACTIVITY_TOPIC: "metadata.items.activity" + OPEN_TELEMETRY_ENABLED: "False" + OPEN_TELEMETRY_HOST: "127.0.0.1" + OPEN_TELEMETRY_PORT: "6831" + + extraEnvYaml: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: upload-credentials + key: redis-password + - name: S3_ACCESS_KEY + valueFrom: + secretKeyRef: + name: upload-credentials + key: minio-access-key + - name: S3_SECRET_KEY + valueFrom: + secretKeyRef: + name: upload-credentials + key: minio-secret-key + + # Single object, not array — chart template accesses .Values.volumes.mountPath directly + volumes: + name: upload-storage + mountPath: /data/core-storage + claimName: core-storage + + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 500m + memory: 500Mi + + readinessProbe: + tcpSocket: + port: 5079 + initialDelaySeconds: 5 + periodSeconds: 10 + + livenessProbe: + httpGet: + path: /v1/health + port: 5079 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 3 + + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 diff --git a/clusters/prod/apps/upload-greenroom/Chart.yaml b/clusters/prod/apps/upload-greenroom/Chart.yaml new file mode 100644 index 0000000..410f3b6 --- /dev/null +++ b/clusters/prod/apps/upload-greenroom/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: upload-greenroom +version: 0.1.0 +dependencies: + - name: upload-service + version: "0.3.1" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/upload-greenroom/application.yaml b/clusters/prod/apps/upload-greenroom/application.yaml new file mode 100644 index 0000000..98d186e --- /dev/null +++ b/clusters/prod/apps/upload-greenroom/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: upload-greenroom + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/upload-greenroom + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: greenroom + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/upload-greenroom/templates/external-secret.yaml b/clusters/prod/apps/upload-greenroom/templates/external-secret.yaml new file mode 100644 index 0000000..08e76ef --- /dev/null +++ b/clusters/prod/apps/upload-greenroom/templates/external-secret.yaml @@ -0,0 +1,25 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: upload-credentials + namespace: greenroom +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: upload-credentials + data: + - secretKey: redis-password + remoteRef: + key: secret/data/redis + property: password + - secretKey: minio-access-key + remoteRef: + key: secret/data/minio + property: access_key + - secretKey: minio-secret-key + remoteRef: + key: secret/data/minio + property: secret_key diff --git a/clusters/prod/apps/upload-greenroom/values.yaml b/clusters/prod/apps/upload-greenroom/values.yaml new file mode 100644 index 0000000..67323ab --- /dev/null +++ b/clusters/prod/apps/upload-greenroom/values.yaml @@ -0,0 +1,96 @@ +upload-service: + image: + repository: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/upload + pullPolicy: IfNotPresent + + + fullnameOverride: upload + replicaCount: 1 + + container: + port: 5079 + + service: + type: ClusterIP + port: 5079 + targetPort: 5079 + + imagePullSecrets: + - name: docker-registry-secret + + appConfig: + port: 5079 + env: prod + + extraEnv: + HOST: "0.0.0.0" + namespace: "greenroom" + ROOT_PATH: "/data/greenroom-storage" + CORE_ZONE_LABEL: "Core" + GREEN_ZONE_LABEL: "Greenroom" + DATAOPS_SERVICE: "http://dataops.utility:5063" + METADATA_SERVICE: "http://metadata.utility:5066" + PROJECT_SERVICE: "http://project.utility:5064" + S3_INTERNAL: "minio.minio:9000" + S3_INTERNAL_HTTPS: "False" + S3_PUBLIC: "object.hdc.ebrains.eu" + S3_PUBLIC_HTTPS: "True" + REDIS_HOST: "redis-master.redis" + REDIS_PORT: "6379" + REDIS_DB: "0" + KAFKA_URL: "kafka.utility:9092" + KAFKA_ACTIVITY_TOPIC: "metadata.items.activity" + OPEN_TELEMETRY_ENABLED: "False" + OPEN_TELEMETRY_HOST: "127.0.0.1" + OPEN_TELEMETRY_PORT: "6831" + + extraEnvYaml: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: upload-credentials + key: redis-password + - name: S3_ACCESS_KEY + valueFrom: + secretKeyRef: + name: upload-credentials + key: minio-access-key + - name: S3_SECRET_KEY + valueFrom: + secretKeyRef: + name: upload-credentials + key: minio-secret-key + + # Single object, not array — chart template accesses .Values.volumes.mountPath directly + volumes: + name: upload-storage + mountPath: /data/greenroom-storage + claimName: greenroom-storage + + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 500m + memory: 500Mi + + readinessProbe: + tcpSocket: + port: 5079 + initialDelaySeconds: 5 + periodSeconds: 10 + + livenessProbe: + httpGet: + path: /v1/health + port: 5079 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 3 + + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 diff --git a/clusters/prod/apps/xwiki/Chart.yaml b/clusters/prod/apps/xwiki/Chart.yaml new file mode 100644 index 0000000..40b4c2a --- /dev/null +++ b/clusters/prod/apps/xwiki/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: xwiki +version: 0.1.0 +dependencies: + - name: xwiki + version: "0.3.0" + repository: https://pilotdataplatform.github.io/helm-charts/ diff --git a/clusters/prod/apps/xwiki/application.yaml b/clusters/prod/apps/xwiki/application.yaml new file mode 100644 index 0000000..93e5af3 --- /dev/null +++ b/clusters/prod/apps/xwiki/application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: xwiki + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "8" +spec: + project: default + source: + repoURL: https://github.com/PilotDataPlatform/pilot-hdc-platform-gitops.git + targetRevision: main + path: clusters/prod/apps/xwiki + helm: + valueFiles: + - ../../registry.yaml + - ../../versions.yaml + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: utility + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/clusters/prod/apps/xwiki/templates/external-secret.yaml b/clusters/prod/apps/xwiki/templates/external-secret.yaml new file mode 100644 index 0000000..6288be2 --- /dev/null +++ b/clusters/prod/apps/xwiki/templates/external-secret.yaml @@ -0,0 +1,42 @@ +# Database credentials — target name MUST be "xwiki-postgresql" +# Both the PG sub-chart (via existingSecret) and the XWiki deployment +# (hardcoded -postgresql) read from this Secret +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: xwiki-postgresql + namespace: utility +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: xwiki-postgresql + data: + - secretKey: postgresql-password + remoteRef: + key: secret/data/xwiki + property: postgresql-password +--- +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: xwiki-config + namespace: utility +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + name: xwiki-config + data: + - secretKey: xwiki.cfg + remoteRef: + key: secret/data/xwiki + property: xwiki-cfg + - secretKey: xwiki.properties + remoteRef: + key: secret/data/xwiki + property: xwiki-properties diff --git a/clusters/prod/apps/xwiki/templates/pvc.yaml b/clusters/prod/apps/xwiki/templates/pvc.yaml new file mode 100644 index 0000000..5a7e170 --- /dev/null +++ b/clusters/prod/apps/xwiki/templates/pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: xwiki-data + namespace: utility +spec: + accessModes: + - ReadWriteMany + storageClassName: nfs-client + resources: + requests: + storage: 5Gi diff --git a/clusters/prod/apps/xwiki/values.yaml b/clusters/prod/apps/xwiki/values.yaml new file mode 100644 index 0000000..d537017 --- /dev/null +++ b/clusters/prod/apps/xwiki/values.yaml @@ -0,0 +1,80 @@ +xwiki: + replicaCount: 1 + + overrides: + image: true + + image: + name: n47w5524.c1.de1.container-registry.ovh.net/hdc-services-image/xwiki + pullPolicy: IfNotPresent + + mysql: + enabled: false + + postgresql: + enabled: true + postgresqlUsername: xwiki + postgresqlDatabase: xwiki + existingSecret: xwiki-postgresql + image: + repository: hdc-services-external/bitnami/postgresql + tag: 11.3.0-debian-9-r38 + volumePermissions: + image: + repository: hdc-services-external/bitnami/minideb + tag: stretch + persistence: + storageClass: nfs-client + size: 1Gi + + service: + type: ClusterIP + + ingress: + enabled: true + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/affinity: cookie + nginx.ingress.kubernetes.io/proxy-body-size: 100m + nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + hostname: xwiki.hdc.ebrains.eu + path: / + pathType: Prefix + tls: true + + # Chart-managed PVC (hardcoded name "xwiki", mounts at /opt/solr/server/solr) + # Can't disable — keep small and ignore + storageClass: nfs-client + storage: 1Gi + + solr: + enabled: false + + # Volume name "xwiki-conf" avoids collision with chart built-in volume "xwiki-data" + extraVolumes: + - name: xwiki-config + secret: + secretName: xwiki-config + - name: xwiki-conf + persistentVolumeClaim: + claimName: xwiki-data + + extraVolumeMounts: + - name: xwiki-conf + mountPath: /usr/local/xwiki/data + - name: xwiki-config + mountPath: /usr/local/xwiki/data/xwiki.cfg + subPath: xwiki.cfg + - name: xwiki-config + mountPath: /usr/local/xwiki/data/xwiki.properties + subPath: xwiki.properties + + resources: + requests: + cpu: "1" + memory: 2Gi + limits: + cpu: "2" + memory: 4Gi diff --git a/docs/vault-secrets.md b/docs/vault-secrets.md index 0aaeac1..3fb4332 100644 --- a/docs/vault-secrets.md +++ b/docs/vault-secrets.md @@ -31,7 +31,8 @@ vault kv patch secret/postgresql -user-password=$(openssl rand -hex 24) vault kv put secret/keycloak \ admin-password=$(openssl rand -hex 24) \ postgres-password=$(openssl rand -hex 24) \ - keycloak-user-password=$(openssl rand -hex 24) + keycloak-user-password=$(openssl rand -hex 24) \ + github-token='' ``` ## Redis (`secret/redis`) @@ -76,7 +77,8 @@ vault kv put secret/docker-registry/ovh \ ```bash vault kv put secret/auth \ - keycloak-client-secret='' + keycloak-client-secret='' \ + freeipa-password='' ``` ## Kong (`secret/kong`) @@ -103,6 +105,17 @@ vault kv put secret/download \ download-key=$(openssl rand -hex 32) ``` +## XWiki (`secret/xwiki`) + +```bash +vault kv put secret/xwiki \ + postgresql-password=$(openssl rand -hex 24) \ + xwiki-cfg='' \ + xwiki-properties='' +``` + +The `xwiki-cfg` and `xwiki-properties` values are full file contents mounted into the container. Copy from the running dev instance or from backup. + ## KG Integration (`secret/kg-integration`) ```bash