Skip to content

Commit

Permalink
packaging: setup: Add keycloak_utils
Browse files Browse the repository at this point in the history
with a single function, for now, keycloak_env_from_engine_conf.

Change-Id: I8d03c2ce9ec8fdad8afd796317ff1e69ea55ecbe
Signed-off-by: Yedidyah Bar David <didi@redhat.com>
  • Loading branch information
didib committed Oct 18, 2022
1 parent 7a65853 commit d87c846
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 0 deletions.
6 changes: 6 additions & 0 deletions packaging/setup/ovirt_engine_setup/engine/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,12 @@ class FileLocations(object):
OVIRT_ENGINE_SERVICE_CONFIGD,
'11-setup-sso.conf',
)
# TODO: Make ovirt-engine-keycloak use
# OVIRT_ENGINE_SERVICE_CONFIG_KEYCLOAK from here instead of its own copy.
OVIRT_ENGINE_SERVICE_CONFIG_KEYCLOAK = os.path.join(
OVIRT_ENGINE_SERVICE_CONFIGD,
'12-setup-keycloak.conf'
)

OVIRT_ENGINE_NOTIFIER_SERVICE_CONFIGD = (
'%s.d' % OVIRT_ENGINE_NOTIFIER_SERVICE_CONFIG
Expand Down
115 changes: 115 additions & 0 deletions packaging/setup/ovirt_engine_setup/engine_common/keycloak_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#
# ovirt-engine-setup -- ovirt engine setup
#
# Copyright oVirt Authors
# SPDX-License-Identifier: Apache-2.0
#
#


"""Keycloak Utilities"""


from ovirt_engine import configfile

from ovirt_engine_setup.engine_common import constants as oengcommcons


def keycloak_env_from_engine_conf(content):
"""
Parse content of 12-setup-keycloak.conf and return a dictionary
that can be merged into the otopi environment for KeycloakEnv.
Input: content of a 12-setup-keycloak.conf file, as a list/tuple
of strings.
Output: A dictionary with keys/values matching
self.environment[KeycloakEnv] ones.
In principle, this is the opposite of the code generating this file,
in plugins/ovirt-engine-setup/ovirt-engine-keycloak/config/keycloak.py .
The input is intentionally only the content and not a file, to make it
useful also for a remote engine case.
I only handle here leycloak-specific keys, and for now, only those I need
for grafana. Specifically, not ENGINE_SSO_EXTERNAL_SSO_LOGOUT_URI, which
refers to "${ENGINE_URI}", and not KEYCLOAK_OVIRT_ADMIN_USER_WITH_PROFILE,
which is used by OVN. So it probably means that this isn't enough for
configuring OVN via --reconfigure-optional-components.
The result does not include ENABLE, which is not in the engine conf, but
in the engine-setup conf, and should be checked beforehand.
"""
res = {}
config = configfile.ConfigFile()
for line in content:
# TODO: Expose _loadLine in ConfigFile and use that?
# Some other interface?
# Right now it only supports reading from files, which is not
# very convenient/natural for a remote engine.
config._loadLine(line)

for e, k in (
(
oengcommcons.KeycloakEnv.KEYCLOAK_TOKEN_URL,
'EXTERNAL_OIDC_TOKEN_END_POINT'
),
(
oengcommcons.KeycloakEnv.KEYCLOAK_USERINFO_URL,
'EXTERNAL_OIDC_USER_INFO_END_POINT'
),
(
oengcommcons.KeycloakEnv.KEYCLOAK_OVIRT_INTERNAL_CLIENT_ID,
'EXTERNAL_OIDC_CLIENT_ID'
),
(
oengcommcons.KeycloakEnv.KEYCLOAK_OVIRT_INTERNAL_CLIENT_SECRET,
'EXTERNAL_OIDC_CLIENT_SECRET'
),
):
res[e] = config.get(k)

# The following are hard-coded, for now.
# TODO: Somehow unite with the copy in ovirt-engine-keycloak constants.
# Perhaps move to some common package that both can use.
# Can't require it directly right now because it pulls the entire engine
# with it, which we do not want to happen on a setup where grafana is
# on a separate remote machine.
for e, const in (
(
oengcommcons.KeycloakEnv.KEYCLOAK_GRAFANA_ADMIN_ROLE,
'grafana-admin'
),
(
oengcommcons.KeycloakEnv.KEYCLOAK_GRAFANA_EDITOR_ROLE,
'grafana-editor'
),
(
oengcommcons.KeycloakEnv.KEYCLOAK_GRAFANA_VIEWER_ROLE,
'grafana-viewer'
),
):
res[e] = const

# Handle KEYCLOAK_AUTH_URL. This is not saved in the config as-is, so
# need to be synthesized. In ovirt-engine-keycloak code, this is done
# using a function called _build_endpoint_url which is used also for
# other stuff, including the token, where the result is different only
# in the final part after the last '/'. Let's rely on that for now.
token_string_end = '/token'
if res[
oengcommcons.KeycloakEnv.KEYCLOAK_TOKEN_URL
].endswith(
token_string_end
):
res[
oengcommcons.KeycloakEnv.KEYCLOAK_AUTH_URL
] = res[
oengcommcons.KeycloakEnv.KEYCLOAK_TOKEN_URL
][:-len(token_string_end)] + '/auth'

return res


# vim: expandtab tabstop=4 shiftwidth=4

0 comments on commit d87c846

Please sign in to comment.