diff --git a/.github/workflows/e2e-tests.yaml b/.github/workflows/e2e-tests.yaml index 1656cea..232a701 100644 --- a/.github/workflows/e2e-tests.yaml +++ b/.github/workflows/e2e-tests.yaml @@ -94,7 +94,7 @@ jobs: kubectl wait --namespace edc-v \ --for=condition=ready pod \ --selector=type=edcv-infra \ - --timeout=120s + --timeout=300s - name: "Deploy JAD applications" run: |- diff --git a/k8s/apps/dataplane-config.yaml b/k8s/apps/dataplane-config.yaml index 0d45d43..c9e6b43 100644 --- a/k8s/apps/dataplane-config.yaml +++ b/k8s/apps/dataplane-config.yaml @@ -31,7 +31,7 @@ data: web.http.control.path: "/api/control" web.http.public.port: "11002" web.http.public.path: "/api/public" - web.http.certs.port: "8085" + web.http.certs.port: "8186" web.http.certs.path: "/api/data" edc.vault.hashicorp.url: "http://vault.edc-v.svc.cluster.local:8200" diff --git a/k8s/apps/ui-config.yaml b/k8s/apps/ui-config.yaml new file mode 100644 index 0000000..7cba25f --- /dev/null +++ b/k8s/apps/ui-config.yaml @@ -0,0 +1,58 @@ +# +# Copyright (c) 2026 Metaform Systems, Inc. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# +# Contributors: +# Metaform Systems, Inc. - initial API and implementation +# + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: jad-web-ui-config + namespace: edc-v +data: + config.json: | + { + "production": true, + "apiUrl": "http://redline.edc-v.svc.cluster.local:8081", + "appName": "Aruba's DataSpace", + "version": "1.0.0", + "features": { + "enableMockData": false, + "enableAnalytics": true, + "enableDebugMode": false, + "enableDevMode": true + }, + "auth": { + "roles": { + "admin": "EDC_ADMIN", + "participant": "EDC_USER_PARTICIPANT", + "validRoles": ["EDC_ADMIN", "EDC_USER_PARTICIPANT"] + }, + "enableAuth": true, + "tokenKey": "auth_token", + "keycloak": { + "url": "http://keycloak-fe.localhost", + "realm": "jad-ui", + "clientId": "edc-aruba-provisioning-customers-portal-fe", + "initOptions": { + "onLoad": "check-sso", + "checkLoginIframe": false, + "pkceMethod": "S256", + "storageKey": "edc-partipant" + }, + "bearerExcludedUrls": ["/assets"] + } + } + } + + + +# REDLINE_URL: "http://redline.edc-v.svc.cluster.local:8081" diff --git a/k8s/apps/ui.yaml b/k8s/apps/ui.yaml new file mode 100644 index 0000000..bff040d --- /dev/null +++ b/k8s/apps/ui.yaml @@ -0,0 +1,92 @@ +# +# Copyright (c) 2026 Metaform Systems, Inc. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# +# Contributors: +# Metaform Systems, Inc. - initial API and implementation +# + + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: jad-web-ui + namespace: edc-v +spec: + replicas: 1 + selector: + matchLabels: + app: jad-web-ui + template: + metadata: + labels: + app: jad-web-ui + spec: + volumes: + - name: config-volume + configMap: + name: jad-web-ui-config + defaultMode: 420 + containers: + - name: jad-web-ui + image: +# ghcr.io/aruba-it-s-p-a/edc-client-participant-fe:3b202e0bb6c88ddef712686e635e25357852377a + ghcr.io/aruba-it-s-p-a/edc-public-participant-portal:demo-madrid + ports: + - containerPort: 80 + protocol: TCP + env: + - name: HOST_API + value: https://identity.aruba.io + resources: {} + volumeMounts: + - name: config-volume + mountPath: /usr/share/nginx/html/customers/assets/config + imagePullPolicy: Always + +--- +apiVersion: v1 +kind: Service +metadata: + name: jad-web-ui + namespace: edc-v + labels: + app: jad-web-ui +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + app: jad-web-ui + +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: jad-web-ui + namespace: edc-v +spec: + parentRefs: + - name: edcv-gateway + kind: Gateway + sectionName: http + hostnames: + - ui.localhost + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: jad-web-ui + port: 80 + weight: 1 diff --git a/k8s/base/keycloak-fe.yaml b/k8s/base/keycloak-fe.yaml new file mode 100644 index 0000000..5e5e10d --- /dev/null +++ b/k8s/base/keycloak-fe.yaml @@ -0,0 +1,222 @@ +# +# Copyright (c) 2025 Metaform Systems, Inc. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# +# Contributors: +# Metaform Systems, Inc. - initial API and implementation +# + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: keycloak4frontend + namespace: edc-v + labels: + platform: edcv +spec: + replicas: 1 + selector: + matchLabels: + app: keycloak-fe + template: + metadata: + labels: + app: keycloak-fe + platform: edcv + type: edcv-infra + spec: + containers: + - name: keycloak + image: quay.io/keycloak/keycloak:latest + args: + - "start-dev" + - "--health-enabled=true" + - "--import-realm" + ports: + - containerPort: 8080 + name: http + - containerPort: 9000 + name: health + env: + - name: KEYCLOAK_ADMIN + value: "admin" + - name: KC_BOOTSTRAP_ADMIN_USERNAME + value: "admin" + - name: KC_BOOTSTRAP_ADMIN_PASSWORD + value: "admin" + - name: KC_HTTP_ENABLED + value: "true" + - name: KC_HOSTNAME + value: http://keycloak-fe.localhost + - name: KC_HOSTNAME_STRICT + value: "true" + - name: KC_PROXY + value: "edge" + - name: KC_HEALTH_ENABLED + value: "true" + - name: KC_METRICS_ENABLED + value: "true" + - name: KC_LOG_LEVEL + value: INFO + - name: KC_DB + value: postgres + - name: POSTGRES_DB + value: keycloak_fe + - name: KC_DB_URL + value: jdbc:postgresql://postgres.edc-v.svc.cluster.local:5432/keycloak_fe + - name: KC_DB_USERNAME + value: "kc_fe" + - name: KC_DB_PASSWORD + value: "kc_fe" + volumeMounts: + - name: realm-config-ui + mountPath: /opt/keycloak/data/import + readinessProbe: + httpGet: + path: /health/ready + port: 9000 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 12 + livenessProbe: + httpGet: + path: /health/live + port: 9000 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 12 + volumes: + - name: realm-config-ui + configMap: + name: keycloak-realm-ui +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: keycloak-realm-ui + namespace: edc-v + labels: + tier: infrastructure +data: + ## redirectUri and webOrigins "*" are required for public clients, otherwise we'll run into redirect and CORS issues + jad-ui-realm.json: | + { + "realm": "jad-ui", + "enabled": true, + "displayName": "Keycloak Realm for authenticating frontend (UI) users", + "displayNameHtml": "
Keycloak Realm for authenticating frontend (UI) users
", + "clients": [ + { + "clientId": "edc-aruba-provisioning-customers-portal-fe", + "enabled": true, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "http://localhost:4200/*", + "*" + ], + "webOrigins": [ + "http://localhost:4200", + "*" + ], + "protocol": "openid-connect", + "publicClient": true, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "attributes": { + "pkce.code.challenge.method": "S256" + } + } + ], + "roles": { + "realm": [ + { + "name": "EDC_ADMIN", + "description": "Administrator role for EDC portal" + }, + { + "name": "EDC_USER_PARTICIPANT", + "description": "Participant role for EDC users" + } + ] + }, + "users": [ + { + "username": "admin", + "enabled": true, + "email": "admin@example.com", + "firstName": "Admin", + "lastName": "User", + "credentials": [ + { + "type": "password", + "value": "admin123", + "temporary": false + } + ], + "realmRoles": ["EDC_ADMIN"] + }, + { + "username": "user", + "enabled": true, + "email": "user@testcompany.it", + "firstName": "Test", + "lastName": "User", + "credentials": [ + { + "type": "password", + "value": "user123", + "temporary": false + } + ], + "realmRoles": ["EDC_USER_PARTICIPANT"] + } + ] + } + +--- +apiVersion: v1 +kind: Service +metadata: + name: keycloak-fe + namespace: edc-v + labels: + tier: infrastructure +spec: + selector: + app: keycloak-fe + ports: + - port: 8080 + targetPort: 8080 + name: http + +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: keycloak-fe + namespace: edc-v +spec: + parentRefs: + - name: edcv-gateway + kind: Gateway + sectionName: http + hostnames: + - keycloak-fe.localhost + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: keycloak-fe + port: 8080 \ No newline at end of file diff --git a/k8s/base/keycloak.yaml b/k8s/base/keycloak.yaml index 9830d68..093e38f 100644 --- a/k8s/base/keycloak.yaml +++ b/k8s/base/keycloak.yaml @@ -83,17 +83,17 @@ spec: path: /health/ready port: 9000 initialDelaySeconds: 3 - periodSeconds: 5 + periodSeconds: 10 successThreshold: 1 - failureThreshold: 5 + failureThreshold: 12 livenessProbe: httpGet: path: /health/live port: 9000 initialDelaySeconds: 3 - periodSeconds: 5 + periodSeconds: 10 successThreshold: 1 - failureThreshold: 5 + failureThreshold: 12 volumes: - name: realm-config configMap: @@ -287,6 +287,9 @@ spec: - port: 8080 targetPort: 8080 name: http + - port: 9000 + targetPort: 9000 + name: health --- apiVersion: gateway.networking.k8s.io/v1 diff --git a/k8s/base/postgres.yaml b/k8s/base/postgres.yaml index 3b6a719..5e36ee6 100644 --- a/k8s/base/postgres.yaml +++ b/k8s/base/postgres.yaml @@ -95,6 +95,12 @@ data: \c keycloak GRANT ALL ON SCHEMA public TO kc; + CREATE DATABASE keycloak_fe; + CREATE USER kc_fe WITH PASSWORD 'kc_fe'; + GRANT ALL PRIVILEGES ON DATABASE keycloak_fe TO kc_fe; + \c keycloak_fe + GRANT ALL ON SCHEMA public TO kc_fe; + CREATE DATABASE cfm; CREATE USER cfm WITH PASSWORD 'cfm'; GRANT ALL PRIVILEGES ON DATABASE cfm TO cfm; diff --git a/tests/end2end/src/test/java/org/eclipse/edc/jad/tests/DataTransferEndToEndTest.java b/tests/end2end/src/test/java/org/eclipse/edc/jad/tests/DataTransferEndToEndTest.java index b89dc7e..f996e5d 100644 --- a/tests/end2end/src/test/java/org/eclipse/edc/jad/tests/DataTransferEndToEndTest.java +++ b/tests/end2end/src/test/java/org/eclipse/edc/jad/tests/DataTransferEndToEndTest.java @@ -27,6 +27,7 @@ import org.junit.jupiter.api.Test; import java.io.IOException; +import java.time.Instant; import java.util.List; import java.util.Map; @@ -55,6 +56,8 @@ public class DataTransferEndToEndTest { private static final ConsoleMonitor MONITOR = new ConsoleMonitor(ConsoleMonitor.Level.DEBUG, true); private static ClientCredentials providerCredentials; private static ClientCredentials consumerCredentials; + private static String consumerContextId; + private static String providerContextId; static String loadResourceFile(String resourceName) { @@ -79,6 +82,8 @@ static void prepare() { } )); + var slug = Instant.now().getEpochSecond(); + var adminToken = createKeycloakToken("admin", "edc-v-admin-secret", "issuer-admin-api:write", "identity-api:write", "management-api:write", "identity-api:read"); createCelExpression(adminToken); @@ -87,12 +92,16 @@ static void prepare() { // onboard consumer MONITOR.info("Onboarding consumer"); - var po = new ParticipantOnboarding("consumer", "did:web:identityhub.edc-v.svc.cluster.local%3A7083:consumer", VAULT_TOKEN, MONITOR.withPrefix("Consumer")); + var consumerName = "consumer-" + slug; + consumerContextId = "did:web:identityhub.edc-v.svc.cluster.local%3A7083:" + consumerName; + var po = new ParticipantOnboarding(consumerName, consumerContextId, VAULT_TOKEN, MONITOR.withPrefix("Consumer " + slug)); consumerCredentials = po.execute(cellId); // onboard provider MONITOR.info("Onboarding provider"); - var providerPo = new ParticipantOnboarding("provider", "did:web:identityhub.edc-v.svc.cluster.local%3A7083:provider", VAULT_TOKEN, MONITOR.withPrefix("Provider")); + var providerName = "provider-" + slug; + providerContextId = "did:web:identityhub.edc-v.svc.cluster.local%3A7083:" + providerName; + var providerPo = new ParticipantOnboarding(providerName, providerContextId, VAULT_TOKEN, MONITOR.withPrefix("Provider " + slug)); providerCredentials = providerPo.execute(cellId); } @@ -154,10 +163,10 @@ void testTodoDataTransfer() { .auth().oauth2(getAccessToken(consumerCredentials.clientId(), consumerCredentials.clientSecret(), "management-api:write").accessToken()) .body(""" { - "providerId":"did:web:identityhub.edc-v.svc.cluster.local%%3A7083:provider", + "providerId":"%s", "policyId": "%s" } - """.formatted(offerId)) + """.formatted(providerContextId, offerId)) .contentType("application/json") .post("/api/mgmt/v1alpha/participants/%s/data".formatted(consumerCredentials.clientId())) .then() @@ -192,10 +201,10 @@ void testCertDataTransfer() { .auth().oauth2(getAccessToken(consumerCredentials.clientId(), consumerCredentials.clientSecret(), "management-api:write").accessToken()) .body(""" { - "providerId":"did:web:identityhub.edc-v.svc.cluster.local%%3A7083:provider", + "providerId":"%s", "policyId": "%s" } - """.formatted(offerId)) + """.formatted(providerContextId, offerId)) .contentType("application/json") .post("/api/mgmt/v1alpha/participants/%s/transfer".formatted(consumerCredentials.clientId())) .then() @@ -226,9 +235,9 @@ private CatalogResponse fetchCatalog(ClientCredentials consumerCredentials) { .contentType("application/json") .body(""" { - "counterPartyDid": "did:web:identityhub.edc-v.svc.cluster.local%3A7083:provider" + "counterPartyDid": "%s" } - """) + """.formatted(providerContextId)) .post("/api/mgmt/v1alpha/participants/%s/catalog".formatted(consumerCredentials.clientId())) .then() .statusCode(200)