From 9b689d6da275c5a9c02e237a28540967b24048f6 Mon Sep 17 00:00:00 2001 From: Stefaan Lippens Date: Wed, 24 Jan 2024 13:29:10 +0100 Subject: [PATCH] Add support for multiple client cred configs through env vars in CI #9 --- Jenkinsfile | 10 ++++-- src/openeo_gfmap/backend.py | 71 ++++++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index c7aa5d2..7075875 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -14,10 +14,14 @@ pythonPipeline { pep440 = true extra_env_variables = [ "OPENEO_AUTH_METHOD=client_credentials", + "OPENEO_OIDC_DEVICE_CODE_MAX_POLL_TIME=5", ] extra_env_secrets = [ - 'OPENEO_AUTH_PROVIDER_ID': 'TAP/big_data_services/openeo/jenkins-service-account provider_id', - 'OPENEO_AUTH_CLIENT_ID': 'TAP/big_data_services/openeo/jenkins-service-account client_id', - 'OPENEO_AUTH_CLIENT_SECRET': 'TAP/big_data_services/openeo/jenkins-service-account client_secret', + 'OPENEO_AUTH_PROVIDER_ID_VITO': 'TAP/big_data_services/openeo/jenkins-service-account provider_id', + 'OPENEO_AUTH_CLIENT_ID_VITO': 'TAP/big_data_services/openeo/jenkins-service-account client_id', + 'OPENEO_AUTH_CLIENT_SECRET_VITO': 'TAP/big_data_services/openeo/jenkins-service-account client_secret', + 'OPENEO_AUTH_PROVIDER_ID_CDSE': 'TAP/big_data_services/openeo/cdse-ci-service-account provider_id', + 'OPENEO_AUTH_CLIENT_ID_CDSE': 'TAP/big_data_services/openeo/cdse-ci-service-account client_id', + 'OPENEO_AUTH_CLIENT_SECRET_CDSE': 'TAP/big_data_services/openeo/cdse-ci-service-account client_secret', ] } diff --git a/src/openeo_gfmap/backend.py b/src/openeo_gfmap/backend.py index d9f3d48..b40764e 100644 --- a/src/openeo_gfmap/backend.py +++ b/src/openeo_gfmap/backend.py @@ -2,12 +2,16 @@ Defines on which backend the pipeline is being currently used. """ +import logging +import os from dataclasses import dataclass from enum import Enum -from typing import Callable, Dict +from typing import Callable, Dict, Optional import openeo +_log = logging.getLogger(__name__) + class Backend(Enum): """Enumerating the backends supported by the Mapping Framework.""" @@ -29,32 +33,65 @@ class BackendContext: backend: Backend +def _create_connection( + url: str, *, env_var_suffix: str, connect_kwargs: Optional[dict] = None +): + """ + Generic helper to create an openEO connection + with support for multiple client credential configurations from environment variables + """ + connection = openeo.connect(url, **(connect_kwargs or {})) + + if ( + os.environ.get("OPENEO_AUTH_METHOD") == "client_credentials" + and f"OPENEO_AUTH_CLIENT_ID_{env_var_suffix}" in os.environ + ): + # Support for multiple client credentials configs from env vars + client_id = os.environ[f"OPENEO_AUTH_CLIENT_ID_{env_var_suffix}"] + client_secret = os.environ[f"OPENEO_AUTH_CLIENT_SECRET_{env_var_suffix}"] + provider_id = os.environ.get(f"OPENEO_AUTH_PROVIDER_ID_{env_var_suffix}") + _log.info( + f"Doing client credentials from env var with {env_var_suffix=} {provider_id} {client_id=} {len(client_secret)=} " + ) + + connection.authenticate_oidc_client_credentials( + client_id=client_id, client_secret=client_secret, provider_id=provider_id + ) + else: + # Standard authenticate_oidc procedure: refresh token, device code or default env var handling + # See https://open-eo.github.io/openeo-python-client/auth.html#oidc-authentication-dynamic-method-selection + + # Use a shorter max poll time by default to alleviate the default impression that the test seem to hang + # because of the OIDC device code poll loop. + max_poll_time = int( + os.environ.get("OPENEO_OIDC_DEVICE_CODE_MAX_POLL_TIME") or 30 + ) + connection.authenticate_oidc(max_poll_time=max_poll_time) + return connection + + def vito_connection() -> openeo.Connection: """Performs a connection to the VITO backend using the oidc authentication.""" - # Note: this generic `authenticate_oidc()` call allows both: - # - device code/refresh token based authentication for manual test - # suiteruns by a developer - # - client credentials auth through env vars for automated/Jenkins CI runs - # - # See https://open-eo.github.io/openeo-python-client/auth.html#oidc-authentication-dynamic-method-selection # NOQA - # and Jenkinsfile, where Jenkins fetches the env vars from VITO TAP Vault. - connection = openeo.connect("openeo.vito.be") - connection.authenticate_oidc() - return connection + return _create_connection( + url="openeo.vito.be", + env_var_suffix="VITO", + ) def cdse_connection() -> openeo.Connection: """Performs a connection to the CDSE backend using oidc authentication.""" - connection = openeo.connect("https://openeo.dataspace.copernicus.eu/openeo/1.2") - connection.authenticate_oidc() - return connection + return _create_connection( + url="openeo.dataspace.copernicus.eu", + env_var_suffix="CDSE", + ) def eodc_connection() -> openeo.Connection: """Perfroms a connection to the EODC backend using the oidc authentication.""" - connection = openeo.connect("https://openeo.eodc.eu/openeo/1.1.0") - connection.authenticate_oidc() - return connection + return _create_connection( + url="https://openeo.eodc.eu/openeo/1.1.0", + env_var_suffix="EODC", + ) BACKEND_CONNECTIONS: Dict[Backend, Callable] = {