From db242237112f2107849942032f4e6dc94421eab9 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> Date: Thu, 18 Apr 2024 10:34:14 -0300 Subject: [PATCH] KIE-ISSUE #1056 - Introduce an Example to have a custom APISIX Ingress to SonataFlow deployments sec use cases (#1902) --- .../sonataflow-apisix-oidc/README.md | 3 + .../manifests/bases/01-postgres.yaml | 86 +++++++++++++++++ .../manifests/bases/02-keycloak.yaml | 92 +++++++++++++++++++ .../manifests/bases/kustomization.yaml | 37 ++++++++ .../workflow-app/01-sonataflow-greeting.yaml | 58 ++++++++++++ .../workflow-app/02-sonataflow-route.yaml | 40 ++++++++ .../workflow-app/greeting.svg | 1 + .../workflow-app/greeting.sw.yaml | 55 +++++++++++ 8 files changed, 372 insertions(+) create mode 100644 serverless-operator-examples/sonataflow-apisix-oidc/README.md create mode 100644 serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/01-postgres.yaml create mode 100644 serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/02-keycloak.yaml create mode 100644 serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/kustomization.yaml create mode 100644 serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/01-sonataflow-greeting.yaml create mode 100644 serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/02-sonataflow-route.yaml create mode 100644 serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/greeting.svg create mode 100644 serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/greeting.sw.yaml diff --git a/serverless-operator-examples/sonataflow-apisix-oidc/README.md b/serverless-operator-examples/sonataflow-apisix-oidc/README.md new file mode 100644 index 0000000000..57a121bdd1 --- /dev/null +++ b/serverless-operator-examples/sonataflow-apisix-oidc/README.md @@ -0,0 +1,3 @@ +# SonataFlow Authentication and Authorization with Keycloak and APISIX + +This is an example directory to support the guide outlined here: [https://sonataflow.org/serverlessworkflow/latest/cloud/custom-ingress-authz.html](https://sonataflow.org/serverlessworkflow/latest/cloud/custom-ingress-authz.html). Please read it in order to fully understand how to use this example. diff --git a/serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/01-postgres.yaml b/serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/01-postgres.yaml new file mode 100644 index 0000000000..0de874326a --- /dev/null +++ b/serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/01-postgres.yaml @@ -0,0 +1,86 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + app.kubernetes.io/name: postgres + name: postgres-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: postgres + name: postgres +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: postgres + template: + metadata: + labels: + app.kubernetes.io/name: postgres + spec: + containers: + - name: postgres + image: postgres + imagePullPolicy: "IfNotPresent" + ports: + - containerPort: 5432 + volumeMounts: + - name: storage + mountPath: /var/lib/pgsql/data + envFrom: + - secretRef: + name: postgres-secrets + readinessProbe: + exec: + command: ["pg_isready"] + initialDelaySeconds: 15 + timeoutSeconds: 2 + livenessProbe: + exec: + command: ["pg_isready"] + initialDelaySeconds: 15 + timeoutSeconds: 2 + resources: + limits: + memory: "256Mi" + cpu: "500m" + volumes: + - name: storage + persistentVolumeClaim: + claimName: postgres-pvc +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: postgres + name: postgres +spec: + selector: + app.kubernetes.io/name: postgres + ports: + - port: 5432 diff --git a/serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/02-keycloak.yaml b/serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/02-keycloak.yaml new file mode 100644 index 0000000000..515cb7f7e2 --- /dev/null +++ b/serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/02-keycloak.yaml @@ -0,0 +1,92 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + name: keycloak + labels: + app: keycloak +spec: + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app: keycloak + type: NodePort +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: keycloak + labels: + app: keycloak +spec: + replicas: 1 + selector: + matchLabels: + app: keycloak + template: + metadata: + labels: + app: keycloak + spec: + initContainers: + - name: init-postgres + image: registry.access.redhat.com/ubi9/ubi-minimal:latest + imagePullPolicy: IfNotPresent + command: + [ + "sh", + "-c", + 'until (echo 1 > /dev/tcp/postgres.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local/5432) >/dev/null 2>&1; do echo "Waiting for postgres server"; sleep 3; done;', + ] + containers: + - name: keycloak + image: keycloak + imagePullPolicy: "IfNotPresent" + args: ["start-dev"] + env: + - name: KEYCLOAK_ADMIN + value: "admin" + - name: KEYCLOAK_ADMIN_PASSWORD + value: "admin" + - name: KC_PROXY + value: "edge" + - name: KC_DB + value: postgres + - name: KC_DB_USERNAME + valueFrom: + secretKeyRef: + key: POSTGRES_USER + name: postgres-secrets + - name: KC_DB_PASSWORD + valueFrom: + secretKeyRef: + key: POSTGRES_PASSWORD + name: postgres-secrets + - name: KC_DB_URL_HOST + value: postgres + ports: + - name: http + containerPort: 8080 + readinessProbe: + httpGet: + path: /realms/master + port: 8080 + resources: + limits: + memory: "2Gi" + cpu: "1" diff --git a/serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/kustomization.yaml b/serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/kustomization.yaml new file mode 100644 index 0000000000..d0065a1f46 --- /dev/null +++ b/serverless-operator-examples/sonataflow-apisix-oidc/manifests/bases/kustomization.yaml @@ -0,0 +1,37 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - 01-postgres.yaml + - 02-keycloak.yaml + +images: + - name: postgres + newName: docker.io/library/postgres + newTag: alpine3.19 + - name: keycloak + newName: quay.io/keycloak/keycloak + newTag: 24.0.2 + +secretGenerator: + - name: postgres-secrets + options: + disableNameSuffixHash: true + literals: + - POSTGRES_USER=keycloak + - POSTGRES_PASSWORD=keycloak + - POSTGRES_DATABASE=keycloak + - PGDATA=/var/lib/pgsql/data diff --git a/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/01-sonataflow-greeting.yaml b/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/01-sonataflow-greeting.yaml new file mode 100644 index 0000000000..a201c91fe1 --- /dev/null +++ b/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/01-sonataflow-greeting.yaml @@ -0,0 +1,58 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlow +metadata: + name: greeting + annotations: + sonataflow.org/description: Greeting example on k8s! + sonataflow.org/version: 0.0.1 +spec: + flow: + start: ChooseOnLanguage + functions: + - name: greetFunction + type: custom + operation: sysout + states: + - name: ChooseOnLanguage + type: switch + dataConditions: + - condition: '${ .language == "English" }' + transition: GreetInEnglish + - condition: '${ .language == "Spanish" }' + transition: GreetInSpanish + defaultCondition: GreetInEnglish + - name: GreetInEnglish + type: inject + data: + greeting: "Hello from YAML Workflow, " + transition: GreetPerson + - name: GreetInSpanish + type: inject + data: + greeting: "Saludos desde YAML Workflow, " + transition: GreetPerson + - name: GreetPerson + type: operation + stateDataFilter: + output: '${ {"message": (.greeting + $WORKFLOW.identity)} }' + actions: + - name: greetAction + functionRef: + refName: greetFunction + arguments: + message: ".greeting+.name" + end: true diff --git a/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/02-sonataflow-route.yaml b/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/02-sonataflow-route.yaml new file mode 100644 index 0000000000..c2ca1afc0e --- /dev/null +++ b/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/02-sonataflow-route.yaml @@ -0,0 +1,40 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apisix.apache.org/v2 +kind: ApisixRoute +metadata: + name: sonataflow +spec: + http: + - name: greeting + match: + hosts: + - local.greeting.sonataflow.org + paths: + - "/*" + backends: + - serviceName: greeting + servicePort: 80 + plugins: + - name: openid-connect + enable: true + config: + client_id: apisix-ingress + client_secret: + discovery: http://keycloak.keycloak.svc.cluster.local:8080/realms/sonataflow/.well-known/openid-configuration + scope: profile email + bearer_only: true + realm: sonataflow + introspection_endpoint_auth_method: client_secret_post diff --git a/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/greeting.svg b/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/greeting.svg new file mode 100644 index 0000000000..ad7dcc8bb7 --- /dev/null +++ b/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/greeting.svg @@ -0,0 +1 @@ +StartChooseOnLanguag e GreetInEnglishGreetInSpanishGreetPersonEnd${ .langua... ${ .langua... ${ .langua... ${ .langua... \ No newline at end of file diff --git a/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/greeting.sw.yaml b/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/greeting.sw.yaml new file mode 100644 index 0000000000..4753a74719 --- /dev/null +++ b/serverless-operator-examples/sonataflow-apisix-oidc/workflow-app/greeting.sw.yaml @@ -0,0 +1,55 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +id: "workflow_unique_identifier" +version: "0.1" +specVersion: "0.8" +name: "Workflow name" +description: "Workflow description" +functions: + - name: greetFunction + type: custom + operation: sysout +start: ChooseOnLanguage +states: + - name: ChooseOnLanguage + type: switch + dataConditions: + - condition: '${ .language == "English" }' + transition: GreetInEnglish + - condition: '${ .language == "Spanish" }' + transition: GreetInSpanish + defaultCondition: + transition: GreetInEnglish + - name: GreetInEnglish + type: inject + data: + greeting: "Hello from YAML Workflow, " + transition: GreetPerson + - name: GreetInSpanish + type: inject + data: + greeting: "Saludos desde YAML Workflow, " + transition: GreetPerson + - name: GreetPerson + type: operation + stateDataFilter: + output: '${ { "message": (.greeting + .name) } }' + actions: + - name: greetAction + functionRef: + refName: greetFunction + arguments: + message: ".greeting+.name" + end: true