diff --git a/.github/keycloak-redirect-url.sh b/.github/keycloak-redirect-url.sh new file mode 100755 index 00000000..3a94303d --- /dev/null +++ b/.github/keycloak-redirect-url.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +set -eo pipefail + +BASE_URL=https://id.dev.appuio.cloud + +USER=$1 +PASSWORD=$2 +REDIRECT_URI=$3 + +ACTION=$4 + +loginRealm=master + +editRealm=appuio-cloud-dev +# The client ID has to be the UUID +editClientId=a4d5a5cb-81ff-4532-9b25-d2d4242d23e2 + +loginUrl="${BASE_URL}/auth/realms/${loginRealm}/protocol/openid-connect/token" +clientUrl="${BASE_URL}/auth/admin/realms/${editRealm}/clients/${editClientId}" + + +echo "* Logging in to ${loginRealm}" +json_resp_login=$(curl -sS --fail --data "username=${USER}&password=${PASSWORD}&grant_type=password&client_id=admin-cli" "${loginUrl}") +access_token=$(echo "${json_resp_login}" | jq -r '.access_token') + +echo "* Retrieving Client config '${editClientId}'" +json_resp_client=$(curl -sS --fail ${clientUrl} -H "Content-Type: application/json" -H "Authorization: bearer ${access_token}") + +if [ "${ACTION}" = "remove" ]; then + echo "* Removing '${REDIRECT_URI}' from Client config '${editClientId}'" + json_req_update=$(echo ${json_resp_client} | jq -c '.redirectUris |= (.- ["'${REDIRECT_URI}'"] | unique)') +else + echo "* Adding '${REDIRECT_URI}' to Client config '${editClientId}'" + json_req_update=$(echo ${json_resp_client} | jq -c '.redirectUris |= (.+ ["'${REDIRECT_URI}'"] | unique)') +fi + +curl -sS --fail ${clientUrl} -H "Content-Type: application/json" -H "Authorization: bearer ${access_token}" -X PUT --data "${json_req_update}" diff --git a/.github/workflows/destroy-preview.yaml b/.github/workflows/destroy-preview.yaml index eff75f3e..c5105f10 100644 --- a/.github/workflows/destroy-preview.yaml +++ b/.github/workflows/destroy-preview.yaml @@ -64,6 +64,9 @@ jobs: **Helm release** | ${{ env.NAMESPACE }}/${{ env.HELM_RELEASE_NAME }} **Cluster** | ${{ env.OPENSHIFT_API }} + - name: Remove route URL from Keycloak client + run: ./github/keycloak-redirect-url.sh "${{ secrets.KEYCLOAK_USER }}" "${{ secrets.KEYCLOAK_PASSWORD }}" "https://${{ steps.deployment_info.outputs.route_host }}/*" remove + - name: Notify on failure uses: peter-evans/create-or-update-comment@v1 if: ${{ failure() }} diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml index 9ff5ba82..6110edc3 100644 --- a/.github/workflows/pull-request.yaml +++ b/.github/workflows/pull-request.yaml @@ -58,6 +58,8 @@ jobs: revision: ${{ github.event.pull_request.head.sha }} secrets: openshift_token: ${{ secrets.OPENSHIFT_TOKEN }} + keycloak_password: ${{ secrets.KEYCLOAK_PASSWORD }} + keycloak_user: ${{ secrets.KEYCLOAK_USER }} needs: - build - docker diff --git a/.github/workflows/template-deploy.yaml b/.github/workflows/template-deploy.yaml index ddb49c07..37482b9b 100644 --- a/.github/workflows/template-deploy.yaml +++ b/.github/workflows/template-deploy.yaml @@ -21,6 +21,10 @@ on: secrets: openshift_token: required: true + keycloak_user: + required: false + keycloak_password: + required: false env: OPENSHIFT_API: https://api.c-appuio-cloudscale-lpg-2.appuio.cloud:6443 @@ -69,6 +73,10 @@ jobs: run: | echo ::set-output name=route_host::"$(oc -n ${{ inputs.namespace }} get route ${{ inputs.helm_release_name }} -o jsonpath='{.spec.host}')" + - name: Add route URL to Keycloak client + if: ${{ github.event_name == 'pull_request' }} + run: .github/keycloak-redirect-url.sh "${{ secrets.keycloak_user }}" "${{ secrets.keycloak_password }}" "https://${{ steps.deployment_info.outputs.route_host }}/*" + - name: Notify on success uses: peter-evans/create-or-update-comment@v1 if: ${{ github.event_name == 'pull_request' }} diff --git a/README.md b/README.md index caaee10a..fae4fe2d 100644 --- a/README.md +++ b/README.md @@ -67,3 +67,16 @@ oc -n $nstest sa get-token $sa ``` Now, put the token into GitHub's Secrets + +## Use existing Keycloak in preview deployments + +A GitHub action workflows dynamically registers the redirect URL in an existing Keycloak instance via API. + +1. Create a new User in master realm +1. Set a secure password +1. In the role mappings, select `appuio-cloud-dev-realm` in the "Client Roles" dropdown. + Add `manage-clients`. +1. Create a new Client in the target realm (e.g. `appuio-control-api`) +1. When editing the client, the URL shows the UUID of the client. + Copy this value and set it in `.github/keycloak-redirect-url.sh`. +1. Update the `KEYCLOAK_USER` and `KEYCLOAK_PASSWORD` secrets in GitHub environment `preview` with the values in the first steps.