Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export SPAWN_RATE ?= 20

# Used to set logging level of RHDH
export RHDH_LOG_LEVEL ?= warn
export KEYCLOAK_LOG_LEVEL ?= WARN

# RHDH image to deploy. Uncomment and set to override RHDH image to deploy and test.
export RHDH_IMAGE_REGISTRY ?=
Expand Down
27 changes: 16 additions & 11 deletions ci-scripts/rhdh-setup/create_resource.sh
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ get_group_path_by_name() {
local group_name="$input"
token=$(get_token)

response=$(curl -s -k --location --request GET "$(keycloak_url)/auth/admin/realms/backstage/groups?search=${group_name}" \
response=$(curl -s -k --location --request GET "$(keycloak_url)/admin/realms/backstage/groups?search=${group_name}" \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $token" 2>&1)

Expand All @@ -224,7 +224,7 @@ get_group_id_by_name() {
group_name="$1"
token=$(get_token)

response=$(curl -s -k --location --request GET "$(keycloak_url)/auth/admin/realms/backstage/groups?search=${group_name}" \
response=$(curl -s -k --location --request GET "$(keycloak_url)/admin/realms/backstage/groups?search=${group_name}" \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $token" 2>&1)

Expand Down Expand Up @@ -272,7 +272,7 @@ assign_parent_group() {
attempt=1
while ((attempt <= max_attempts)); do
token=$(get_token)
response="$(curl -s -k --location --request POST "$(keycloak_url)/auth/admin/realms/backstage/groups/${parent_id}/children" \
response="$(curl -s -k --location --request POST "$(keycloak_url)/admin/realms/backstage/groups/${parent_id}/children" \
-H 'Content-Type: application/json' -H "Authorization: Bearer $token" \
--data-raw '{"name":"'"${child_name}"'"}' 2>&1)"
if [ "${PIPESTATUS[0]}" -eq 0 ] && ! echo "$response" | grep -q 'error' >&/dev/null; then
Expand All @@ -299,7 +299,7 @@ create_group() {
groupname="g${idx}"
while ((attempt <= max_attempts)); do
token=$(get_token)
response="$(curl -s -k --location --request POST "$(keycloak_url)/auth/admin/realms/backstage/groups" \
response="$(curl -s -k --location --request POST "$(keycloak_url)/admin/realms/backstage/groups" \
-H 'Content-Type: application/json' -H "Authorization: Bearer $token" \
--data-raw '{"name":"'"${groupname}"'"}' 2>&1)"
if [ "${PIPESTATUS[0]}" -eq 0 ] && ! echo "$response" | grep -q 'error' >&/dev/null; then
Expand All @@ -322,7 +322,7 @@ create_group() {
groupname="g${idx}"
while ((attempt <= max_attempts)); do
token=$(get_token)
response="$(curl -s -k --location --request POST "$(keycloak_url)/auth/admin/realms/backstage/groups" \
response="$(curl -s -k --location --request POST "$(keycloak_url)/admin/realms/backstage/groups" \
-H 'Content-Type: application/json' -H "Authorization: Bearer $token" \
--data-raw '{"name":"'"${groupname}"'"}' 2>&1)"
if [ "${PIPESTATUS[0]}" -eq 0 ] && ! echo "$response" | grep -q 'error' >&/dev/null; then
Expand Down Expand Up @@ -454,13 +454,13 @@ create_user() {
groups="$groups]"
while ((attempt <= max_attempts)); do
token=$(get_token)
username="t${0}"
response="$(curl -s -k --location --request POST "$(keycloak_url)/auth/admin/realms/backstage/users" \
username="t_${0}"
response="$(curl -s -k --location --request POST "$(keycloak_url)/admin/realms/backstage/users" \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer '"$token" \
--data-raw '{"firstName":"'"${username}"'","lastName":"tester", "email":"'"${username}"'@test.com","emailVerified":"true", "enabled":"true", "username":"'"${username}"'","groups":'"$groups"',"credentials":[{"type":"password","value":"'"${KEYCLOAK_USER_PASS}"'","temporary":false}]}' 2>&1)"
if [ "${PIPESTATUS[0]}" -eq 0 ] && ! echo "$response" | grep -q 'error' >&/dev/null; then
log_info "User $username ($groups) created" >>"$TMP_DIR/create_user.log"
log_info "User $username ($groups) created. [$response]" >>"$TMP_DIR/create_user.log"
return
else
log_warn "Unable to create the $username user at $attempt. attempt. [$response]. Trying again up to $max_attempts times." >>"$TMP_DIR/create_user.log"
Expand All @@ -482,8 +482,13 @@ create_users() {

token_lockfile="$TMP_DIR/token.lockfile"


keycloak_token() {
curl -s -k "$(keycloak_url)/auth/realms/master/protocol/openid-connect/token" -d username=admin -d "password=$1" -d 'grant_type=password' -d 'client_id=admin-cli' | jq -r ".expires_in_timestamp = $(python3 -c 'from datetime import datetime, timedelta; t_add=int(30); print(int((datetime.now() + timedelta(seconds=t_add)).timestamp()))')"
curl -s -k "$(keycloak_url)/realms/master/protocol/openid-connect/token" \
-d username=temp-admin \
-d "password=$1" \
-d 'grant_type=password' \
-d 'client_id=admin-cli' | jq -r ".expires_in_timestamp = $(python3 -c 'from datetime import datetime, timedelta; t_add=int(30); print(int((datetime.now() + timedelta(seconds=t_add)).timestamp()))')"
}

rhdh_token() {
Expand All @@ -510,7 +515,7 @@ rhdh_token() {
--data-urlencode "redirect_uri=${REDIRECT_URL}" \
--data-urlencode "scope=openid email profile" \
--data-urlencode "response_type=code" \
"$(keycloak_url)/auth/realms/$REALM/protocol/openid-connect/auth" 2>&1 | tee "$TMP_DIR/auth_url.log" | grep -oE 'action="[^"]+"' | grep -oE '"[^"]+"' | tr -d '"')
"$(keycloak_url)/realms/$REALM/protocol/openid-connect/auth" 2>&1| tee "$TMP_DIR/auth_url.log" | grep -oE 'action="[^"]+"' | grep -oE '"[^"]+"' | tr -d '"')

execution=$(echo "$AUTH_URL" | grep -oE 'execution=[^&]+' | grep -oE '[^=]+$')
tab_id=$(echo "$AUTH_URL" | grep -oE 'tab_id=[^&]+' | grep -oE '[^=]+$')
Expand Down Expand Up @@ -572,7 +577,7 @@ get_token() {
log_token_err "Unable to get $token_type token, re-attempting"
fi
else
keycloak_pass=$(oc -n "${RHDH_NAMESPACE}" get secret credential-rhdh-sso -o template --template='{{.data.ADMIN_PASSWORD}}' | base64 -d)
keycloak_pass=$(oc -n "${RHDH_NAMESPACE}" get secret rhdh-keycloak-initial-admin -o template --template='{{.data.password}}'| base64 -d)
if ! keycloak_token "$keycloak_pass" >"$token_file"; then
log_token_err "Unable to get $token_type token, re-attempting"
fi
Expand Down
54 changes: 48 additions & 6 deletions ci-scripts/rhdh-setup/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export FORCE_ORCHESTRATOR_INFRA_UNINSTALL="${FORCE_ORCHESTRATOR_INFRA_UNINSTALL:
export ENABLE_PROFILING="${ENABLE_PROFILING:-false}"
export RBAC_POLICY="${RBAC_POLICY:-all_groups_admin}"
export RHDH_LOG_LEVEL="${RHDH_LOG_LEVEL:-warn}"
export KEYCLOAK_LOG_LEVEL="${KEYCLOAK_LOG_LEVEL:-WARN}"

export PSQL_LOG="${PSQL_LOG:-true}"
export RHDH_METRIC="${RHDH_METRIC:-true}"
Expand Down Expand Up @@ -238,11 +239,28 @@ keycloak_install() {
)
envsubst <template/keycloak/keycloak-op.yaml | $clin apply -f -
envsubst <template/backstage/perf-test-secrets.yaml | $clin apply -f -
grep -m 1 "rhsso-operator" <($clin get pods -w)
wait_to_start deployment rhsso-operator 300 300
grep -m 1 "rhbk-operator" <($clin get pods -w)
wait_to_start deployment rhbk-operator 300 300

export KEYCLOAK_DB_PASSWORD
KEYCLOAK_DB_PASSWORD=$(mktemp -u XXXXXXXXXX)
export KEYCLOAK_DB_STORAGE
KEYCLOAK_DB_STORAGE=${KEYCLOAK_DB_STORAGE:-${RHDH_DB_STORAGE:-1Gi}}

log_info "Creating Keycloak PostgreSQL database with storage: $KEYCLOAK_DB_STORAGE"
envsubst <template/keycloak/keycloak-postgresql.yaml | $clin apply -f -
wait_to_start statefulset keycloak-postgresql 300 300

$clin create secret generic keycloak-db-user --from-literal=keycloak-db-user=keycloak --dry-run=client -o yaml | $clin apply -f -

envsubst <template/keycloak/keycloak.yaml | $clin apply -f -
wait_to_start statefulset keycloak 450 600
envsubst <template/keycloak/keycloakRealm.yaml | $clin apply -f -
wait_to_start statefulset rhdh-keycloak 450 600

$clin create route edge keycloak \
--service=rhdh-keycloak-service \
--port=8080 \
--dry-run=client -o yaml | $clin apply -f -

if [ "$INSTALL_METHOD" == "helm" ]; then
export OAUTH2_REDIRECT_URI="https://${RHDH_HELM_RELEASE_NAME}-developer-hub-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}/oauth2/callback"
elif [ "$INSTALL_METHOD" == "olm" ]; then
Expand All @@ -252,9 +270,33 @@ keycloak_install() {
export OAUTH2_REDIRECT_URI="https://backstage-developer-hub-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}/oauth2/callback"
fi
fi
envsubst <template/keycloak/keycloakClient.yaml | $clin apply -f -
# shellcheck disable=SC2016
envsubst '${KEYCLOAK_USER_PASS}' <template/keycloak/keycloakUser.yaml | $clin apply -f -
envsubst '${KEYCLOAK_CLIENT_SECRET} ${OAUTH2_REDIRECT_URI} ${KEYCLOAK_USER_PASS}' <template/keycloak/keycloakRealmImport.yaml | $clin apply -f -
$clin create secret generic keycloak-client-secret-backstage --from-literal=CLIENT_ID=backstage --from-literal=CLIENT_SECRET="$KEYCLOAK_CLIENT_SECRET" --dry-run=client -o yaml | oc apply -f -
# Wait up to 1 minute for completion realm generation
$clin wait --for=condition=Done keycloakrealmimport/backstage-realm-import --timeout=60s
assign_roles_to_client
}

assign_roles_to_client() {
ADMIN_TOKEN=$(get_token "keycloak")
SA_USER_ID=$(curl -s -k "$(keycloak_url)/admin/realms/backstage/users?username=service-account-backstage" -H "Authorization: Bearer $ADMIN_TOKEN" | jq -r '.[0].id')
REALM_MGMT_ID=$(curl -s -k "$(keycloak_url)/admin/realms/backstage/clients?clientId=realm-management" -H "Authorization: Bearer $ADMIN_TOKEN" | jq -r '.[0].id')

ROLE_NAMES=$(curl -s -k "$(keycloak_url)/admin/realms/backstage/clients/$REALM_MGMT_ID/roles" -H "Authorization: Bearer $ADMIN_TOKEN" | jq -r '.[].name')

while IFS= read -r role_name; do
[ -z "$role_name" ] && continue

ROLE_JSON=$(curl -s -k "$(keycloak_url)/admin/realms/backstage/clients/$REALM_MGMT_ID/roles/$role_name" \
-H "Authorization: Bearer $ADMIN_TOKEN")

curl -s -k -X POST \
"$(keycloak_url)/admin/realms/backstage/users/$SA_USER_ID/role-mappings/clients/$REALM_MGMT_ID" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d "[$ROLE_JSON]"
done <<< "$ROLE_NAMES"
}

create_users_groups() {
Expand Down
4 changes: 2 additions & 2 deletions ci-scripts/rhdh-setup/template/backstage/app-config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
app:
\app:
title: Red Hat Developer Hub
analytics:
adoptionInsights: {}
Expand All @@ -25,7 +25,7 @@ catalog:
frequency:
hours: 2
timeout:
minutes: 1
minutes: 10
initialDelay:
minutes: 1
techdocs:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ upstream:
key: github.token
name: "{{ .Release.Name }}-plugin-secrets"
- name: KEYCLOAK_BASE_URL
value: "https://keycloak-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}/auth"
value: "https://keycloak-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}"
- name: KEYCLOAK_LOGIN_REALM
value: "backstage"
- name: KEYCLOAK_REALM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ upstream:
key: github.token
name: "{{ .Release.Name }}-plugin-secrets"
- name: KEYCLOAK_BASE_URL
value: "https://keycloak-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}/auth"
value: "https://keycloak-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}"
- name: KEYCLOAK_LOGIN_REALM
value: "backstage"
- name: KEYCLOAK_REALM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ extraContainers:
key: keycloak_cookie_secret
name: perf-test-secrets
- name: OAUTH2_PROXY_OIDC_ISSUER_URL
value: https://keycloak-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}/auth/realms/backstage
value: https://keycloak-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}/realms/backstage
- name: OAUTH2_PROXY_SSL_INSECURE_SKIP_VERIFY
value: "true"
- name: OAUTH2_PROXY_LOGGING_LEVEL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ spec:
extraEnvs:
envs:
- name: KEYCLOAK_BASE_URL
value: "https://keycloak-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}/auth"
value: "https://keycloak-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}"
- name: KEYCLOAK_LOGIN_REALM
value: "backstage"
- name: KEYCLOAK_REALM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ spec:
key: keycloak_cookie_secret
name: perf-test-secrets
- name: OAUTH2_PROXY_OIDC_ISSUER_URL
value: https://keycloak-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}/auth/realms/backstage
value: https://keycloak-${RHDH_NAMESPACE}.${OPENSHIFT_APP_DOMAIN}/realms/backstage
- name: OAUTH2_PROXY_SSL_INSECURE_SKIP_VERIFY
value: "true"
image: quay.io/oauth2-proxy/oauth2-proxy:v7.12.0
Expand Down
8 changes: 4 additions & 4 deletions ci-scripts/rhdh-setup/template/keycloak/keycloak-op.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
name: rhsso-operator-group
name: rhbk-operator-group
spec:
targetNamespaces:
- ${RHDH_NAMESPACE}
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: rhsso-operator
name: rhbk-operator
spec:
channel: stable
name: rhsso-operator
channel: stable-v26.0
name: rhbk-operator
source: redhat-operators
sourceNamespace: openshift-marketplace
installPlanApproval: Automatic
103 changes: 103 additions & 0 deletions ci-scripts/rhdh-setup/template/keycloak/keycloak-postgresql.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
apiVersion: v1
kind: Secret
metadata:
name: keycloak-postgresql
labels:
app: keycloak-postgresql
type: Opaque
stringData:
postgres-password: ${KEYCLOAK_DB_PASSWORD}
password: ${KEYCLOAK_DB_PASSWORD}
replication-password: ${KEYCLOAK_DB_PASSWORD}
---
apiVersion: v1
kind: Service
metadata:
name: keycloak-postgresql
labels:
app: keycloak-postgresql
spec:
type: ClusterIP
ports:
- name: tcp-postgresql
port: 5432
targetPort: tcp-postgresql
selector:
app: keycloak-postgresql
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: keycloak-postgresql
labels:
app: keycloak-postgresql
spec:
serviceName: keycloak-postgresql
replicas: 1
selector:
matchLabels:
app: keycloak-postgresql
template:
metadata:
labels:
app: keycloak-postgresql
spec:
containers:
- name: postgresql
image: registry.redhat.io/rhel9/postgresql-15:latest
imagePullPolicy: IfNotPresent
ports:
- name: tcp-postgresql
containerPort: 5432
env:
- name: POSTGRESQL_USER
value: keycloak
- name: POSTGRESQL_PASSWORD
valueFrom:
secretKeyRef:
name: keycloak-postgresql
key: password
- name: POSTGRESQL_DATABASE
value: keycloak
- name: POSTGRESQL_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: keycloak-postgresql
key: postgres-password
- name: PGDATA
value: /var/lib/pgsql/data/userdata
volumeMounts:
- name: data
mountPath: /var/lib/pgsql/data
livenessProbe:
exec:
command:
- /bin/sh
- -c
- exec pg_isready -U keycloak -d keycloak -h 127.0.0.1 -p 5432
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 6
readinessProbe:
exec:
command:
- /bin/sh
- -c
- exec pg_isready -U keycloak -d keycloak -h 127.0.0.1 -p 5432
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 6
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: ${KEYCLOAK_DB_STORAGE}
Loading