From 12e90e66fa90577ffdced86d6f1de605207a8aea Mon Sep 17 00:00:00 2001 From: Yedidyah Bar David Date: Wed, 21 Sep 2022 10:39:40 +0300 Subject: [PATCH] packaging: setup: Fix configuring grafana with keycloak With this flow: 1. Setup an engine with keycloak, no dwh/grafana 2. engine-setup --reconfigure-optional-components, enable dwh+grafana keycloak is already configured, but we do want to configure grafana to use keycloak. So remove the condition that we only do this if keycloak is not configured yet. Also support configuring grafana on a separate machine when keycloak on the engine machine is configured. Requires [1]. spec updated to require 4.5.4 engine-setup to get it. [1] https://github.com/oVirt/ovirt-engine/pull/669 Change-Id: I019335c60f686d139da0e9368147e035db75ba37 Signed-off-by: Yedidyah Bar David --- ovirt-engine-dwh.spec.in | 2 +- .../ovirt-engine-grafana-dwh/core/config.py | 117 +++++++++++++++--- 2 files changed, 102 insertions(+), 17 deletions(-) diff --git a/ovirt-engine-dwh.spec.in b/ovirt-engine-dwh.spec.in index 5873c55..d17d2dc 100644 --- a/ovirt-engine-dwh.spec.in +++ b/ovirt-engine-dwh.spec.in @@ -152,7 +152,7 @@ Requires: postgresql-contrib >= 12.0 %package grafana-integration-setup Summary: %{product_name} Grafana integration setup Group: Virtualization/Management -Requires: ovirt-engine-setup-plugin-ovirt-engine-common >= 4.5.3 +Requires: ovirt-engine-setup-plugin-ovirt-engine-common >= 4.5.4 Requires: %{name}-setup = %{version}-%{release} Requires: grafana >= 7.3 Requires: grafana-postgres >= 7.3 diff --git a/packaging/setup/plugins/ovirt-engine-setup/ovirt-engine-grafana-dwh/core/config.py b/packaging/setup/plugins/ovirt-engine-setup/ovirt-engine-grafana-dwh/core/config.py index 75ef374..b339689 100644 --- a/packaging/setup/plugins/ovirt-engine-setup/ovirt-engine-grafana-dwh/core/config.py +++ b/packaging/setup/plugins/ovirt-engine-setup/ovirt-engine-grafana-dwh/core/config.py @@ -25,6 +25,7 @@ from ovirt_engine_setup.engine import constants as oenginecons from ovirt_engine_setup.engine_common import constants as oengcommcons +from ovirt_engine_setup.engine_common import keycloak_utils from ovirt_engine_setup import constants as osetupcons from ovirt_engine_setup.grafana_dwh import constants as ogdwhcons from ovirt_setup_lib import dialog @@ -69,6 +70,15 @@ def _init(self): oengcommcons.KeycloakEnv.ENABLE, None, ) + self._keycloak_enabled_on_remote_engine = None + + @plugin.event( + stage=plugin.Stages.STAGE_LATE_SETUP, + ) + def _late_setup(self): + self._remote_engine = self.environment[ + osetupcons.CoreEnv.REMOTE_ENGINE + ] @plugin.event( stage=plugin.Stages.STAGE_CUSTOMIZATION, @@ -184,9 +194,6 @@ def _customization_sso(self): if self.environment[oenginecons.CoreEnv.ENABLE]: self._register_sso_client = True else: - self._remote_engine = self.environment[ - osetupcons.CoreEnv.REMOTE_ENGINE - ] fd, tmpconf = tempfile.mkstemp() atexit.register(os.unlink, tmpconf) cmd = self._get_sso_client_registration_cmd(tmpconf) @@ -224,6 +231,90 @@ def _customization_sso(self): f.write(res) self._process_sso_client_registration_result(tmpconf) + def _check_if_keycloak_enabled_on_remote_engine(self): + cmd = ( + 'otopi-config-query query ' + '-k OVESETUP_CONFIG/keycloakEnable ' + '-f /etc/ovirt-engine-setup.conf' + ) + res = self._remote_engine.execute_on_engine( + cmd=cmd, + timeout=120, + text=_( + '\nPlease run the following command on the engine ' + 'machine {engine_fqdn}, and note the output.\n\n' + '{cmd}\n' + ).format( + engine_fqdn=self.environment[ + oenginecons.ConfigEnv.ENGINE_FQDN + ], + cmd=cmd, + ), + ) + if res is None: + # Likely using manual_files. Ask the user. + remote_keycloak_enabled = dialog.queryBoolean( + dialog=self.dialog, + name='GRAFANA_REMOTE_ENGINE_KEYCLOAK_ENABLED', + note=_( + 'Was the output of the command "True"? ' + '(@VALUES@) [@DEFAULT@]: ' + ), + prompt=True, + default=True, + ) + else: + remote_keycloak_enabled = ( + b''.join(res['stdout']).decode().strip() == 'True' + ) + return remote_keycloak_enabled + + @plugin.event( + stage=plugin.Stages.STAGE_CUSTOMIZATION, + before=( + osetupcons.Stages.DIALOG_TITLES_E_MISC, + ), + after=( + osetupcons.Stages.DIALOG_TITLES_S_MISC, + ), + condition=lambda self: ( + self.environment[ogdwhcons.CoreEnv.ENABLE] + ), + ) + def _customization_grafana_config(self): + # Update the environment where needed - on a separate machine, or + # when keycloak was already configured in a previous run. + config_content = None + config_filename = ( + oenginecons.FileLocations.OVIRT_ENGINE_SERVICE_CONFIG_KEYCLOAK + ) + if self.environment[oenginecons.CoreEnv.ENABLE]: + # We are on the engine machine + if ( + self.environment[ogdwhcons.ConfigEnv.NEW_DATABASE] and + self.environment[oengcommcons.KeycloakEnv.ENABLE] and + self.environment[oengcommcons.KeycloakEnv.CONFIGURED] + ): + # Relevant flow: + # 1. engine-setup - enable keycloak, disable grafana + # 2. engine-setup --reconfigure-optional-components, enable + # grafana. + with open(config_filename) as f: + config_content = f.read().splitlines() + else: + # Engine is remote + if self.environment[ogdwhcons.ConfigEnv.NEW_DATABASE]: + if self._check_if_keycloak_enabled_on_remote_engine(): + self._keycloak_enabled_on_remote_engine = True + config_content = self._remote_engine.copy_from_engine( + file_name=config_filename, + dialog_name='GRAFANA_REMOTE_ENGINE_KEYCLOAK_CONF', + ).decode().splitlines() + if config_content: + self.environment.update( + keycloak_utils.keycloak_env_from_engine_conf(config_content) + ) + @plugin.event( stage=plugin.Stages.STAGE_MISC, name=ogdwhcons.Stages.GRAFANA_CONFIG, @@ -237,7 +328,7 @@ def _customization_sso(self): ( self.environment[oengcommcons.KeycloakEnv.ENABLE] and not self.environment[oengcommcons.KeycloakEnv.CONFIGURED] - ) + ) or self._keycloak_enabled_on_remote_engine ) ) ) @@ -290,10 +381,10 @@ def _misc_grafana_config(self): role_attr = '' # override configuration for internal Keycloak based SSO - keycloak_enabled = self.environment.get(oengcommcons.KeycloakEnv.ENABLE) - keycloak_configured = self.environment.get(oengcommcons.KeycloakEnv.CONFIGURED) - - if keycloak_enabled and not keycloak_configured: + if ( + self.environment.get(oengcommcons.KeycloakEnv.ENABLE) or + self._keycloak_enabled_on_remote_engine + ): auth_url = self.environment[ oengcommcons.KeycloakEnv.KEYCLOAK_AUTH_URL ] @@ -394,14 +485,8 @@ def _misc_engine_grafana_access(self): ), condition=lambda self: ( self.environment[ogdwhcons.CoreEnv.ENABLE] and - not self.environment[oenginecons.CoreEnv.ENABLE] and - ( - self.environment[ogdwhcons.ConfigEnv.NEW_DATABASE] or - ( - self.environment[oengcommcons.KeycloakEnv.ENABLE] and - not self.environment[oengcommcons.KeycloakEnv.CONFIGURED] - ) - ) + self.environment[ogdwhcons.ConfigEnv.NEW_DATABASE] and + not self.environment[oenginecons.CoreEnv.ENABLE] ), ) def _closeup_engine_grafana_access(self):