From 7264e21c81a58033c29c9a1fab48e334388c11a1 Mon Sep 17 00:00:00 2001 From: Patrick Lee Scott Date: Mon, 26 Oct 2020 12:26:07 -0500 Subject: [PATCH] feat: new CI/Test process and secret creation bug fix (#42) fixes #34 and fixes #40 chore: update gitignore with files from VSCode test: update test script fix: ci refactor + fixes #34, fixes #40 chore: test more kube versions --- .github/ci.docker-build.sh | 13 +++ .github/ci.example.sh | 23 ++++++ .github/ci.helm.sh | 14 ++++ .github/ci.keycloak-controller.sh | 28 +++++++ .github/ci.keycloak.sh | 24 ++++++ .github/ci.maven.sh | 10 +++ .github/ci.provision.helm.sh | 12 +++ .github/ci.provision.kubernetes.sh | 10 +++ .github/ci.provision.maven.sh | 9 ++ .github/ci.verify.sh | 16 ++++ .github/docker-build.sh | 13 --- .github/k8s-install.sh | 82 ------------------- .github/keycloak-values.yaml | 15 ++++ .github/kind-config.yaml | 4 +- .github/local.kind.sh | 8 ++ .github/local.maven.sh | 8 ++ .github/mvn-build.sh | 11 --- .github/workflows/ci.yaml | 43 ++++++---- .gitignore | 7 +- README.md | 74 +++++++++++++++++ examples/client-mappers-roles.yaml | 52 ------------ .../keycloak-client-fully-configured.yaml | 47 +++++++++++ ...eycloak-clientscope-fully-configured.yaml} | 6 +- examples/keycloak-fully-configured.yaml | 10 +-- examples/keycloak-realm-fully-configured.yaml | 11 +++ examples/realm.yaml | 11 --- pom.xml | 4 +- .../controller/ApplicationHandler.java | 2 +- .../controller/client/ClientController.java | 14 +++- 29 files changed, 377 insertions(+), 204 deletions(-) create mode 100755 .github/ci.docker-build.sh create mode 100755 .github/ci.example.sh create mode 100755 .github/ci.helm.sh create mode 100755 .github/ci.keycloak-controller.sh create mode 100755 .github/ci.keycloak.sh create mode 100755 .github/ci.maven.sh create mode 100755 .github/ci.provision.helm.sh create mode 100755 .github/ci.provision.kubernetes.sh create mode 100755 .github/ci.provision.maven.sh create mode 100755 .github/ci.verify.sh delete mode 100755 .github/docker-build.sh delete mode 100755 .github/k8s-install.sh create mode 100644 .github/keycloak-values.yaml create mode 100755 .github/local.kind.sh create mode 100755 .github/local.maven.sh delete mode 100755 .github/mvn-build.sh delete mode 100644 examples/client-mappers-roles.yaml create mode 100644 examples/keycloak-client-fully-configured.yaml rename examples/{client-scope.yaml => keycloak-clientscope-fully-configured.yaml} (77%) create mode 100644 examples/keycloak-realm-fully-configured.yaml delete mode 100644 examples/realm.yaml diff --git a/.github/ci.docker-build.sh b/.github/ci.docker-build.sh new file mode 100755 index 0000000..27a5e0b --- /dev/null +++ b/.github/ci.docker-build.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# +# build docker image and push it to kind nodes + +set -o errexit + +DOCKER_TAG="keycloak-controller:local" + +echo -e "\n##### create docker image with tag $DOCKER_TAG #####\n" +docker build -t "$DOCKER_TAG" ./target + +echo -e "\n##### push docker image to kind nodes #####\n" +kind --name chart-testing load docker-image "$DOCKER_TAG" diff --git a/.github/ci.example.sh b/.github/ci.example.sh new file mode 100755 index 0000000..f4a2b17 --- /dev/null +++ b/.github/ci.example.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# ci for keycloak-controller +# + +set -o errexit + +NAMESPACE="keycloak" + +echo -e "\n##### install keycloak-controller examples #####\n" +while IFS= read -r KEYCLOAK_EXAMPLE; do + kubectl -n "$NAMESPACE" apply -f "${KEYCLOAK_EXAMPLE}" +done < <(find examples -type f) + +echo -e "\n##### show keycloak-controller examples #####\n" +kubectl -n "$NAMESPACE" get keycloaks.k8s.kiwigrid.com +echo "" +kubectl -n "$NAMESPACE" get keycloakrealms.k8s.kiwigrid.com +echo "" +kubectl -n "$NAMESPACE" get keycloakclients.k8s.kiwigrid.com +echo "" +kubectl -n "$NAMESPACE" get keycloakclientscopes.k8s.kiwigrid.com +echo "" \ No newline at end of file diff --git a/.github/ci.helm.sh b/.github/ci.helm.sh new file mode 100755 index 0000000..4cf0085 --- /dev/null +++ b/.github/ci.helm.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# +# ci for keycloak-controller +# + +set -o errexit + +echo -e "\n##### add helm repos #####\n" +helm repo add bitnami https://charts.bitnami.com/bitnami +helm repo add codecentric https://codecentric.github.io/helm-charts +helm repo add kiwigrid https://kiwigrid.github.io + +echo -e "\n##### update helm repos #####\n" +helm repo update diff --git a/.github/ci.keycloak-controller.sh b/.github/ci.keycloak-controller.sh new file mode 100755 index 0000000..a022f13 --- /dev/null +++ b/.github/ci.keycloak-controller.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# +# ci for keycloak-controller +# + +set -o errexit + +KEYCLOAK_CONTROLLER_CHART_VERSION="${1}" +NAMESPACE="keycloak" + +echo -e "\n##### install keycloak-controller crds #####\n" +while IFS= read -r CRD; do + kubectl apply -f "${CRD}" +done < <(find src/main/k8s -type f) + +echo -e "\n##### test controller crds #####\n" +kubectl -n "$NAMESPACE" wait --for condition=established --timeout=15s crd/keycloakclients.k8s.kiwigrid.com +kubectl -n "$NAMESPACE" wait --for condition=established --timeout=15s crd/keycloakclientscopes.k8s.kiwigrid.com +kubectl -n "$NAMESPACE" wait --for condition=established --timeout=15s crd/keycloakrealms.k8s.kiwigrid.com +kubectl -n "$NAMESPACE" wait --for condition=established --timeout=15s crd/keycloaks.k8s.kiwigrid.com + +echo -e "\n##### install keycloak-controller #####\n" +helm upgrade -i keycloak-controller kiwigrid/keycloak-controller \ + --wait \ + --namespace keycloak \ + --version "$KEYCLOAK_CONTROLLER_CHART_VERSION" \ + --set image.repository=keycloak-controller \ + --set image.tag=local \ No newline at end of file diff --git a/.github/ci.keycloak.sh b/.github/ci.keycloak.sh new file mode 100755 index 0000000..1fb6757 --- /dev/null +++ b/.github/ci.keycloak.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# +# ci for keycloak-controller +# + +set -o errexit + +KEYCLOAK_CHART_VERSION="${1}" +NAMESPACE="keycloak" + +echo -e "\n##### create keycloak namespace #####\n" +kubectl create namespace $NAMESPACE + +echo -e "\n##### install keycloak #####\n" +kubectl create secret generic keycloak-auth \ + --namespace $NAMESPACE \ + --from-literal=username=keycloak \ + --from-literal=password=keycloak + +helm upgrade -i keycloak codecentric/keycloak \ + --wait \ + --namespace $NAMESPACE \ + --version "${KEYCLOAK_CHART_VERSION}" \ + --values .github/keycloak-values.yaml \ No newline at end of file diff --git a/.github/ci.maven.sh b/.github/ci.maven.sh new file mode 100755 index 0000000..0845938 --- /dev/null +++ b/.github/ci.maven.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# +# ci for keycloak-controller +# + +set -o errexit + +export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 + +mvn clean && mvn package \ No newline at end of file diff --git a/.github/ci.provision.helm.sh b/.github/ci.provision.helm.sh new file mode 100755 index 0000000..5bff287 --- /dev/null +++ b/.github/ci.provision.helm.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -o errexit + +HELM_VERSION="${1}" + +echo -e "\n##### install helm #####\n" +curl --silent --show-error --fail --location --output get_helm.sh https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get +chmod 700 get_helm.sh +./get_helm.sh --version "${HELM_VERSION}" + +helm version \ No newline at end of file diff --git a/.github/ci.provision.kubernetes.sh b/.github/ci.provision.kubernetes.sh new file mode 100755 index 0000000..1056557 --- /dev/null +++ b/.github/ci.provision.kubernetes.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -o errexit + +K8S_VERSION="${1}" + +echo -e "\n##### install kubectl #####\n" +curl --silent --show-error --fail --location --output kubectl "https://storage.googleapis.com/kubernetes-release/release/${K8S_VERSION}/bin/linux/amd64/kubectl" +chmod +x ./kubectl +sudo mv ./kubectl /usr/local/bin/kubectl \ No newline at end of file diff --git a/.github/ci.provision.maven.sh b/.github/ci.provision.maven.sh new file mode 100755 index 0000000..8dd06fb --- /dev/null +++ b/.github/ci.provision.maven.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -o errexit + +echo -e "\n##### install mvn & java #####\n" +sudo apt-get update && sudo apt-get install -y maven openjdk-11-jdk +export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 + +mvn --version \ No newline at end of file diff --git a/.github/ci.verify.sh b/.github/ci.verify.sh new file mode 100755 index 0000000..a95babd --- /dev/null +++ b/.github/ci.verify.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -o errexit + +NAMESPACE="keycloak" + +echo -e "\n##### check for errors in keycloak-controller logs #####\n" +sleep 60 +if kubectl -n "${NAMESPACE}" logs -l app.kubernetes.io/name=keycloak-controller | grep -q ERROR; then + echo "errors found in logs :(" + kubectl -n "${NAMESPACE}" logs -l app.kubernetes.io/name=keycloak-controller + exit 1 +else + echo "no errors found in logs :)" + kubectl -n "${NAMESPACE}" logs -l app.kubernetes.io/name=keycloak-controller +fi \ No newline at end of file diff --git a/.github/docker-build.sh b/.github/docker-build.sh deleted file mode 100755 index 949d1f8..0000000 --- a/.github/docker-build.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -# -# build docker image and push it to kind nodes - -set -o errexit - -DOCKER_TAG="keycloak-controller:ci-snapshot" - -echo -e "\n##### create docker image with tag ${DOCKER_TAG} #####\n" -docker build -t "${DOCKER_TAG}" ./target - -echo -e "\n##### push docker image to kind nodes #####\n" -kind --name chart-testing load docker-image "${DOCKER_TAG}" diff --git a/.github/k8s-install.sh b/.github/k8s-install.sh deleted file mode 100755 index d0d2267..0000000 --- a/.github/k8s-install.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash -# -# ci for keycloak-controller -# - -set -o errexit - -KEYCLOAK_CHART_VERSION="${1}" -KEYCLOAK_CONTROLLER_CHART_VERSION="${2}" -K8S_VERSION="${3}" -NAMESPACE="keycloak" - -echo -e "\n##### show versions #####\n" -echo "helm version: ${HELM_VERSION}" -echo "kubernetes version: ${K8S_VERSION}" -echo "keycloak chart version: ${KEYCLOAK_CHART_VERSION}" -echo "keycloak-controller chart version: ${KEYCLOAK_CONTROLLER_CHART_VERSION}" -echo "" - -echo -e "\n##### install kubectl #####\n" -curl --silent --show-error --fail --location --output kubectl "https://storage.googleapis.com/kubernetes-release/release/${K8S_VERSION}/bin/linux/amd64/kubectl" -chmod +x ./kubectl -sudo mv ./kubectl /usr/local/bin/kubectl - -echo -e "\n##### install helm #####\n" -curl --silent --show-error --fail --location --output get_helm.sh https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get -chmod 700 get_helm.sh -./get_helm.sh --version "${HELM_VERSION}" - -echo -e "\n##### add helm repos #####\n" -helm repo add bitnami https://charts.bitnami.com/bitnami -helm repo add codecentric https://codecentric.github.io/helm-charts -helm repo add kiwigrid https://kiwigrid.github.io - -echo -e "\n##### update helm repos #####\n" -helm repo update - -echo -e "\n##### create keycloak namespace #####\n" -kubectl create namespace "${NAMESPACE}" - -echo -e "\n##### install keycloak #####\n" -helm upgrade -i keycloak codecentric/keycloak --wait --namespace "${NAMESPACE}" --version "${KEYCLOAK_CHART_VERSION}" - -echo -e "\n##### install keycloak-controller #####\n" -helm upgrade -i keycloak-controller kiwigrid/keycloak-controller --wait --namespace "${NAMESPACE}" --version "${KEYCLOAK_CONTROLLER_CHART_VERSION}" --set image.repository=keycloak-controller --set image.tag=ci-snapshot - -echo -e "\n##### install keycloak-controller crds #####\n" -while IFS= read -r CRD; do - kubectl apply -f "${CRD}" -done < <(find src/main/k8s -type f) - -echo -e "\n##### test controller crds #####\n" -kubectl -n "${NAMESPACE}" wait --for condition=established --timeout=15s crd/keycloakclients.k8s.kiwigrid.com -kubectl -n "${NAMESPACE}" wait --for condition=established --timeout=15s crd/keycloakclientscopes.k8s.kiwigrid.com -kubectl -n "${NAMESPACE}" wait --for condition=established --timeout=15s crd/keycloakrealms.k8s.kiwigrid.com -kubectl -n "${NAMESPACE}" wait --for condition=established --timeout=15s crd/keycloaks.k8s.kiwigrid.com - -echo -e "\n##### install keycloak-controller examples #####\n" -while IFS= read -r KEYCLOAK_EXAMPLE; do - kubectl -n "${NAMESPACE}" apply -f "${KEYCLOAK_EXAMPLE}" -done < <(find examples -type f) - -echo -e "\n##### show keycloak-controller examples #####\n" -kubectl -n "${NAMESPACE}" get keycloakclients.k8s.kiwigrid.com -echo "" -kubectl -n "${NAMESPACE}" get keycloakclientscopes.k8s.kiwigrid.com -echo "" -kubectl -n "${NAMESPACE}" get keycloakrealms.k8s.kiwigrid.com -echo "" -kubectl -n "${NAMESPACE}" get keycloaks.k8s.kiwigrid.com -echo "" - -echo -e "\n##### check for errors in keycloak-controller logs #####\n" -sleep 150 -if kubectl -n "${NAMESPACE}" logs -l app.kubernetes.io/name=keycloak-controller | grep -q ERROR; then - echo "errors found in logs :(" - kubectl -n "${NAMESPACE}" logs -l app.kubernetes.io/name=keycloak-controller - exit 1 -else - echo "no errors found in logs :)" - kubectl -n "${NAMESPACE}" logs -l app.kubernetes.io/name=keycloak-controller -fi diff --git a/.github/keycloak-values.yaml b/.github/keycloak-values.yaml new file mode 100644 index 0000000..e128499 --- /dev/null +++ b/.github/keycloak-values.yaml @@ -0,0 +1,15 @@ +extraEnv: | + - name: KEYCLOAK_USER_FILE + value: /secrets/keycloak-auth/username + - name: KEYCLOAK_PASSWORD_FILE + value: /secrets/keycloak-auth/password + - name: PROXY_ADDRESS_FORWARDING + value: "true" +extraVolumeMounts: | + - name: keycloak-auth + mountPath: /secrets/keycloak-auth + readOnly: true +extraVolumes: | + - name: keycloak-auth + secret: + secretName: keycloak-auth \ No newline at end of file diff --git a/.github/kind-config.yaml b/.github/kind-config.yaml index e00d963..bc43344 100644 --- a/.github/kind-config.yaml +++ b/.github/kind-config.yaml @@ -1,8 +1,8 @@ kind: Cluster -apiVersion: kind.sigs.k8s.io/v1alpha3 +apiVersion: kind.x-k8s.io/v1alpha4 nodes: # the control plane node config - role: control-plane # the 2 workers - role: worker -- role: worker +- role: worker \ No newline at end of file diff --git a/.github/local.kind.sh b/.github/local.kind.sh new file mode 100755 index 0000000..75c8948 --- /dev/null +++ b/.github/local.kind.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# +# ci for keycloak-controller +# + +set -o errexit + +kind create cluster --config .github/kind-config.yaml --name chart-testing \ No newline at end of file diff --git a/.github/local.maven.sh b/.github/local.maven.sh new file mode 100755 index 0000000..6cbd48d --- /dev/null +++ b/.github/local.maven.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# +# ci for keycloak-controller +# + +set -o errexit + +mvn clean && mvn package \ No newline at end of file diff --git a/.github/mvn-build.sh b/.github/mvn-build.sh deleted file mode 100755 index c4f30d1..0000000 --- a/.github/mvn-build.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -set -o errexit - -echo -e "\n##### install mvn & java #####\n" -sudo apt-get update -sudo apt-get install -y maven openjdk-11-jdk - -echo -e "\n##### build keycloak-controller #####\n" -export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 -mvn package diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7914054..71ec3b6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,37 +20,46 @@ jobs: needs: - lint-bash-scripts env: - HELM_VERSION: v3.2.4 + HELM_VERSION: v3.3.4 strategy: matrix: k8s-version: - v1.14.10 - - v1.15.7 - - v1.16.9 - - v1.17.5 - - v1.18.6 + - v1.15.12 + - v1.16.15 + - v1.17.11 + - v1.18.8 + - v1.19.1 keycloak-chart: - # keycloak 9.0.0 - - 7.7.1 - # keycloak 10.0.0 - - 8.3.0 - # keycloak 11.0.0 - 9.0.1 keycloak-controller-chart: - 0.6.1 steps: - name: Checkout uses: actions/checkout@v2 - - name: Fetch history - run: git fetch --prune --unshallow + - name: provision + run: | + .github/ci.provision.kubernetes.sh ${{ matrix.k8s-version }} & \ + .github/ci.provision.helm.sh $HELM_VERSION & \ + .github/ci.provision.maven.sh & \ + wait + - name: maven + run: .github/ci.maven.sh - name: Create kind ${{ matrix.k8s-version }} cluster uses: helm/kind-action@master with: config: .github/kind-config.yaml node_image: kindest/node:${{ matrix.k8s-version }} - - name: mvn build - run: .github/mvn-build.sh - name: build docker image & push to kind nodes - run: .github/docker-build.sh - - name: test keycloak-controller - run: .github/k8s-install.sh ${{ matrix.keycloak-chart }} ${{ matrix.keycloak-controller-chart }} ${{ matrix.k8s-version }} + run: .github/ci.docker-build.sh + - name: helm + run: .github/ci.helm.sh + - name: keycloak and keycloak controller + run: | + .github/ci.keycloak.sh ${{ matrix.keycloak-chart }} & \ + .github/ci.keycloak-controller.sh ${{ matrix.keycloak-controller-chart }} & \ + wait + - name: examples + run: .github/ci.example.sh + - name: verify + run: .github/ci.verify.sh \ No newline at end of file diff --git a/.gitignore b/.gitignore index 21e2fc7..c0896e9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,9 @@ target/ .idea/ /dependency-reduced-pom.xml -.attach_pid* \ No newline at end of file +.attach_pid* +.classpath +.factorypath +.project +.settings +.vscode \ No newline at end of file diff --git a/README.md b/README.md index be354a5..aeb2766 100644 --- a/README.md +++ b/README.md @@ -81,3 +81,77 @@ spec: access.token.claim: "true" included.client.audience: my-service ``` + +# Development + +To test the controller using the same process as Github Actions from a blank container, install `act`: + +``` +brew install act +``` + +And then trigger the pull request action: + +``` +act pull_request -P ubuntu-latest=nektos/act-environments-ubuntu:18.04 +``` + +## Machine Setup + +To run Keycloak Controller locally some of the same scripts that power the Github Actions can be used, but you'll want to provision your machine locally instead, as you most likely don't want to delete all your installs and builds for every single change, or change your local environment in a forceful manner - such as installing versions of a tool that conflicts with another local tool you are using. + +The tools you'll need to make sure are installed are `kubectl`, `helm`, `kind`, `java`, and `maven`. + +Please look at their official documentation to find how to install each. + +Once they are installed you can run the various ci scripts: + +Here is an example of running the full pipeline, parallelized where possible - of course you could run them ad-hoc in any order that makes sense: + +###### Setup + +Build `.jar` and run a Kubernetes cluster in Docker: + +```sh +bash .github/local.maven.sh & +bash .github/local.kind.sh & +wait +``` + +Build docker image using .jar from previous step, and get Helm ready: + +```sh +bash .github/ci.docker-build.sh & +bash .github/ci.helm.sh & +wait +``` + +Install Keycloak and Keycloak Controller configured to use the image produced and uploaded to Kind in the last step: + +```sh +bash .github/ci.keycloak.sh "9.0.1" & \ +bash .github/ci.keycloak-controller.sh "0.6.1" & \ +wait +``` + +###### Run Examples + +``` +bash .github/ci.example.sh && +bash .github/ci.verify.sh +``` + +###### Make changes and see them running in Kubernetes + +``` +bash .github/local.maven.sh && +bash .github/ci.docker-build.sh && +kubectl rollout restart deployment -n keycloak keycloak-controller && +kubectl rollout status deployment -n keycloak keycloak-controller +``` + +###### Teardown + +``` +kind delete clusters chart-testing +``` diff --git a/examples/client-mappers-roles.yaml b/examples/client-mappers-roles.yaml deleted file mode 100644 index 54404cb..0000000 --- a/examples/client-mappers-roles.yaml +++ /dev/null @@ -1,52 +0,0 @@ -apiVersion: k8s.kiwigrid.com/v1beta1 -kind: KeycloakClient -metadata: - name: customized-client -spec: - keycloak: fully-configured-keycloak - realm: food-realm - clientId: pizza-service - clientType: confidential - directAccessGrantsEnabled: true - standardFlowEnabled: false - implicitFlowEnabled: false - serviceAccountsEnabled: true - secretName: pizza-service - roles: - - name: service - realmRoles: - - service - - admin - - grandmaster - serviceAccountRealmRoles: - - editor - mapper: - - name: audience - protocolMapper: oidc-audience-mapper - config: - claim.name: audience - access.token.claim: "true" - included.client.audience: pizza-service - - name: tenant - protocolMapper: oidc-script-based-protocol-mapper - config: - claim.name: tenant - access.token.claim: "true" - jsonType.label: String - script: "realm.getName();" - - name: username - protocolMapper: oidc-usermodel-property-mapper - config: - claim.name: username - access.token.claim: "true" - jsonType.label: String - user.attribute: username - - name: roles - protocolMapper: oidc-usermodel-client-role-mapper - config: - claim.name: roles - access.token.claim: "true" - jsonType.label: String - multivalued: "true" - usermodel.clientRoleMapping.clientId: pizza-service - usermodel.clientRoleMapping.rolePrefix: pizza-service- \ No newline at end of file diff --git a/examples/keycloak-client-fully-configured.yaml b/examples/keycloak-client-fully-configured.yaml new file mode 100644 index 0000000..bb6995d --- /dev/null +++ b/examples/keycloak-client-fully-configured.yaml @@ -0,0 +1,47 @@ +apiVersion: k8s.kiwigrid.com/v1beta1 +kind: KeycloakClient +metadata: + name: fully-configured-client +spec: + keycloak: fully-configured-keycloak + realm: fully-configured-realm + clientId: fully-configured-client + clientType: confidential + defaultClientScopes: + - email + - profile + - roles + directAccessGrantsEnabled: true + standardFlowEnabled: true + implicitFlowEnabled: false + redirectUris: + - http://* + - https://* + mapper: + - name: audience + protocolMapper: oidc-audience-mapper + config: + claim.name: audience + access.token.claim: "true" + included.client.audience: fully-configured-client + - name: username + protocolMapper: oidc-usermodel-property-mapper + config: + access.token.claim: "true" + claim.name: username + jsonType.label: String + user.attribute: username + - name: clientRoles + protocolMapper: oidc-usermodel-client-role-mapper + config: + access.token.claim: "true" + claim.name: clientRoles + jsonType.label: String + multivalued: "true" + - name: roles + protocolMapper: oidc-usermodel-realm-role-mapper + config: + access.token.claim: "true" + claim.name: roles + jsonType.label: String + multivalued: "true" \ No newline at end of file diff --git a/examples/client-scope.yaml b/examples/keycloak-clientscope-fully-configured.yaml similarity index 77% rename from examples/client-scope.yaml rename to examples/keycloak-clientscope-fully-configured.yaml index 578ba83..c24b4f4 100644 --- a/examples/client-scope.yaml +++ b/examples/keycloak-clientscope-fully-configured.yaml @@ -1,11 +1,11 @@ apiVersion: k8s.kiwigrid.com/v1beta1 kind: KeycloakClientScope metadata: - name: client-scope-example + name: fully-configured-clientscope spec: keycloak: fully-configured-keycloak - realm: food-realm - name: client-scope-example + realm: fully-configured-realm + name: fully-configured-clientscope mapper: - name: scope-group-mapper-example protocolMapper: oidc-script-based-protocol-mapper diff --git a/examples/keycloak-fully-configured.yaml b/examples/keycloak-fully-configured.yaml index 2e1ae4a..9bdc0d8 100644 --- a/examples/keycloak-fully-configured.yaml +++ b/examples/keycloak-fully-configured.yaml @@ -3,10 +3,10 @@ kind: Keycloak metadata: name: fully-configured-keycloak spec: - url: https://keycloak.example.com/auth + url: http://keycloak-http.keycloak.svc.cluster.local/auth realm: master clientId: admin-cli - username: admin - passwordSecretNamespace: infrastructure - passwordSecretName: keycloak-http - passwordSecretKey: password \ No newline at end of file + username: keycloak + passwordSecretNamespace: keycloak + passwordSecretName: keycloak-auth + passwordSecretKey: password diff --git a/examples/keycloak-realm-fully-configured.yaml b/examples/keycloak-realm-fully-configured.yaml new file mode 100644 index 0000000..cf71c44 --- /dev/null +++ b/examples/keycloak-realm-fully-configured.yaml @@ -0,0 +1,11 @@ +apiVersion: k8s.kiwigrid.com/v1beta1 +kind: KeycloakRealm +metadata: + name: fully-configured-realm +spec: + keycloak: fully-configured-keycloak + realm: fully-configured-realm + roles: + - service + - admin + - operations \ No newline at end of file diff --git a/examples/realm.yaml b/examples/realm.yaml deleted file mode 100644 index 02caed2..0000000 --- a/examples/realm.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: k8s.kiwigrid.com/v1beta1 -kind: KeycloakRealm -metadata: - name: realm-example -spec: - keycloak: keycloak-instance-example - realm: my-realm - roles: - - service - - admin - - operations diff --git a/pom.xml b/pom.xml index 2dd2442..97de0b7 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ 3.6.3.Final 1.2.3 0.1.5 - 4.6.2 + 4.9.2 1.18.16 1.4.10 3.1.2 @@ -200,7 +200,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.8.1 diff --git a/src/main/java/com/kiwigrid/keycloak/controller/ApplicationHandler.java b/src/main/java/com/kiwigrid/keycloak/controller/ApplicationHandler.java index 811a927..91177e0 100644 --- a/src/main/java/com/kiwigrid/keycloak/controller/ApplicationHandler.java +++ b/src/main/java/com/kiwigrid/keycloak/controller/ApplicationHandler.java @@ -23,7 +23,7 @@ public class ApplicationHandler { final ClientController clientController; final ClientScopeController clientScopeController; - @Scheduled(fixedRate = "${retry-rate:60s}") + @Scheduled(fixedRate = "${retry-rate:10s}") void retry() { keycloakController.retry(); realmController.retry(); diff --git a/src/main/java/com/kiwigrid/keycloak/controller/client/ClientController.java b/src/main/java/com/kiwigrid/keycloak/controller/client/ClientController.java index 58fb130..b062b4a 100644 --- a/src/main/java/com/kiwigrid/keycloak/controller/client/ClientController.java +++ b/src/main/java/com/kiwigrid/keycloak/controller/client/ClientController.java @@ -264,15 +264,21 @@ void manageSecret(RealmResource realmResource, String clientUuid, ClientResource // get secret from keycloak / kubernetes var keycloakSecretValue = realmResource.clients().get(clientUuid).getSecret().getValue(); - var kubernetesSecretResource = kubernetes.secrets().inNamespace(secretNamespace).withName(secretName); + var kubernetesSecretsInNamespace = kubernetes.secrets().inNamespace(secretNamespace); + var kubernetesSecretResource = kubernetesSecretsInNamespace.withName(secretName); var kubernetesSecret = kubernetesSecretResource.get(); // create secret if not found if (kubernetesSecret == null) { - kubernetesSecretResource.create(kubernetesSecretResource.createNew().withNewMetadata() - .withNamespace(secretNamespace).withName(secretName).withResourceVersion(null).and() - .addToData(secretKey, Base64.getEncoder().encodeToString(keycloakSecretValue.getBytes())).done()); + + kubernetesSecretsInNamespace.createOrReplaceWithNew() + .withNewMetadata() + .withName(secretName) + .endMetadata() + .addToData(secretKey, Base64.getEncoder().encodeToString(keycloakSecretValue.getBytes())) + .done(); + log.info("{}/{}/{}: kubernetes secret {}/{} created", keycloak, realm, clientId, secretNamespace, secretName); return;