From 2d9b71dcff2194ed64908c737fed4ed20df003e9 Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Wed, 8 Apr 2026 00:18:24 +0530 Subject: [PATCH 01/20] added the metering code --- buildpack/telemetry/metering.py | 126 +++++++++++++++++++++++++++----- 1 file changed, 107 insertions(+), 19 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index 603b60e54..a05a11bd1 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -27,6 +27,19 @@ def _is_usage_metering_enabled(): return True +def _should_use_license_server(): + use_license_server = os.environ.get("MXRUNTIME_License.UseLicenseServer", "").lower() + return use_license_server == "true" + + +def _get_sap_metering_endpoint(): + return os.environ.get("MXRUNTIME_License.MeteringEndpoint", "").strip() or None + + +def _get_sap_metering_token(): + return os.environ.get("MXRUNTIME_License.MeteringToken", "").strip() or None + + def _get_project_id(file_path): try: with open(file_path) as file_handle: @@ -89,29 +102,104 @@ def _is_sidecar_installed(): return False -def stage(buildpack_path, build_path, cache_dir): - try: - if _is_usage_metering_enabled(): - logging.info("Usage metering is enabled") - _download(buildpack_path, build_path, cache_dir) +def _download_sap_sidecar(build_path, endpoint, token): + """Download SAP metering sidecar binary from HTTPS endpoint.""" + import requests + + logging.info("=== SAP METERING SIDECAR DOWNLOAD ===") + + # Reuse existing variables - same directory structure as Mendix sidecar + sidecar_dir = os.path.join(build_path, NAMESPACE) + destination = os.path.join(sidecar_dir, BINARY) + + logging.info("Source endpoint: %s", endpoint) + logging.info("Target directory: %s", sidecar_dir) + logging.info("Target file: %s", destination) + + util.mkdir_p(sidecar_dir) + logging.info("Created target directory: %s", sidecar_dir) + + logging.info("Downloading SAP metering sidecar from [%s]...", endpoint) + + # Download binary file via HTTPS with auth-token header + response = requests.get( + endpoint, + headers={"auth-token": token}, + stream=True, + timeout=60, + ) + response.raise_for_status() + + # Stream binary content to disk + with open(destination, "wb") as file_handle: + for chunk in response.iter_content(chunk_size=8192): + if chunk: + file_handle.write(chunk) - project_id = _get_project_id( - os.path.join(build_path, "model", "metadata.json") + logging.info("SAP metering sidecar downloaded successfully to [%s]", destination) + + # Verify file exists and get size + if os.path.exists(destination): + file_size = os.path.getsize(destination) + logging.info("Binary file size: %.2f MB", file_size / (1024 * 1024)) + else: + logging.error("Binary file not found after download: %s", destination) + raise Exception(f"Binary file not found: {destination}") + + util.set_executable(destination) + logging.info("Set executable permissions for: %s", BINARY) + + logging.info("=== SAP METERING SIDECAR DOWNLOAD COMPLETE ===") + return destination + + +def stage(buildpack_path, build_path, cache_dir): + if _should_use_license_server(): + # UseLicenseServer = true: original Mendix metering flow + try: + if _is_usage_metering_enabled(): + logging.info("Usage metering is enabled") + _download(buildpack_path, build_path, cache_dir) + + project_id = _get_project_id( + os.path.join(build_path, "model", "metadata.json") + ) + config = {"ProjectID": project_id} + + logging.debug("Writing metering sidecar configuration file...") + write_file( + os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE), + config, + ) + else: + logging.info("Usage metering is NOT enabled") + except Exception: + logging.info( + "Encountered an exception while staging the metering sidecar. " + "This is nothing to worry about." ) - config = {"ProjectID": project_id} + else: + # UseLicenseServer = false: attempt SAP metering sidecar download + endpoint = _get_sap_metering_endpoint() + token = _get_sap_metering_token() + + if not endpoint or not token: + logging.warning( + "SAP metering sidecar NOT downloaded: " + "MXRUNTIME_License.MeteringEndpoint or MXRUNTIME_License.MeteringToken " + "is missing or empty. Continuing buildpack execution." + ) + return - logging.debug("Writing metering sidecar configuration file...") - write_file( - os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE), - config, + try: + _download_sap_sidecar(build_path, endpoint, token) + logging.info("SAP metering sidecar staged successfully") + except Exception: + logging.error( + "Encountered an exception while staging the SAP metering sidecar. " + "Continuing buildpack execution.", + exc_info=True, ) - else: - logging.info("Usage metering is NOT enabled") - except Exception: - logging.info( - "Encountered an exception while staging the metering sidecar. " - "This is nothing to worry about." - ) def run(): From 1f6eaf5db1eee7a45a817de23f1e631cd29eebf1 Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Wed, 8 Apr 2026 14:40:32 +0530 Subject: [PATCH 02/20] added logging --- buildpack/telemetry/metering.py | 36 ++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index a05a11bd1..82e599373 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -29,7 +29,13 @@ def _is_usage_metering_enabled(): def _should_use_license_server(): use_license_server = os.environ.get("MXRUNTIME_License.UseLicenseServer", "").lower() - return use_license_server == "true" + result = use_license_server == "true" + logging.info( + "License server usage check: MXRUNTIME_License.UseLicenseServer=%r, result=%s", + use_license_server, + result, + ) + return result def _get_sap_metering_endpoint(): @@ -154,23 +160,27 @@ def _download_sap_sidecar(build_path, endpoint, token): def stage(buildpack_path, build_path, cache_dir): + logging.info("Starting metering stage (buildpack_path=%s, build_path=%s)", buildpack_path, build_path) if _should_use_license_server(): + logging.info("Using Mendix license server flow for metering") # UseLicenseServer = true: original Mendix metering flow try: if _is_usage_metering_enabled(): logging.info("Usage metering is enabled") + logging.info("Downloading Mendix metering sidecar...") _download(buildpack_path, build_path, cache_dir) + logging.info("Mendix metering sidecar downloaded successfully") - project_id = _get_project_id( - os.path.join(build_path, "model", "metadata.json") - ) + metadata_path = os.path.join(build_path, "model", "metadata.json") + logging.info("Reading project ID from: %s", metadata_path) + project_id = _get_project_id(metadata_path) + logging.info("Project ID: %s", project_id) config = {"ProjectID": project_id} - logging.debug("Writing metering sidecar configuration file...") - write_file( - os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE), - config, - ) + config_path = os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE) + logging.info("Writing metering sidecar configuration file to: %s", config_path) + write_file(config_path, config) + logging.info("Metering sidecar configuration file written successfully") else: logging.info("Usage metering is NOT enabled") except Exception: @@ -179,9 +189,15 @@ def stage(buildpack_path, build_path, cache_dir): "This is nothing to worry about." ) else: + logging.info("License server not used; attempting SAP metering sidecar flow") # UseLicenseServer = false: attempt SAP metering sidecar download endpoint = _get_sap_metering_endpoint() token = _get_sap_metering_token() + logging.info( + "SAP metering config: endpoint=%s, token_present=%s", + endpoint, + bool(token), + ) if not endpoint or not token: logging.warning( @@ -192,6 +208,7 @@ def stage(buildpack_path, build_path, cache_dir): return try: + logging.info("Downloading SAP metering sidecar from endpoint: %s", endpoint) _download_sap_sidecar(build_path, endpoint, token) logging.info("SAP metering sidecar staged successfully") except Exception: @@ -200,6 +217,7 @@ def stage(buildpack_path, build_path, cache_dir): "Continuing buildpack execution.", exc_info=True, ) + logging.info("Metering stage completed") def run(): From 4f742524e21e68d5003309edd44b9f334bc1efd6 Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Thu, 9 Apr 2026 12:28:22 +0530 Subject: [PATCH 03/20] added the sap metering sidecar --- buildpack/telemetry/metering.py | 137 ++++++++++++-------------------- 1 file changed, 49 insertions(+), 88 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index 82e599373..eb33aa9d3 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -27,15 +27,21 @@ def _is_usage_metering_enabled(): return True -def _should_use_license_server(): - use_license_server = os.environ.get("MXRUNTIME_License.UseLicenseServer", "").lower() - result = use_license_server == "true" - logging.info( - "License server usage check: MXRUNTIME_License.UseLicenseServer=%r, result=%s", - use_license_server, - result, - ) - return result +def _is_sap_metering_configured(): + use_license_server = os.environ.get("MXRUNTIME_License.UseLicenseServer", "false").lower() + if use_license_server == "true": + return False + + endpoint = _get_sap_metering_endpoint() + token = _get_sap_metering_token() + + if not endpoint or not token: + logging.warning( + "Missing configuration for SAP metering sidecar." + ) + return False + + return True def _get_sap_metering_endpoint(): @@ -108,24 +114,13 @@ def _is_sidecar_installed(): return False -def _download_sap_sidecar(build_path, endpoint, token): +def _copy_sap_metering_sidecar(build_path, endpoint, token): """Download SAP metering sidecar binary from HTTPS endpoint.""" import requests - logging.info("=== SAP METERING SIDECAR DOWNLOAD ===") - - # Reuse existing variables - same directory structure as Mendix sidecar sidecar_dir = os.path.join(build_path, NAMESPACE) destination = os.path.join(sidecar_dir, BINARY) - - logging.info("Source endpoint: %s", endpoint) - logging.info("Target directory: %s", sidecar_dir) - logging.info("Target file: %s", destination) - util.mkdir_p(sidecar_dir) - logging.info("Created target directory: %s", sidecar_dir) - - logging.info("Downloading SAP metering sidecar from [%s]...", endpoint) # Download binary file via HTTPS with auth-token header response = requests.get( @@ -142,82 +137,48 @@ def _download_sap_sidecar(build_path, endpoint, token): if chunk: file_handle.write(chunk) - logging.info("SAP metering sidecar downloaded successfully to [%s]", destination) - - # Verify file exists and get size - if os.path.exists(destination): - file_size = os.path.getsize(destination) - logging.info("Binary file size: %.2f MB", file_size / (1024 * 1024)) - else: - logging.error("Binary file not found after download: %s", destination) - raise Exception(f"Binary file not found: {destination}") - + logging.info("SAP metering sidecar downloaded successfully") util.set_executable(destination) - logging.info("Set executable permissions for: %s", BINARY) - - logging.info("=== SAP METERING SIDECAR DOWNLOAD COMPLETE ===") return destination def stage(buildpack_path, build_path, cache_dir): - logging.info("Starting metering stage (buildpack_path=%s, build_path=%s)", buildpack_path, build_path) - if _should_use_license_server(): - logging.info("Using Mendix license server flow for metering") - # UseLicenseServer = true: original Mendix metering flow - try: - if _is_usage_metering_enabled(): - logging.info("Usage metering is enabled") - logging.info("Downloading Mendix metering sidecar...") - _download(buildpack_path, build_path, cache_dir) - logging.info("Mendix metering sidecar downloaded successfully") - - metadata_path = os.path.join(build_path, "model", "metadata.json") - logging.info("Reading project ID from: %s", metadata_path) - project_id = _get_project_id(metadata_path) - logging.info("Project ID: %s", project_id) - config = {"ProjectID": project_id} - - config_path = os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE) - logging.info("Writing metering sidecar configuration file to: %s", config_path) - write_file(config_path, config) - logging.info("Metering sidecar configuration file written successfully") - else: - logging.info("Usage metering is NOT enabled") - except Exception: - logging.info( - "Encountered an exception while staging the metering sidecar. " - "This is nothing to worry about." - ) - else: - logging.info("License server not used; attempting SAP metering sidecar flow") - # UseLicenseServer = false: attempt SAP metering sidecar download - endpoint = _get_sap_metering_endpoint() - token = _get_sap_metering_token() - logging.info( - "SAP metering config: endpoint=%s, token_present=%s", - endpoint, - bool(token), - ) + try: + if _is_usage_metering_enabled(): + # Original Mendix metering flow + logging.info("Usage metering is enabled") + _download(buildpack_path, build_path, cache_dir) - if not endpoint or not token: - logging.warning( - "SAP metering sidecar NOT downloaded: " - "MXRUNTIME_License.MeteringEndpoint or MXRUNTIME_License.MeteringToken " - "is missing or empty. Continuing buildpack execution." + project_id = _get_project_id( + os.path.join(build_path, "model", "metadata.json") ) - return + config = {"ProjectID": project_id} - try: - logging.info("Downloading SAP metering sidecar from endpoint: %s", endpoint) - _download_sap_sidecar(build_path, endpoint, token) - logging.info("SAP metering sidecar staged successfully") - except Exception: - logging.error( - "Encountered an exception while staging the SAP metering sidecar. " - "Continuing buildpack execution.", - exc_info=True, + logging.debug("Writing metering sidecar configuration file...") + write_file( + os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE), + config, ) - logging.info("Metering stage completed") + elif _is_sap_metering_configured(): + # UseLicenseServer = false with valid SAP endpoint and token + endpoint = _get_sap_metering_endpoint() + token = _get_sap_metering_token() + try: + _copy_sap_metering_sidecar(build_path, endpoint, token) + logging.info("SAP metering sidecar staged successfully") + except Exception: + logging.error( + "Encountered an exception while staging the SAP metering sidecar. " + "Continuing buildpack execution." + ) + logging.debug("SAP metering sidecar staging exception details:", exc_info=True) + else: + logging.info("Usage metering is NOT enabled") + except Exception: + logging.info( + "Encountered an exception while staging the metering sidecar. " + "This is nothing to worry about." + ) def run(): From b57808922a734975b988eaece7ee0731f31c0ce2 Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Tue, 14 Apr 2026 14:54:23 +0530 Subject: [PATCH 04/20] updated the auth token usage --- buildpack/telemetry/metering.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index eb33aa9d3..09eb63ff7 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -33,9 +33,8 @@ def _is_sap_metering_configured(): return False endpoint = _get_sap_metering_endpoint() - token = _get_sap_metering_token() - if not endpoint or not token: + if not endpoint: logging.warning( "Missing configuration for SAP metering sidecar." ) @@ -45,11 +44,11 @@ def _is_sap_metering_configured(): def _get_sap_metering_endpoint(): - return os.environ.get("MXRUNTIME_License.MeteringEndpoint", "").strip() or None + return os.environ.get("MXRUNTIME_License.MeteringEndpoint", "").strip() def _get_sap_metering_token(): - return os.environ.get("MXRUNTIME_License.MeteringToken", "").strip() or None + return os.environ.get("MXRUNTIME_License.MeteringToken", "").strip() def _get_project_id(file_path): From 0452f16f6c320e825d2a137918c40bd2053aa398 Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Tue, 14 Apr 2026 15:06:48 +0530 Subject: [PATCH 05/20] updated the comments --- buildpack/telemetry/metering.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index 09eb63ff7..7ac40bf75 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -121,7 +121,6 @@ def _copy_sap_metering_sidecar(build_path, endpoint, token): destination = os.path.join(sidecar_dir, BINARY) util.mkdir_p(sidecar_dir) - # Download binary file via HTTPS with auth-token header response = requests.get( endpoint, headers={"auth-token": token}, @@ -130,7 +129,6 @@ def _copy_sap_metering_sidecar(build_path, endpoint, token): ) response.raise_for_status() - # Stream binary content to disk with open(destination, "wb") as file_handle: for chunk in response.iter_content(chunk_size=8192): if chunk: @@ -144,7 +142,6 @@ def _copy_sap_metering_sidecar(build_path, endpoint, token): def stage(buildpack_path, build_path, cache_dir): try: if _is_usage_metering_enabled(): - # Original Mendix metering flow logging.info("Usage metering is enabled") _download(buildpack_path, build_path, cache_dir) @@ -159,7 +156,6 @@ def stage(buildpack_path, build_path, cache_dir): config, ) elif _is_sap_metering_configured(): - # UseLicenseServer = false with valid SAP endpoint and token endpoint = _get_sap_metering_endpoint() token = _get_sap_metering_token() try: From 241305fb4a07626037513ff31fea9881e982298c Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Fri, 17 Apr 2026 16:35:54 +0530 Subject: [PATCH 06/20] updated the env vars --- buildpack/telemetry/metering.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index 7ac40bf75..680b4f197 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -44,11 +44,11 @@ def _is_sap_metering_configured(): def _get_sap_metering_endpoint(): - return os.environ.get("MXRUNTIME_License.MeteringEndpoint", "").strip() + return os.environ.get("METERING_BINARY_PATH", "").strip() def _get_sap_metering_token(): - return os.environ.get("MXRUNTIME_License.MeteringToken", "").strip() + return os.environ.get("METERING_BINARY_TOKEN", "").strip() def _get_project_id(file_path): From 145110cbe22fbccd735ce844a3a7ba0f16f1982f Mon Sep 17 00:00:00 2001 From: "priyal.chawda@mendix.com" Date: Thu, 23 Apr 2026 18:38:08 +0530 Subject: [PATCH 07/20] fix: update cryptography to 46.0.7 to address CVE-2026-39892 - Updated cryptography from 46.0.5 to 46.0.7 - Fixes buffer overflow vulnerability in non-contiguous buffer handling - Regenerated requirements.txt with Python 3.10 - All unit tests passing (184 passed) - All linting checks passing --- requirements.in | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.in b/requirements.in index edee2e58f..4417521af 100644 --- a/requirements.in +++ b/requirements.in @@ -1,6 +1,6 @@ backoff==2.2.1 certifi==2024.8.30 -cryptography==46.0.5 +cryptography==46.0.7 distro==1.9.0 httplib2==0.22.0 jinja2==3.1.6 diff --git a/requirements.txt b/requirements.txt index 91b30ca73..7730b314f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ cffi==2.0.0 # via cryptography charset-normalizer==2.0.3 # via requests -cryptography==46.0.5 +cryptography==46.0.7 # via -r requirements.in distro==1.9.0 # via -r requirements.in From 4e0365b06025704f03c9c99f44566bd7824863e8 Mon Sep 17 00:00:00 2001 From: "priyal.chawda@mendix.com" Date: Mon, 27 Apr 2026 15:49:50 +0530 Subject: [PATCH 08/20] Bumped the cryptography module version to latest 47.0.0 --- requirements.in | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.in b/requirements.in index 4417521af..20fd018a4 100644 --- a/requirements.in +++ b/requirements.in @@ -1,6 +1,6 @@ backoff==2.2.1 certifi==2024.8.30 -cryptography==46.0.7 +cryptography==47.0.0 distro==1.9.0 httplib2==0.22.0 jinja2==3.1.6 diff --git a/requirements.txt b/requirements.txt index 7730b314f..414ae8e2e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ cffi==2.0.0 # via cryptography charset-normalizer==2.0.3 # via requests -cryptography==46.0.7 +cryptography==47.0.0 # via -r requirements.in distro==1.9.0 # via -r requirements.in From 446fe36429a9524aea86b464244e2975981c77cb Mon Sep 17 00:00:00 2001 From: Piyush Date: Fri, 8 May 2026 21:07:57 +0530 Subject: [PATCH 09/20] Fix CVE-2026-25645 and CVE-2026-34073 by upgrading requests and cryptography Updated requests from 2.32.5 to 2.33.1 to address CVE-2026-25645. Updated cryptography from 46.0.5 to 47.0.0 to address CVE-2026-34073. Co-Authored-By: Claude Sonnet 4.5 --- requirements.in | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.in b/requirements.in index 20fd018a4..411416512 100644 --- a/requirements.in +++ b/requirements.in @@ -7,5 +7,5 @@ jinja2==3.1.6 omegaconf==2.3.0 psycopg2-binary==2.9.10 pyyaml==6.0.2 -requests==2.32.5 +requests==2.33.1 urllib3==2.6.3 diff --git a/requirements.txt b/requirements.txt index 414ae8e2e..4401858cd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -40,7 +40,7 @@ pyyaml==6.0.2 # via # -r requirements.in # omegaconf -requests==2.32.5 +requests==2.33.1 # via -r requirements.in typing-extensions==4.15.0 # via cryptography From ef8bec4c0f3629101ff5e25003829e678926a60c Mon Sep 17 00:00:00 2001 From: Bhavin Shah <162097397+bhavinshah-mendix@users.noreply.github.com> Date: Mon, 25 May 2026 16:32:00 +0530 Subject: [PATCH 10/20] Security/upgrade requests urllib3 CVE fix (#894) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Security: Upgrade requests to 2.34.2 and urllib3 to 2.7.0 Fixes high-severity CVEs: - CVE-2026-25645 (requests): Fixed in 2.33.0+ - GHSA-mf9v-mfxr-j63j (urllib3): Streaming API decompression issue - GHSA-qccp-gfcp-xxvc (urllib3): Cross-origin redirect header leakage Changes: - requests: 2.32.5 → 2.34.2 - urllib3: 2.6.3 → 2.7.0 - charset-normalizer: 2.0.3 → 3.4.7 (transitive) - idna: 3.10 → 3.15 (transitive) Co-Authored-By: Claude Sonnet 4.5 * Fixes high-severity CVEs: - CVE-2026-25645 (requests): Fixed in 2.33.0+ - GHSA-mf9v-mfxr-j63j (urllib3): Streaming API decompression issue - GHSA-qccp-gfcp-xxvc (urllib3): Cross-origin redirect header leakage --------- Co-authored-by: Claude Sonnet 4.5 --- requirements.in | 4 ++-- requirements.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements.in b/requirements.in index 411416512..cf0cbf2f6 100644 --- a/requirements.in +++ b/requirements.in @@ -7,5 +7,5 @@ jinja2==3.1.6 omegaconf==2.3.0 psycopg2-binary==2.9.10 pyyaml==6.0.2 -requests==2.33.1 -urllib3==2.6.3 +requests==2.34.2 +urllib3==2.7.0 diff --git a/requirements.txt b/requirements.txt index 4401858cd..6f4af638a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -40,11 +40,11 @@ pyyaml==6.0.2 # via # -r requirements.in # omegaconf -requests==2.33.1 +requests==2.34.2 # via -r requirements.in typing-extensions==4.15.0 # via cryptography -urllib3==2.6.3 +urllib3==2.7.0 # via # -r requirements.in # requests From 89b2ec4e5813bccfc01c2a658633f03e1225edae Mon Sep 17 00:00:00 2001 From: mayankmendix <60148863+mayankmendix@users.noreply.github.com> Date: Fri, 29 May 2026 19:04:54 +0530 Subject: [PATCH 11/20] (fix) add typing extension lib (#898) * Update requirements.txt * Update requirements.in --- requirements.in | 1 + requirements.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.in b/requirements.in index cf0cbf2f6..7b668abec 100644 --- a/requirements.in +++ b/requirements.in @@ -8,4 +8,5 @@ omegaconf==2.3.0 psycopg2-binary==2.9.10 pyyaml==6.0.2 requests==2.34.2 +typing-extensions==4.15.0 urllib3==2.7.0 diff --git a/requirements.txt b/requirements.txt index 6f4af638a..84236d78b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -43,7 +43,7 @@ pyyaml==6.0.2 requests==2.34.2 # via -r requirements.in typing-extensions==4.15.0 - # via cryptography + # via -r requirements.in urllib3==2.7.0 # via # -r requirements.in From 5f4fcf3acc155419328416be1b6c4c10ce78125e Mon Sep 17 00:00:00 2001 From: EnasAbdelrazek <96430281+EnasAbdelrazek@users.noreply.github.com> Date: Mon, 15 Jun 2026 10:14:16 +0200 Subject: [PATCH 12/20] Expand static files caching (#901) Support static files caching --- etc/nginx/conf/nginx.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/nginx/conf/nginx.conf.j2 b/etc/nginx/conf/nginx.conf.j2 index 04167e1db..4c4f52b25 100644 --- a/etc/nginx/conf/nginx.conf.j2 +++ b/etc/nginx/conf/nginx.conf.j2 @@ -97,7 +97,7 @@ http { {{ location.body }} } {% else %} - if ($request_uri ~ ^/(.*\.(css|js)|forms/.*|img/.*|pages/.*|mxclientsystem/images/.*)\?[0-9]+$) { + if ($request_uri ~ ^/((.*\.(css|js)|forms/.*|img/.*|pages/.*|mxclientsystem/images/.*)\?[0-9]+|dist/chunks/.*\.js|.*\.(woff2?|ttf|otf|eot))$) { expires 1y; } {% if location.path == "/" %} From e316ef6de19258394b46d4ac3fcff6d242eafc3c Mon Sep 17 00:00:00 2001 From: Bhavin Shah <162097397+bhavinshah-mendix@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:24:12 +0530 Subject: [PATCH 13/20] =?UTF-8?q?Security:=20Fix=20CVE-2026-45409=20(idna)?= =?UTF-8?q?=20and=20GHSA-537c-gmf6-5ccf=20(cryptogr=E2=80=A6=20(#902)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Security: Fix CVE-2026-45409 (idna) and GHSA-537c-gmf6-5ccf (cryptography) Upgrades dependencies to address high-severity vulnerabilities: - cryptography 47.0.0 → 48.0.1: Fixes vulnerable OpenSSL in wheels - idna 3.10 → 3.15: Fixes DoS vulnerability in IDNA encoding CVE-2026-45409: idna versions prior to 3.15 were vulnerable to DoS attacks via specially crafted inputs to idna.encode() function. GHSA-537c-gmf6-5ccf: cryptography wheels prior to 48.0.1 included a statically linked copy of OpenSSL with security vulnerabilities. --- requirements-dev.in | 2 +- requirements.in | 3 ++- requirements.txt | 8 +++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/requirements-dev.in b/requirements-dev.in index 5b3a8da82..5ed8b5594 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -1,5 +1,5 @@ click==8.1.7 -idna==3.10 +idna==3.15 pytest==8.3.3 pytest-timer==1.0.0 pytest-timeout==2.3.1 diff --git a/requirements.in b/requirements.in index 7b668abec..57a369315 100644 --- a/requirements.in +++ b/requirements.in @@ -1,8 +1,9 @@ backoff==2.2.1 certifi==2024.8.30 -cryptography==47.0.0 +cryptography==48.0.1 distro==1.9.0 httplib2==0.22.0 +idna==3.15 jinja2==3.1.6 omegaconf==2.3.0 psycopg2-binary==2.9.10 diff --git a/requirements.txt b/requirements.txt index 84236d78b..8e3483636 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,14 +16,16 @@ cffi==2.0.0 # via cryptography charset-normalizer==2.0.3 # via requests -cryptography==47.0.0 +cryptography==48.0.1 # via -r requirements.in distro==1.9.0 # via -r requirements.in httplib2==0.22.0 # via -r requirements.in -idna==3.10 - # via requests +idna==3.15 + # via + # -r requirements.in + # requests jinja2==3.1.6 # via -r requirements.in markupsafe==2.0.1 From 4efd60a390403db986aad6b6f97c435b14e381d6 Mon Sep 17 00:00:00 2001 From: Bhavin Shah <162097397+bhavinshahM@users.noreply.github.com> Date: Wed, 12 Aug 2026 12:09:16 +0530 Subject: [PATCH 14/20] =?UTF-8?q?Security:=20Upgrade=20nginx=20from=201.26?= =?UTF-8?q?.1=20to=201.30.4=20to=20fix=20CVE-2025-23419=20a=E2=80=A6=20(#9?= =?UTF-8?q?09)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Security: Upgrade nginx from 1.26.1 to 1.30.4 to fix CVE-2025-23419 and CVE-2026-42945 Co-authored-by: bhavin.shah --- dependencies.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies.yml b/dependencies.yml index a3f464ded..2fb38101f 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -79,10 +79,10 @@ dependencies: version: 8.24.0 nginx: artifact: nginx_{{ version }}_linux_x64_{{ fs }}_{{ commit }}.tgz - commit: b1316f75 + commit: 8ae9e822 fs: cflinuxfs4 cpe: cpe:2.3:a:f5:nginx:{{ version }}:*:*:*:*:*:*:* - version: 1.26.1 + version: 1.30.4 ruby: artifact: ruby/ruby_{{ version }}_linux_x64_{{ fs }}_{{ commit }}.tgz commit: 5fed98f8 From e555256af9e861cedf0f5659048ed1d2eacd17c1 Mon Sep 17 00:00:00 2001 From: PiyushTiwari-LowCode <106152452+PiyushTiwari-LowCode@users.noreply.github.com> Date: Wed, 12 Aug 2026 12:31:21 +0530 Subject: [PATCH 15/20] Fix CVE-2026-69247(cryptography)andCVE-2026-59939(httplib2) (#907) Co-authored-by: Piyush Co-authored-by: mayankmendix <60148863+mayankmendix@users.noreply.github.com> --- requirements.in | 4 ++-- requirements.txt | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/requirements.in b/requirements.in index 57a369315..d92647def 100644 --- a/requirements.in +++ b/requirements.in @@ -1,8 +1,8 @@ backoff==2.2.1 certifi==2024.8.30 -cryptography==48.0.1 +cryptography==50.0.0 distro==1.9.0 -httplib2==0.22.0 +httplib2==0.32.0 idna==3.15 jinja2==3.1.6 omegaconf==2.3.0 diff --git a/requirements.txt b/requirements.txt index 8e3483636..3b55f07ed 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,11 +16,11 @@ cffi==2.0.0 # via cryptography charset-normalizer==2.0.3 # via requests -cryptography==48.0.1 +cryptography==50.0.0 # via -r requirements.in distro==1.9.0 # via -r requirements.in -httplib2==0.22.0 +httplib2==0.32.0 # via -r requirements.in idna==3.15 # via @@ -36,7 +36,7 @@ psycopg2-binary==2.9.10 # via -r requirements.in pycparser==2.20 # via cffi -pyparsing==2.4.7 +pyparsing==3.3.2 # via httplib2 pyyaml==6.0.2 # via @@ -45,7 +45,9 @@ pyyaml==6.0.2 requests==2.34.2 # via -r requirements.in typing-extensions==4.15.0 - # via -r requirements.in + # via + # -r requirements.in + # cryptography urllib3==2.7.0 # via # -r requirements.in From 6f11727773525e2d01247e6a8278c861b3965592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Serrador?= <61971372+mruiserrmendix@users.noreply.github.com> Date: Thu, 13 Aug 2026 08:41:23 +0200 Subject: [PATCH 16/20] Add deprecation warning for Cloud Foundry Buildpack (#910) Added a warning about the deprecation of the Cloud Foundry Buildpack for Mendix 12 and future Runtime versions. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 408ed0ce7..cf0196e39 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ This document contains general information on the Mendix Cloud Foundry Buildpack. +**Warning** - We strongly encourage customers to begin their journey toward [Mendix Portable Runtime](https://docs.mendix.com/developerportal/deploy/portable-app-distribution-deploy/), as the Cloud Foundry Buildpack will no longer support Mendix 12 and future Runtime versions, marking the start of the deprecation process. For more information, see the [blog release](https://www.mendix.com/blog/mendix-portable-runtime/) + The buildpack is heavily tied to the Mendix Public Cloud, but can be used independently. Release notes are available for the [buildpack](https://github.com/mendix/cf-mendix-buildpack/releases/), [Mendix itself](https://docs.mendix.com/releasenotes/studio-pro/) and the [Mendix Public Cloud](https://docs.mendix.com/releasenotes/developer-portal/deployment). From 8f153486c131f92ed28d566432cca6d0398ff429 Mon Sep 17 00:00:00 2001 From: Bhavin Shah <162097397+bhavinshahM@users.noreply.github.com> Date: Wed, 2 Sep 2026 23:25:41 +0530 Subject: [PATCH 17/20] Fix PostgreSQL metrics query to filter by application database (#914) Co-authored-by: Bhavin --- etc/telegraf/telegraf.toml.j2 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/etc/telegraf/telegraf.toml.j2 b/etc/telegraf/telegraf.toml.j2 index 194b0b60b..1f4002cd1 100644 --- a/etc/telegraf/telegraf.toml.j2 +++ b/etc/telegraf/telegraf.toml.j2 @@ -104,6 +104,7 @@ numbackends AS connections, pg_database_size(datname) AS database_size FROM pg_stat_database + WHERE datname = '{{ db_config["DatabaseName"] }}' """ version = 901 withdbname = false @@ -116,6 +117,7 @@ datname, deadlocks FROM pg_stat_database + WHERE datname = '{{ db_config["DatabaseName"] }}' """ version = 920 withdbname = false @@ -128,6 +130,7 @@ datname, 2^31 - age(datfrozenxid) AS before_xid_wraparound FROM pg_database + WHERE datname = '{{ db_config["DatabaseName"] }}' """ version = 901 withdbname = false @@ -175,6 +178,7 @@ MAX(setting) AS max_connections, SUM(numbackends)/MAX(setting) AS percent_usage_connections FROM pg_stat_database, max_con + WHERE datname = '{{ db_config["DatabaseName"] }}' """ version = 901 withdbname = false @@ -216,6 +220,7 @@ tup_returned AS rows_returned_rate, tup_updated AS rows_updated_rate FROM pg_stat_database + WHERE datname = '{{ db_config["DatabaseName"] }}' """ version = 901 withdbname = false @@ -228,6 +233,7 @@ datname, temp_files AS temp_files_rate FROM pg_stat_database + WHERE datname = '{{ db_config["DatabaseName"] }}' """ version = 920 withdbname = false From 7ae5435d100d2e07223853728d559ba75f8707cf Mon Sep 17 00:00:00 2001 From: Priyal Chawda <86288192+Pri1235@users.noreply.github.com> Date: Wed, 16 Sep 2026 21:19:31 +0530 Subject: [PATCH 18/20] Feature/sap hana client jar stage (#915) Added SAP HANA client JAR staging support --- README.md | 10 ++++++++++ buildpack/core/runtime.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/README.md b/README.md index cf0196e39..15be897e1 100644 --- a/README.md +++ b/README.md @@ -273,6 +273,16 @@ Selection based on name `hana` and tags `["hana", "database", "relational"]`. ], ``` +#### SAP HANA Client + +To include the SAP HANA client JAR (`ngdbc.jar`) in your app's classpath at staging time, set the following environment variable: + +```shell +cf set-env MXRUNTIME_IncludeSAPHanaClient true +``` + +When enabled, the buildpack fetches the latest `ngdbc.jar` from the Mendix CDN and places it in `model/lib/userlib/`, making it available to the Mendix runtime. If the download fails, staging continues without the JAR and a warning is logged. + ### Connect an External File Store The Mendix Runtime supports multiple external file stores: AWS S3, Azure Storage and Swift (Bluemix Object Storage). diff --git a/buildpack/core/runtime.py b/buildpack/core/runtime.py index c6e047f83..a92971849 100644 --- a/buildpack/core/runtime.py +++ b/buildpack/core/runtime.py @@ -9,6 +9,7 @@ import time import backoff +import requests from buildpack import util from lib.m2ee import M2EE as m2ee_class from lib.m2ee.version import MXVersion @@ -56,6 +57,32 @@ def is_version_maintained(version): return True return False +def _stage_hana_client(build_dir): + enabled = os.environ.get("MXRUNTIME_IncludeSAPHanaClient", "").strip().lower() == "true" + if not enabled: + return + + cdn_prefix = util.BLOBSTORE_BUILDPACK_DEFAULT_PREFIX + "sap-hana-client" + try: + dest = os.path.join(build_dir, "model", "lib", "userlib") + util.mkdir_p(dest) + version_url = util.get_blobstore_url(f"{cdn_prefix}/version.txt") + resp = requests.get(version_url, timeout=10) + resp.raise_for_status() + jar_name = f"ngdbc-{resp.text.strip()}.jar" + jar_url = util.get_blobstore_url(f"{cdn_prefix}/{jar_name}") + util.download(jar_url, os.path.join(dest, jar_name)) + logging.info( + "SAP HANA client JAR [%s] staged to [%s]", + jar_name, + dest, + ) + except Exception: + logging.warning( + "Failed to stage SAP HANA client JAR, continuing deployment...", + exc_info=True, + ) + def stage(buildpack_dir, build_path, cache_path): logging.debug("Creating directory structure for Mendix runtime...") @@ -85,6 +112,7 @@ def stage(buildpack_dir, build_path, cache_path): util.set_executable(file_path) resolve_runtime_dependency(buildpack_dir, build_path, cache_path) + _stage_hana_client(build_path) FORCED_MXRUNTIME_URL_KEY = "FORCED_MXRUNTIME_URL" From 74618d65a4c9d00090d904566628e064b880535e Mon Sep 17 00:00:00 2001 From: Priyal Chawda <86288192+Pri1235@users.noreply.github.com> Date: Mon, 21 Sep 2026 15:21:02 +0530 Subject: [PATCH 19/20] Skip staging SAP HANA client JAR if already present in userlib or vendorlib (#916) Skip staging SAP HANA client JAR if already present in userlib or vendorlib --- buildpack/core/runtime.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/buildpack/core/runtime.py b/buildpack/core/runtime.py index a92971849..b17db959d 100644 --- a/buildpack/core/runtime.py +++ b/buildpack/core/runtime.py @@ -9,6 +9,7 @@ import time import backoff +import glob import requests from buildpack import util from lib.m2ee import M2EE as m2ee_class @@ -62,9 +63,19 @@ def _stage_hana_client(build_dir): if not enabled: return + model_lib = os.path.join(build_dir, "model", "lib") + for lib_dir in ("userlib", "vendorlib"): + existing = glob.glob(os.path.join(model_lib, lib_dir, "ngdbc-*.jar")) + if existing: + logging.info( + "SAP HANA client JAR [%s] already present, skipping download", + existing[0], + ) + return + cdn_prefix = util.BLOBSTORE_BUILDPACK_DEFAULT_PREFIX + "sap-hana-client" try: - dest = os.path.join(build_dir, "model", "lib", "userlib") + dest = os.path.join(model_lib, "userlib") util.mkdir_p(dest) version_url = util.get_blobstore_url(f"{cdn_prefix}/version.txt") resp = requests.get(version_url, timeout=10) From 53442d5774439ced6fb5fc42cc206bc802f508cb Mon Sep 17 00:00:00 2001 From: Bhavin Shah <162097397+bhavinshahM@users.noreply.github.com> Date: Mon, 28 Sep 2026 16:11:17 +0530 Subject: [PATCH 20/20] Add RDS ap-southeast-7 support (#917) * Add RDS ap-southeast-7 support --- buildpack/infrastructure/database.py | 2 + .../ap-southeast-7-bundle.pem | 76 +++++++++++++++++++ tests/unit/test_db_rds.py | 11 +++ 3 files changed, 89 insertions(+) create mode 100644 etc/rds-certificates/ap-southeast-7-bundle.pem diff --git a/buildpack/infrastructure/database.py b/buildpack/infrastructure/database.py index f5912d903..95e43688f 100644 --- a/buildpack/infrastructure/database.py +++ b/buildpack/infrastructure/database.py @@ -263,6 +263,7 @@ def init(self): "ap-south-2": "ap-south-2-bundle.pem", "ap-southeast-3": "ap-southeast-3-bundle.pem", "ap-southeast-4": "ap-southeast-4-bundle.pem", + "ap-southeast-7": "ap-southeast-7-bundle.pem", "ap-south-1": "ap-south-1-bundle.pem", "ap-northeast-3": "ap-northeast-3-bundle.pem", "ap-northeast-1": "ap-northeast-1-bundle.pem", @@ -542,6 +543,7 @@ def stage(buildpack_dir, build_dir): "ap-south-2": "ap-south-2-bundle.pem", "ap-southeast-3": "ap-southeast-3-bundle.pem", "ap-southeast-4": "ap-southeast-4-bundle.pem", + "ap-southeast-7": "ap-southeast-7-bundle.pem", "ap-south-1": "ap-south-1-bundle.pem", "ap-northeast-3": "ap-northeast-3-bundle.pem", "ap-northeast-1": "ap-northeast-1-bundle.pem", diff --git a/etc/rds-certificates/ap-southeast-7-bundle.pem b/etc/rds-certificates/ap-southeast-7-bundle.pem new file mode 100644 index 000000000..86cf81a9c --- /dev/null +++ b/etc/rds-certificates/ap-southeast-7-bundle.pem @@ -0,0 +1,76 @@ +-----BEGIN CERTIFICATE----- +MIICtzCCAj2gAwIBAgIQc48r2iRBCPPCj3oRSgZxujAKBggqhkjOPQQDAzCBmzEL +MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x +EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 +b24gUkRTIGFwLXNvdXRoZWFzdC03IFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH +DAdTZWF0dGxlMCAXDTI0MDkxMjE1NTQ0MFoYDzIxMjQwOTEyMTY1NDQwWjCBmzEL +MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x +EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 +b24gUkRTIGFwLXNvdXRoZWFzdC03IFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH +DAdTZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEVSBo1+i/T9w0C7C1qdnl +DfUXpFa+x4QYZvwLtt6m9L96k5irB7Wlw5168uTBW/ssRbv067PBnQEdZfI3iLKK +xWSpDFZN11tRneyDXag/fj1MCzBQ25WG+BitQdbzzuYuo0IwQDAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTiqTOsp/NisMSxMzARIGIKFcol4TAOBgNVHQ8BAf8E +BAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIxAJlFgjECsVieUHNKE2Cmbj1wujERebHM +YNqCdnO//DeQ6Rh4SJkNaWB9LRmrmsdvIwIwf2iyQNetoO2JWNt7gzdRjO+7dF2+ +/LdagQCVp4R2N1Q6xzttRqZEK0lyAd0t7wlX +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGCTCCA/GgAwIBAgIRAIgSQsm7XtddDiXpo3j09qYwDQYJKoZIhvcNAQEMBQAw +gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ +bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws +QW1hem9uIFJEUyBhcC1zb3V0aGVhc3QtNyBSb290IENBIFJTQTQwOTYgRzExEDAO +BgNVBAcMB1NlYXR0bGUwIBcNMjQwOTEyMTU1NDM2WhgPMjEyNDA5MTIxNjU0MzZa +MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg +SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM +LEFtYXpvbiBSRFMgYXAtc291dGhlYXN0LTcgUm9vdCBDQSBSU0E0MDk2IEcxMRAw +DgYDVQQHDAdTZWF0dGxlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA +jLfyuFmUeGd3WSDotJVQ+XjY20Yt75KWDFjXNLNZ7+/97RshOjZ0M3dZ+CcKmIQz +37vjb80kk0p+jeuaLxprWjc5kLJjaFZNPA8mxM/UmARvMvBRrO4uRRRQvYFyXqi+ +Frsl46t/+nyarL09ICx/1reZIzsOsI9BcDM0CK1hqQSwrIjOK2mXuHVfrufXjLnR +wZA2rOonQJJAXgOo1RvD11xmOUUIglP2ljAZZskxL+zU8d5k9Ed4HkGsOY3ywbP0 +/E+Fd33Gli3EF01wAbIaZL0vuW2rW4oxjh8QW7O7Sfnsr9fdNU2Tye1jSCxle5e3 +2Sfq+0Iw5TiT0KYTmcpcKzvljd1wwHdiNKeo7ZCVIer/lGl62PoAb2NWeLepk0IO +IwTZ+Dq76hs9XZJbYxWhXpVcT31b9e3++jROMPz7Mzi/wMg+RBWXgjDuuj1Z16sF +MFfK6QEmD8SOKL3GAKn7PBQxZea+j6iF7G1nGz1/Wfvzz7I8DocnAmQZabKzEnpR +LTEU2LZ86pkeLkM3uI9jm/VWeV4xLv/dC7trDkTUSHpJ4J5/ItMecdAlhCEJ2qM2 +x46OUbGYsf9gvacLkqQoS/XFL8R4bxR01URlHU+98yfODBCehulmnKOz3dQOth2c +sF9v2spYG2gmY3jg7N8suvPbzYKWmL7pVCQtqVOZPkkCAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUy2Eg468T4F9w7gg9AxeZBj+gjKYwDgYDVR0P +AQH/BAQDAgGGMA0GCSqGSIb3DQEBDAUAA4ICAQCGLMyGrhwhqoDRtJ6gGx1SkJd4 +uxG3R4VFKS23JhDJKoDISjcCrVQu5Z3xSj157HmDnc/TEHgW/t1y472QOagzN2RD +9xgFBGfU1sHxKX79WBSf93L3alM+oE1tS+drDlBPV4gzxvCc+zvUYQKWjz/W6q9f +bdrk16J2/yOyli3XpEqf1o4c9FVnAbi9c3zdugfARskwypo2LHDuo8z+u/Ab7j1y +NZ8HtLg/hwVjfSoPLD8guYSZHXYn6ed7AmOUUJjlauWUfCCvU/F+Dk51JMLlVVK+ +y9ZgHXa8YDsGsCmpdgfC3MLSEVkx87mxj1rkFLI03q9i6L2BOWQtgd6NmvYd7pJx +cqx6bmSh43CscGDEngIB50XWqXd4QlVKmPPgDnd55szfnNQzzG9q8I9KTEv+B/Ck +apl2XxVAEUdb26Wi7RH+9Wms6HQeU4i7cDuWpm+EfZZmdjwvA4bs3Ox07SkenHqu +Ti6RJf1PiHoE9SHiFUiBnd++YsNByjGqn4Vxla1MlVdkaUMlvvc3/9oky4KfcRdQ +AK7L9cQqf7g6G4Ne5PNvosG3KaS009xSN1AAalTqS9eqrDYR2yZSixmUYqP57Jm5 +5ERI+pZi2aKpl0ONC7vKIyH+gxjsRPct4DKoxZnt4/KJYhINOlQz8i/j0jfqftmg +G1bYpbRRbfWoGHjGJA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECDCCAvCgAwIBAgIQTcWg4evi5wHEIHLNrHCqQjANBgkqhkiG9w0BAQsFADCB +nDELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu +Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTUwMwYDVQQDDCxB +bWF6b24gUkRTIGFwLXNvdXRoZWFzdC03IFJvb3QgQ0EgUlNBMjA0OCBHMTEQMA4G +A1UEBwwHU2VhdHRsZTAgFw0yNDA5MTIxNTU0MzFaGA8yMDY0MDkxMjE2NTQzMVow +gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ +bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws +QW1hem9uIFJEUyBhcC1zb3V0aGVhc3QtNyBSb290IENBIFJTQTIwNDggRzExEDAO +BgNVBAcMB1NlYXR0bGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCS +X21nYtSipOhpdF6QfLE4BTwbtrXCR3EBhOHB1MfwwjNh25uex3X/gHW/sUTgC/oe +Oboi+3I/HN6a5MneTcVVps8AL8rJGym0ShSIYza/3MyT+PtfqDNmYfmF8VRIhNSR +CoYW93F/BoZF7bFk4ljOrBSrRbfb1qmEtkTPNGBRnJ0jh05Fwq5a5XnkGcOGNDyH +kGt9ZaUm+cJmzAa1omHspCjgg6854CNs4k5ovT2vaZ/0yAogdSpkB9INLM0ZMqJ+ +QoKAyN6hdISjwEEZrl+0OKymc2jR+NpQcd3378bDIfg3iYvuvTp84kKpZ4gRaukm +mSUg/PQqmGdBlAivOiknAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFDsAilCg2DzFiZheGlKVb74AubP2MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQsFAAOCAQEACUGKd2GVv87xnVnPajqbi7GkMd+XGwyG1P8Nkon9rfUgwgHR +dHDsO6jIKf3ZEzNcMgMyV5sXs2944WRhGkYxQ62wbkEaqtjNExmlmUiS3vvrGOfg +BmRhJvAOM5HbNMqmi5BC4GlhHWQKhRbStwhvbVYnARBVfR/Wz4Qb4fizaXbuNWAo +V0XBQc+67lto2eBQ84KQXTp60FdwSBzltbM7sZmp6dMNgnfPNUrdxurVboF+VsxS +3aUJnmEi6TJAGL2SXLermB6HiTgxtxOJUiefu4Ipv0JEg41OzbKWsJXTaSH0QDb1 +nSeMyoXqF3ixcAhQbw/7NrzMMlf3NmMaVlohVA== +-----END CERTIFICATE----- diff --git a/tests/unit/test_db_rds.py b/tests/unit/test_db_rds.py index 5804be0e1..c75ff584f 100644 --- a/tests/unit/test_db_rds.py +++ b/tests/unit/test_db_rds.py @@ -99,3 +99,14 @@ def test_rds_testfree_postgres_urlencoded(self): assert config["DatabaseJdbcUrl"].find("sslmode") >= 0 assert config["DatabaseUserName"] == "ua98s7?ananla" assert config["DatabasePassword"] == "na8na+nlay&aona0--anbs" + + def test_rds_ap_southeast_7_uses_regional_certificate(self): + os.environ["VCAP_SERVICES"] = self.rds_vcap_example.replace( + "eu-west-1", "ap-southeast-7" + ) + + factory = DatabaseConfigurationFactory() + + config = factory.get_instance().get_m2ee_configuration() + + assert "ap-southeast-7-bundle.pem" in config["DatabaseJdbcUrl"]