Skip to content
Draft
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
2 changes: 1 addition & 1 deletion helm-chart/renku/requirements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ dependencies:
repository: "oci://harbor.renkulab.io/bitnami-mirror"
condition: postgresql.enabled
- name: keycloakx
version: 5.0.0
version: 7.1.4
repository: "https://codecentric.github.io/helm-charts"
condition: keycloakx.enabled
- name: redis
Expand Down
103 changes: 30 additions & 73 deletions scripts/init-realm/init-realm.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ def sorted_list(data: List) -> List:
continue

changed = True
warning = (
f"Found mismatch for key '{key}' at {case} '{new_object[id_key]}'!"
)
warning = f"Found mismatch for key '{key}' at {case} '{new_object[id_key]}'!"
logging.warning(warning)

return changed
Expand All @@ -80,9 +78,7 @@ def _fix_json_values(data: Dict) -> Dict:
"""
Fix quoted booleans in the JSON document from the Keycloak API.
"""
return json.loads(
json.dumps(data).replace('"true"', "true").replace('"false"', "false")
)
return json.loads(json.dumps(data).replace('"true"', "true").replace('"false"', "false"))


def _check_and_create_client(keycloak_admin, new_client: OIDCClient, force: bool):
Expand Down Expand Up @@ -121,9 +117,7 @@ def _check_and_create_client(keycloak_admin, new_client: OIDCClient, force: bool
existing_realm_roles = []
if new_client.oauth_flow == OAuthFlow.client_credentials:
try:
service_account_user = keycloak_admin.get_client_service_account_user(
realm_client["id"]
)
service_account_user = keycloak_admin.get_client_service_account_user(realm_client["id"])
except KeycloakGetError as err:
if err.response_code != 404:
raise
Expand All @@ -136,9 +130,7 @@ def _check_and_create_client(keycloak_admin, new_client: OIDCClient, force: bool
if err.response_code != 404:
raise
try:
existing_realm_roles = keycloak_admin.get_realm_roles_of_user(
service_account_user["id"]
)
existing_realm_roles = keycloak_admin.get_realm_roles_of_user(service_account_user["id"])
except KeycloakGetError as err:
if err.response_code != 404:
raise
Expand All @@ -154,9 +146,7 @@ def _check_and_create_client(keycloak_admin, new_client: OIDCClient, force: bool
f"Realm roles changed existing realm roles {set(existing_realm_roles_names)} != new realm roles {set(new_client.service_account_realm_roles)}"
)
roles_changed = True
changed = _check_existing(
realm_client, new_client.to_dict(), "client", "clientId"
)
changed = _check_existing(realm_client, new_client.to_dict(), "client", "clientId")

if not force or (not changed and not roles_changed):
return
Expand All @@ -165,18 +155,15 @@ def _check_and_create_client(keycloak_admin, new_client: OIDCClient, force: bool

keycloak_admin.delete_client(realm_client["id"])
created_client_id = keycloak_admin.create_client(new_client.to_dict())
service_account_user = keycloak_admin.get_client_service_account_user(
created_client_id
)
if new_client.oauth_flow == OAuthFlow.client_credentials:
service_account_user = keycloak_admin.get_client_service_account_user(created_client_id)
else:
service_account_user = None

if isinstance(service_account_user, dict) and service_account_user.get("id"):
if new_client.service_account_roles:
logging.info(
f"Reassigning service account roles {new_client.service_account_roles}"
)
realm_management_roles = keycloak_admin.get_client_roles(
realm_management_client_id
)
logging.info(f"Reassigning service account roles {new_client.service_account_roles}")
realm_management_roles = keycloak_admin.get_client_roles(realm_management_client_id)
matching_roles = [
{"name": role["name"], "id": role["id"]}
for role in realm_management_roles
Expand All @@ -187,19 +174,15 @@ def _check_and_create_client(keycloak_admin, new_client: OIDCClient, force: bool
service_account_user["id"], realm_management_client_id, matching_roles
)
if new_client.service_account_realm_roles:
logging.info(
f"Reassigning service account realm roles {new_client.service_account_realm_roles}"
)
logging.info(f"Reassigning service account realm roles {new_client.service_account_realm_roles}")
all_realm_roles = keycloak_admin.get_realm_roles()
matching_realm_roles = [
{"name": role["name"], "id": role["id"]}
for role in all_realm_roles
if role["name"] in new_client.service_account_realm_roles
]
logging.info(f"Found and assigning matching realm roles: {matching_realm_roles}")
keycloak_admin.assign_realm_roles(
user_id=service_account_user["id"], roles=matching_realm_roles
)
keycloak_admin.assign_realm_roles(user_id=service_account_user["id"], roles=matching_realm_roles)

logging.info("done")

Expand All @@ -208,19 +191,11 @@ def _check_and_create_client(keycloak_admin, new_client: OIDCClient, force: bool
logging.info("Creating {} client...".format(new_client.id))
created_client_id = keycloak_admin.create_client(new_client.to_dict())
if new_client.oauth_flow == OAuthFlow.client_credentials:
service_account_user = keycloak_admin.get_client_service_account_user(
created_client_id
)
service_account_user = keycloak_admin.get_client_service_account_user(created_client_id)
if new_client.service_account_roles:
logging.info(
f"Assigning service account roles {new_client.service_account_roles}"
)
realm_management_client_id = keycloak_admin.get_client_id(
"realm-management"
)
realm_management_roles = keycloak_admin.get_client_roles(
realm_management_client_id
)
logging.info(f"Assigning service account roles {new_client.service_account_roles}")
realm_management_client_id = keycloak_admin.get_client_id("realm-management")
realm_management_roles = keycloak_admin.get_client_roles(realm_management_client_id)
matching_roles = [
{"name": role["name"], "id": role["id"]}
for role in realm_management_roles
Expand All @@ -231,19 +206,15 @@ def _check_and_create_client(keycloak_admin, new_client: OIDCClient, force: bool
service_account_user["id"], realm_management_client_id, matching_roles
)
if new_client.service_account_realm_roles:
logging.info(
f"Assigning service account realm roles {new_client.service_account_realm_roles}"
)
logging.info(f"Assigning service account realm roles {new_client.service_account_realm_roles}")
all_realm_roles = keycloak_admin.get_realm_roles()
matching_realm_roles = [
{"name": role["name"], "id": role["id"]}
for role in all_realm_roles
if role["name"] in new_client.service_account_realm_roles
]
logging.info(f"Found and assigning matching realm roles: {matching_realm_roles}")
keycloak_admin.assign_realm_roles(
user_id=service_account_user["id"], roles=matching_realm_roles
)
keycloak_admin.assign_realm_roles(user_id=service_account_user["id"], roles=matching_realm_roles)

logging.info("done")

Expand Down Expand Up @@ -271,9 +242,7 @@ def _check_and_create_user(keycloak_admin, new_user):
logging.info("Creating user {} ...".format(new_user["username"]))
keycloak_admin.create_user(payload=new_user)
new_user_id = keycloak_admin.get_user_id(new_user["username"])
keycloak_admin.set_user_password(
new_user_id, new_user_password, temporary=False
)
keycloak_admin.set_user_password(new_user_id, new_user_password, temporary=False)
logging.info("done")


Expand All @@ -286,9 +255,7 @@ def _wait_for_tls(url: str, retries=60, wait_secs=2):
requests.get(url, allow_redirects=True)
except (ConnectionError, SSLError) as err:
if cur_retry >= retries:
raise Exception(
"Timed out trying to wait for name resolution or TLS"
) from err
raise Exception("Timed out trying to wait for name resolution or TLS") from err
logging.warning("Failed name resolution or TLS, will wait and retry.")
time.sleep(wait_secs)
else:
Expand Down Expand Up @@ -366,7 +333,9 @@ def _wait_for_tls(url: str, retries=60, wait_secs=2):
else:
logging.info(
"Could not get a token. Is Keycloak \
running under {}?".format(args.keycloak_url)
running under {}?".format(
args.keycloak_url
)
)
exit(1)

Expand All @@ -392,16 +361,10 @@ def _wait_for_tls(url: str, retries=60, wait_secs=2):
realm = keycloak_admin.get_realm(args.realm)
event_retention_seconds = 86400
if not realm.get("eventsEnabled"):
logging.info(
f"Enabling user events tracking for realm with retention {event_retention_seconds}"
)
keycloak_admin.update_realm(
args.realm, {"eventsEnabled": True, "eventsExpiration": event_retention_seconds}
)
logging.info(f"Enabling user events tracking for realm with retention {event_retention_seconds}")
keycloak_admin.update_realm(args.realm, {"eventsEnabled": True, "eventsExpiration": event_retention_seconds})
if not realm.get("adminEventsEnabled"):
logging.info(
f"Enabling admin events tracking for realm with retention {event_retention_seconds}"
)
logging.info(f"Enabling admin events tracking for realm with retention {event_retention_seconds}")
keycloak_admin.update_realm(
args.realm,
{
Expand Down Expand Up @@ -430,9 +393,7 @@ def _wait_for_tls(url: str, retries=60, wait_secs=2):
keycloak_admin.create_realm_role(realm_role_payload, skip_exists=True)

# Create alertmanager-webhook realm role
logging.info(
"Creating alertmanager-webhook realm role, skipping if it already exists..."
)
logging.info("Creating alertmanager-webhook realm role, skipping if it already exists...")
alertmanager_webhook_realm_role_payload = {
"name": "alertmanager-webhook",
"composite": True,
Expand All @@ -443,9 +404,7 @@ def _wait_for_tls(url: str, retries=60, wait_secs=2):
},
"clientRole": False,
}
keycloak_admin.create_realm_role(
alertmanager_webhook_realm_role_payload, skip_exists=True
)
keycloak_admin.create_realm_role(alertmanager_webhook_realm_role_payload, skip_exists=True)

logging.info("done")

Expand All @@ -458,9 +417,7 @@ def _wait_for_tls(url: str, retries=60, wait_secs=2):

if os.environ.get("ALERTMANAGER_WEBHOOK_OIDC_ENABLED", "false").lower() == "true":
alertmanager_webhook_oidc_client = OIDCAlertmanagerWebhookClient.from_env()
_check_and_create_client(
keycloak_admin, alertmanager_webhook_oidc_client, args.force
)
_check_and_create_client(keycloak_admin, alertmanager_webhook_oidc_client, args.force)

demo_user = DemoUserConfig.from_env().to_dict()
if demo_user is not None:
Expand Down
Loading