Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2d9b71d
added the metering code
Apr 7, 2026
1f6eaf5
added logging
Apr 8, 2026
4f74252
added the sap metering sidecar
Apr 9, 2026
b578089
updated the auth token usage
Apr 14, 2026
0452f16
updated the comments
Apr 14, 2026
241305f
updated the env vars
Apr 17, 2026
8fc3a83
Merge pull request #888 from bhavinshah-mendix/feature/sap-metering-s…
mayankmendix Apr 17, 2026
145110c
fix: update cryptography to 46.0.7 to address CVE-2026-39892
Apr 23, 2026
4e0365b
Bumped the cryptography module version to latest 47.0.0
Apr 27, 2026
244e12f
Merge pull request #889 from Pri1235/fix/update-cryptography-46.0.7
mayankmendix Apr 28, 2026
446fe36
Fix CVE-2026-25645 and CVE-2026-34073 by upgrading requests and crypt…
May 8, 2026
813d91d
Merge pull request #890 from PiyushTiwari-LowCode/fix-CVE-Cryptograph…
mayankmendix May 11, 2026
ef8bec4
Security/upgrade requests urllib3 CVE fix (#894)
bhavinshahM May 25, 2026
981b11a
Merge branch 'master' into develop
mayankmendix May 28, 2026
70bb176
Merge branch 'master' into develop
sailhenz May 29, 2026
89b2ec4
(fix) add typing extension lib (#898)
mayankmendix May 29, 2026
5f4fcf3
Expand static files caching (#901)
EnasAbdelrazek Jun 15, 2026
e316ef6
Security: Fix CVE-2026-45409 (idna) and GHSA-537c-gmf6-5ccf (cryptogr…
bhavinshahM Jul 3, 2026
4efd60a
Security: Upgrade nginx from 1.26.1 to 1.30.4 to fix CVE-2025-23419 a…
bhavinshahM Aug 12, 2026
e555256
Fix CVE-2026-69247(cryptography)andCVE-2026-59939(httplib2) (#907)
PiyushTiwari-LowCode Aug 12, 2026
6f11727
Add deprecation warning for Cloud Foundry Buildpack (#910)
mruiserrmendix Aug 13, 2026
29f557f
Merge branch 'master' into develop
mayankmendix Aug 13, 2026
8f15348
Fix PostgreSQL metrics query to filter by application database (#914)
bhavinshahM Sep 2, 2026
7ae5435
Feature/sap hana client jar stage (#915)
Pri1235 Sep 16, 2026
74618d6
Skip staging SAP HANA client JAR if already present in userlib or ven…
Pri1235 Sep 21, 2026
53442d5
Add RDS ap-southeast-7 support (#917)
bhavinshahM Sep 28, 2026
374cc4b
Merge branch 'master' into develop
mayankmendix Sep 28, 2026
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
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <YOUR_APP> 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).
Expand Down
39 changes: 39 additions & 0 deletions buildpack/core/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import time

import backoff
import glob
import requests
from buildpack import util
from lib.m2ee import M2EE as m2ee_class
from lib.m2ee.version import MXVersion
Expand Down Expand Up @@ -56,6 +58,42 @@ 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

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(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...")
Expand Down Expand Up @@ -85,6 +123,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"
Expand Down
2 changes: 2 additions & 0 deletions buildpack/infrastructure/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
76 changes: 76 additions & 0 deletions etc/rds-certificates/ap-southeast-7-bundle.pem
Original file line number Diff line number Diff line change
@@ -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-----
6 changes: 6 additions & 0 deletions etc/telegraf/telegraf.toml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -116,6 +117,7 @@
datname,
deadlocks
FROM pg_stat_database
WHERE datname = '{{ db_config["DatabaseName"] }}'
"""
version = 920
withdbname = false
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -228,6 +233,7 @@
datname,
temp_files AS temp_files_rate
FROM pg_stat_database
WHERE datname = '{{ db_config["DatabaseName"] }}'
"""
version = 920
withdbname = false
Expand Down
11 changes: 11 additions & 0 deletions tests/unit/test_db_rds.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Loading