diff --git a/install-platform.sh b/install-platform.sh index c119e1bd..e292b6dd 100755 --- a/install-platform.sh +++ b/install-platform.sh @@ -83,9 +83,9 @@ wait_until_apps_synced_healthy() { fi # terminate sync if sync is running and takes longer than 300 seconds (workaround when sync gets stuck) operation_phase=$(kubectl get application -n argocd ${app} -o jsonpath='{.status.operationState.phase}') - if [ "${operation_phase}" = "Running" ] && [ ${sync_duration} -gt 300 ] || [ "${operation_phase}" = "Failed" ] ; then + if [ "${operation_phase}" = "Running" ] && [ ${sync_duration} -gt 300 ] || [ "${operation_phase}" = "Failed" ] || [ "${operation_phase}" = "Error" ] ; then # Terminate the operation for the application - echo "sync of app ${app} gets terminated because it took longer than 300 seconds" + echo "sync of app ${app} gets terminated because it took longer than 300 seconds or failed" kubectl exec sx-argocd-application-controller-0 -n argocd -- argocd app terminate-op "$app" --core echo "wait for 10 seconds" sleep 10 @@ -328,12 +328,16 @@ fi if [[ $( echo $argocd_apps | grep sx-kargo ) ]] ; then kubectl delete ExternalSecret github-creds -n kargo # check if kargo is synced and healthy for 5 minutes + # we trigger a new sync in case the bootstrap-app already failed 5 times + kubectl exec sx-argocd-application-controller-0 -n argocd -- argocd app sync "sx-kargo" --async --core wait_until_apps_synced_healthy "sx-kargo" "Synced" "Healthy" 300 fi if [[ $( echo $argocd_apps | grep sx-team-onboarding ) ]] ; then kubectl delete ExternalSecret github-creds -n kargo # check if kargo is synced and healthy for 5 minutes + # we trigger a new sync in case the bootstrap-app already failed 5 times + kubectl exec sx-argocd-application-controller-0 -n argocd -- argocd app sync "sx-team-onboarding" --async --core wait_until_apps_synced_healthy "sx-team-onboarding" "Synced" "Healthy" 300 fi @@ -341,6 +345,8 @@ fi if [[ $( echo $argocd_apps | grep sx-backstage ) ]] ; then # check if backstage is already synced (it will still be degraded because of the missing secret we create in the next step) + # we trigger a new sync in case the bootstrap-app already failed 5 times + kubectl exec sx-argocd-application-controller-0 -n argocd -- argocd app sync "sx-bootstrap-app" --async --core wait_until_apps_synced_healthy "sx-backstage" "Synced" "*" 900 echo "adding special configuration for sx-backstage" @@ -424,6 +430,8 @@ if [[ $( echo $argocd_apps | grep sx-backstage ) ]] ; then fi # finally wait for all apps including backstage to be synced and health + # we trigger a new sync in case the bootstrap-app already failed 5 times + kubectl exec sx-argocd-application-controller-0 -n argocd -- argocd app sync "sx-bootstrap-app" --async --core wait_until_apps_synced_healthy "${argocd_apps}" "Synced" "Healthy" 300 fi diff --git a/platform-apps/charts/argocd/values-k3d.yaml b/platform-apps/charts/argocd/values-k3d.yaml index 27f57fe1..a86a1160 100644 --- a/platform-apps/charts/argocd/values-k3d.yaml +++ b/platform-apps/charts/argocd/values-k3d.yaml @@ -32,6 +32,139 @@ argo-cd: end return hs + "*.upbound.io/*": + health.lua: | + health_status = { + status = "Progressing", + message = "Provisioning ..." + } + + local function contains (table, val) + for i, v in ipairs(table) do + if v == val then + return true + end + end + return false + end + + local has_no_status = { + "ProviderConfig", + "ProviderConfigUsage" + } + + if obj.status == nil or next(obj.status) == nil and contains(has_no_status, obj.kind) then + health_status.status = "Healthy" + health_status.message = "Resource is up-to-date." + return health_status + end + + if obj.status == nil or next(obj.status) == nil or obj.status.conditions == nil then + if obj.kind == "ProviderConfig" and obj.status.users ~= nil then + health_status.status = "Healthy" + health_status.message = "Resource is in use." + return health_status + end + return health_status + end + + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "LastAsyncOperation" then + if condition.status == "False" then + health_status.status = "Degraded" + health_status.message = condition.message + return health_status + end + end + + if condition.type == "Synced" then + if condition.status == "False" then + health_status.status = "Degraded" + health_status.message = condition.message + return health_status + end + end + + if condition.type == "Ready" then + if condition.status == "True" then + health_status.status = "Healthy" + health_status.message = "Resource is up-to-date." + return health_status + end + end + end + + return health_status + + "*.crossplane.io/*": + health.lua: | + health_status = { + status = "Progressing", + message = "Provisioning ..." + } + + local function contains (table, val) + for i, v in ipairs(table) do + if v == val then + return true + end + end + return false + end + + local has_no_status = { + "Composition", + "CompositionRevision", + "DeploymentRuntimeConfig", + "ControllerConfig", + "ProviderConfig", + "ProviderConfigUsage" + } + if obj.status == nil or next(obj.status) == nil and contains(has_no_status, obj.kind) then + health_status.status = "Healthy" + health_status.message = "Resource is up-to-date." + return health_status + end + + if obj.status == nil or next(obj.status) == nil or obj.status.conditions == nil then + if obj.kind == "ProviderConfig" and obj.status.users ~= nil then + health_status.status = "Healthy" + health_status.message = "Resource is in use." + return health_status + end + return health_status + end + + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "LastAsyncOperation" then + if condition.status == "False" then + health_status.status = "Degraded" + health_status.message = condition.message + return health_status + end + end + + if condition.type == "Synced" then + if condition.status == "False" then + health_status.status = "Degraded" + health_status.message = condition.message + return health_status + end + end + + if contains({"Ready", "Healthy", "Offered", "Established"}, condition.type) then + if condition.status == "True" then + health_status.status = "Healthy" + health_status.message = "Resource is up-to-date." + return health_status + end + end + end + + return health_status + + + rbac: policy.csv: | p, backstage, applications, get, */*, allow diff --git a/platform-apps/charts/keycloak/templates/cp-keycloak-cp-secret.yaml b/platform-apps/charts/keycloak/templates/cp-keycloak-cp-secret.yaml index ad02c7b4..e8aab116 100644 --- a/platform-apps/charts/keycloak/templates/cp-keycloak-cp-secret.yaml +++ b/platform-apps/charts/keycloak/templates/cp-keycloak-cp-secret.yaml @@ -5,6 +5,9 @@ metadata: namespace: crossplane labels: type: provider-credentials + annotations: + argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true + argocd.argoproj.io/sync-wave: "-1" type: Opaque stringData: credentials: | diff --git a/platform-apps/charts/keycloak/templates/cp-keycloak-default-clientroles-grafana.yaml b/platform-apps/charts/keycloak/templates/cp-keycloak-default-clientroles-grafana.yaml index 4fdceaea..009ab8ac 100644 --- a/platform-apps/charts/keycloak/templates/cp-keycloak-default-clientroles-grafana.yaml +++ b/platform-apps/charts/keycloak/templates/cp-keycloak-default-clientroles-grafana.yaml @@ -5,7 +5,7 @@ metadata: argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true argocd.argoproj.io/sync-wave: "1" labels: - platform-engineer.cloud/role: viewer + platform-engineer.cloud/role: grafana-viewer name: client-default-role-grafana-viewer spec: forProvider: @@ -25,7 +25,7 @@ metadata: argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true argocd.argoproj.io/sync-wave: "1" labels: - platform-engineer.cloud/role: editor + platform-engineer.cloud/role: grafana-editor name: client-default-role-grafana-editor spec: forProvider: @@ -45,7 +45,7 @@ metadata: argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true argocd.argoproj.io/sync-wave: "1" labels: - platform-engineer.cloud/role: admin + platform-engineer.cloud/role: grafana-admin name: client-default-role-grafana-admin spec: forProvider: diff --git a/platform-apps/charts/keycloak/templates/cp-keycloak-grafana-group-roles.yaml b/platform-apps/charts/keycloak/templates/cp-keycloak-grafana-group-roles.yaml index 49b39d0e..f2c85e5c 100644 --- a/platform-apps/charts/keycloak/templates/cp-keycloak-grafana-group-roles.yaml +++ b/platform-apps/charts/keycloak/templates/cp-keycloak-grafana-group-roles.yaml @@ -1,79 +1,10 @@ -apiVersion: group.keycloak.crossplane.io/v1alpha1 -kind: Roles -metadata: - name: {{ .Values.deployments.keycloak.grafanaclient.config.clientID }}-grafana-group-roles - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: "1" -spec: - deletionPolicy: Delete - forProvider: - exhaustive: false - groupIdRef: - name: admins - realmIdRef: - name: {{ .Values.deployments.keycloak.realm.realmid }} - roleIdsSelector: - matchLabels: - platform-engineer.cloud/role: admin - initProvider: {} - managementPolicies: - - '*' - providerConfigRef: - name: sx-keycloak-config ---- -apiVersion: group.keycloak.crossplane.io/v1alpha1 -kind: Roles -metadata: - name: {{ .Values.deployments.keycloak.grafanaclient.config.clientID }}-grafana-group-roles-viewer - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: "1" -spec: - deletionPolicy: Delete - forProvider: - exhaustive: false - groupIdRef: - name: users - realmIdRef: - name: {{ .Values.deployments.keycloak.realm.realmid }} - roleIdsSelector: - matchLabels: - platform-engineer.cloud/role: editor - initProvider: {} - managementPolicies: - - '*' - providerConfigRef: - name: sx-keycloak-config ---- -apiVersion: group.keycloak.crossplane.io/v1alpha1 -kind: Roles -metadata: - name: {{ .Values.deployments.keycloak.grafanaclient.config.clientID }}-grafana-group-roles-viewer-team1 - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: "1" -spec: - deletionPolicy: Delete - forProvider: - exhaustive: false - groupIdRef: - name: team1 - realmIdRef: - name: {{ .Values.deployments.keycloak.realm.realmid }} - roleIdsSelector: - matchLabels: - platform-engineer.cloud/role: viewer - initProvider: {} - managementPolicies: - - '*' - providerConfigRef: - name: sx-keycloak-config +{{- range $group := .Values.deployments.keycloak.realm.groups }} +{{- range $role := $group.roles }} --- apiVersion: group.keycloak.crossplane.io/v1alpha1 kind: Roles metadata: - name: {{ .Values.deployments.keycloak.grafanaclient.config.clientID }}-grafana-group-roles-viewer-team-a + name: {{ $.Values.deployments.keycloak.grafanaclient.config.clientID }}-group-roles-{{ $group.name }}-{{ $role }} annotations: argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true argocd.argoproj.io/sync-wave: "1" @@ -82,15 +13,16 @@ spec: forProvider: exhaustive: false groupIdRef: - name: team-a + name: {{ $group.name }} realmIdRef: - name: {{ .Values.deployments.keycloak.realm.realmid }} + name: {{ $.Values.deployments.keycloak.realm.realmid }} roleIdsSelector: matchLabels: - platform-engineer.cloud/role: viewer + platform-engineer.cloud/role: {{ $role }} initProvider: {} managementPolicies: - '*' providerConfigRef: name: sx-keycloak-config ---- \ No newline at end of file +{{- end }} +{{- end }} \ No newline at end of file diff --git a/platform-apps/charts/keycloak/templates/cp-keycloak-realm.yaml b/platform-apps/charts/keycloak/templates/cp-keycloak-realm.yaml index 6e01d17f..61e337fd 100644 --- a/platform-apps/charts/keycloak/templates/cp-keycloak-realm.yaml +++ b/platform-apps/charts/keycloak/templates/cp-keycloak-realm.yaml @@ -8,7 +8,6 @@ metadata: annotations: link.argocd.argoproj.io/external-link: https://{{ .Values.deployments.ingress.host }}/admin/master/console/#/{{ .Values.deployments.keycloak.realm.realmid }} argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: "1" spec: forProvider: realm: {{ .Values.deployments.keycloak.realm.realmid }} diff --git a/platform-apps/charts/keycloak/templates/xr.yaml b/platform-apps/charts/keycloak/templates/xr.yaml index 8dc49a30..c0ffba28 100644 --- a/platform-apps/charts/keycloak/templates/xr.yaml +++ b/platform-apps/charts/keycloak/templates/xr.yaml @@ -29,7 +29,6 @@ metadata: name: keycloak-builtin-objects-{{ .Values.deployments.keycloak.realm.realmid }} annotations: argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: "-1" spec: providerConfigName: sx-keycloak-config providerSecretName: keycloak-credentials-cp diff --git a/platform-apps/charts/keycloak/values-demo-metalstack.yaml b/platform-apps/charts/keycloak/values-demo-metalstack.yaml index 975a6eb4..9ee7a9eb 100644 --- a/platform-apps/charts/keycloak/values-demo-metalstack.yaml +++ b/platform-apps/charts/keycloak/values-demo-metalstack.yaml @@ -84,19 +84,27 @@ deployments: password: "test" groups: - name: admins - mfa: false # valid if .keycloak.mfa.enabled is true, disable for admin + roles: + - grafana-admin + mfa: false # valid if .keycloak.mfa.enabled is true, disable for admin members: - backstageadmin - demoadmin - name: team1 + roles: + - grafana-viewer mfa: true # valid if .keycloak.mfa.enabled is true members: - team1user - name: team-a + roles: + - grafana-viewer mfa: false # valid if .keycloak.mfa.enabled is true members: - team-auser - name: users + roles: + - grafana-editor mfa: false # valid if .keycloak.mfa.enabled is true members: - phac diff --git a/platform-apps/charts/keycloak/values-k3d.yaml b/platform-apps/charts/keycloak/values-k3d.yaml index f62b076b..e646ad19 100644 --- a/platform-apps/charts/keycloak/values-k3d.yaml +++ b/platform-apps/charts/keycloak/values-k3d.yaml @@ -74,13 +74,19 @@ deployments: password: "test" groups: - name: admins + roles: + - grafana-admin members: - backstageadmin - demoadmin - name: team1 + roles: + - grafana-viewer members: - team1user - name: users + roles: + - grafana-editor members: - phac - jokl diff --git a/platform-apps/charts/mimir/values-k3d.yaml b/platform-apps/charts/mimir/values-k3d.yaml index 4f0422d7..bcb6d642 100644 --- a/platform-apps/charts/mimir/values-k3d.yaml +++ b/platform-apps/charts/mimir/values-k3d.yaml @@ -28,4 +28,3 @@ mimir: resources: requests: cpu: 50m - \ No newline at end of file diff --git a/platform-apps/charts/vault/templates/crossplane/cp-authbackend-oidc.yaml b/platform-apps/charts/vault/templates/crossplane/cp-authbackend-oidc.yaml index ddc47c89..be37c5a0 100644 --- a/platform-apps/charts/vault/templates/crossplane/cp-authbackend-oidc.yaml +++ b/platform-apps/charts/vault/templates/crossplane/cp-authbackend-oidc.yaml @@ -44,7 +44,7 @@ metadata: name: oidc-backend-role annotations: argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: "4" + argocd.argoproj.io/sync-wave: "7" spec: providerConfigRef: name: vault-crossplane-providerconfig diff --git a/platform-apps/charts/vault/templates/crossplane/cp-provider.yaml b/platform-apps/charts/vault/templates/crossplane/cp-provider.yaml index 61021562..2992fd3e 100644 --- a/platform-apps/charts/vault/templates/crossplane/cp-provider.yaml +++ b/platform-apps/charts/vault/templates/crossplane/cp-provider.yaml @@ -1,3 +1,21 @@ +apiVersion: pkg.crossplane.io/v1beta1 +kind: DeploymentRuntimeConfig +metadata: + name: debug-config + annotations: + argocd.argoproj.io/sync-wave: "-10" +spec: + deploymentTemplate: + spec: + selector: {} + template: + spec: + containers: + - name: package-runtime + args: + - --poll=1m + - --debug +--- # should move to crossplane ns, maybe? apiVersion: pkg.crossplane.io/v1 kind: Provider @@ -7,3 +25,7 @@ metadata: argocd.argoproj.io/sync-wave: "-10" spec: package: xpkg.upbound.io/upbound/provider-vault:v1.0.0 + runtimeConfigRef: + apiVersion: pkg.crossplane.io/v1beta1 + kind: DeploymentRuntimeConfig + name: debug-config diff --git a/platform-apps/charts/vault/values-k3d.yaml b/platform-apps/charts/vault/values-k3d.yaml index 66fc2ddd..d5b7cb9c 100644 --- a/platform-apps/charts/vault/values-k3d.yaml +++ b/platform-apps/charts/vault/values-k3d.yaml @@ -50,7 +50,7 @@ vault: runAsNonRoot: true extraContainers: - name: auto-initializer - image: hashicorp/vault:1.17.2 + image: hashicorp/vault:1.18.1 env: - name: VAULT_ADDR valueFrom: @@ -92,7 +92,7 @@ vault: runAsNonRoot: true - name: auto-unsealer - image: hashicorp/vault:1.17.2 + image: hashicorp/vault:1.18.1 env: - name: VAULT_ADDR valueFrom: @@ -137,7 +137,7 @@ vault: privileged: false runAsNonRoot: true - name: vault-initializer - image: hashicorp/vault:1.17.2 + image: hashicorp/vault:1.18.1 env: - name: VAULT_ADDR valueFrom: @@ -168,13 +168,13 @@ vault: else - # due to #405 + # due to https://github.com/suxess-it/kubriX/issues/405 if [ ! $(vault read auth/oidc/config) ]; then vault auth enable oidc vault write auth/oidc/config oidc_discovery_url="https://keycloak-127-0-0-1.nip.io/realms/kubrix" oidc_client_id="vault" oidc_client_secret="demosecret" default_role="default" oidc_discovery_ca_pem=@/vault/userconfig/vault-ca/ca.crt fi - # workaround due to #422 + # workaround due to https://github.com/suxess-it/kubriX/issues/422 if [ ! $(vault list identity/group-alias/id) ]; then echo vault admins group configured, just updating group aliases vault list identity/group/name