From f561efef1f948f417b20c48a6fcded26ee71e791 Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Wed, 9 Oct 2024 15:50:53 -0400 Subject: [PATCH 1/2] PYTHON-4574 - FaaS detection logic mistakenly identifies EKS as AWS Lambda --- pymongo/pool_options.py | 60 +++++++++++++++++--------------- test/asynchronous/test_client.py | 12 +++++++ test/test_client.py | 12 +++++++ 3 files changed, 55 insertions(+), 29 deletions(-) diff --git a/pymongo/pool_options.py b/pymongo/pool_options.py index 61486c91c6..1beab97e35 100644 --- a/pymongo/pool_options.py +++ b/pymongo/pool_options.py @@ -179,37 +179,39 @@ def _getenv_int(key: str) -> Optional[int]: def _metadata_env() -> dict[str, Any]: env: dict[str, Any] = {} container = get_container_env_info() + # Don't populate FaaS metadata if a container is present. if container: env["container"] = container - # Skip if multiple (or no) envs are matched. - if (_is_lambda(), _is_azure_func(), _is_gcp_func(), _is_vercel()).count(True) != 1: - return env - if _is_lambda(): - env["name"] = "aws.lambda" - region = os.getenv("AWS_REGION") - if region: - env["region"] = region - memory_mb = _getenv_int("AWS_LAMBDA_FUNCTION_MEMORY_SIZE") - if memory_mb is not None: - env["memory_mb"] = memory_mb - elif _is_azure_func(): - env["name"] = "azure.func" - elif _is_gcp_func(): - env["name"] = "gcp.func" - region = os.getenv("FUNCTION_REGION") - if region: - env["region"] = region - memory_mb = _getenv_int("FUNCTION_MEMORY_MB") - if memory_mb is not None: - env["memory_mb"] = memory_mb - timeout_sec = _getenv_int("FUNCTION_TIMEOUT_SEC") - if timeout_sec is not None: - env["timeout_sec"] = timeout_sec - elif _is_vercel(): - env["name"] = "vercel" - region = os.getenv("VERCEL_REGION") - if region: - env["region"] = region + else: + # Skip if multiple (or no) envs are matched. + if (_is_lambda(), _is_azure_func(), _is_gcp_func(), _is_vercel()).count(True) != 1: + return env + if _is_lambda(): + env["name"] = "aws.lambda" + region = os.getenv("AWS_REGION") + if region: + env["region"] = region + memory_mb = _getenv_int("AWS_LAMBDA_FUNCTION_MEMORY_SIZE") + if memory_mb is not None: + env["memory_mb"] = memory_mb + elif _is_azure_func(): + env["name"] = "azure.func" + elif _is_gcp_func(): + env["name"] = "gcp.func" + region = os.getenv("FUNCTION_REGION") + if region: + env["region"] = region + memory_mb = _getenv_int("FUNCTION_MEMORY_MB") + if memory_mb is not None: + env["memory_mb"] = memory_mb + timeout_sec = _getenv_int("FUNCTION_TIMEOUT_SEC") + if timeout_sec is not None: + env["timeout_sec"] = timeout_sec + elif _is_vercel(): + env["name"] = "vercel" + region = os.getenv("VERCEL_REGION") + if region: + env["region"] = region return env diff --git a/test/asynchronous/test_client.py b/test/asynchronous/test_client.py index faa23348c9..46409141ac 100644 --- a/test/asynchronous/test_client.py +++ b/test/asynchronous/test_client.py @@ -2019,6 +2019,18 @@ async def test_handshake_08_invalid_aws_ec2(self): None, ) + async def test_handshake_09_container_with_provider(self): + # No FaaS metadata should be present. + await self._test_handshake( + { + ENV_VAR_K8S: "1", + "AWS_LAMBDA_RUNTIME_API": "1", + "AWS_REGION": "us-east-1", + "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "256", + }, + {"container": {"orchestrator": "kubernetes"}}, + ) + def test_dict_hints(self): self.db.t.find(hint={"x": 1}) diff --git a/test/test_client.py b/test/test_client.py index be1994dd93..c78310713a 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -1977,6 +1977,18 @@ def test_handshake_08_invalid_aws_ec2(self): None, ) + def test_handshake_09_container_with_provider(self): + # No FaaS metadata should be present. + self._test_handshake( + { + ENV_VAR_K8S: "1", + "AWS_LAMBDA_RUNTIME_API": "1", + "AWS_REGION": "us-east-1", + "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "256", + }, + {"container": {"orchestrator": "kubernetes"}}, + ) + def test_dict_hints(self): self.db.t.find(hint={"x": 1}) From 857b7ea9b008ec690a6b5109b285bcb6f9638671 Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Fri, 11 Oct 2024 10:56:50 -0400 Subject: [PATCH 2/2] Update to reflect expected behavior --- pymongo/pool_options.py | 60 +++++++++++++++----------------- test/asynchronous/test_client.py | 8 +++-- test/test_client.py | 8 +++-- 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/pymongo/pool_options.py b/pymongo/pool_options.py index 1beab97e35..61486c91c6 100644 --- a/pymongo/pool_options.py +++ b/pymongo/pool_options.py @@ -179,39 +179,37 @@ def _getenv_int(key: str) -> Optional[int]: def _metadata_env() -> dict[str, Any]: env: dict[str, Any] = {} container = get_container_env_info() - # Don't populate FaaS metadata if a container is present. if container: env["container"] = container - else: - # Skip if multiple (or no) envs are matched. - if (_is_lambda(), _is_azure_func(), _is_gcp_func(), _is_vercel()).count(True) != 1: - return env - if _is_lambda(): - env["name"] = "aws.lambda" - region = os.getenv("AWS_REGION") - if region: - env["region"] = region - memory_mb = _getenv_int("AWS_LAMBDA_FUNCTION_MEMORY_SIZE") - if memory_mb is not None: - env["memory_mb"] = memory_mb - elif _is_azure_func(): - env["name"] = "azure.func" - elif _is_gcp_func(): - env["name"] = "gcp.func" - region = os.getenv("FUNCTION_REGION") - if region: - env["region"] = region - memory_mb = _getenv_int("FUNCTION_MEMORY_MB") - if memory_mb is not None: - env["memory_mb"] = memory_mb - timeout_sec = _getenv_int("FUNCTION_TIMEOUT_SEC") - if timeout_sec is not None: - env["timeout_sec"] = timeout_sec - elif _is_vercel(): - env["name"] = "vercel" - region = os.getenv("VERCEL_REGION") - if region: - env["region"] = region + # Skip if multiple (or no) envs are matched. + if (_is_lambda(), _is_azure_func(), _is_gcp_func(), _is_vercel()).count(True) != 1: + return env + if _is_lambda(): + env["name"] = "aws.lambda" + region = os.getenv("AWS_REGION") + if region: + env["region"] = region + memory_mb = _getenv_int("AWS_LAMBDA_FUNCTION_MEMORY_SIZE") + if memory_mb is not None: + env["memory_mb"] = memory_mb + elif _is_azure_func(): + env["name"] = "azure.func" + elif _is_gcp_func(): + env["name"] = "gcp.func" + region = os.getenv("FUNCTION_REGION") + if region: + env["region"] = region + memory_mb = _getenv_int("FUNCTION_MEMORY_MB") + if memory_mb is not None: + env["memory_mb"] = memory_mb + timeout_sec = _getenv_int("FUNCTION_TIMEOUT_SEC") + if timeout_sec is not None: + env["timeout_sec"] = timeout_sec + elif _is_vercel(): + env["name"] = "vercel" + region = os.getenv("VERCEL_REGION") + if region: + env["region"] = region return env diff --git a/test/asynchronous/test_client.py b/test/asynchronous/test_client.py index 46409141ac..c6b6416c16 100644 --- a/test/asynchronous/test_client.py +++ b/test/asynchronous/test_client.py @@ -2020,7 +2020,6 @@ async def test_handshake_08_invalid_aws_ec2(self): ) async def test_handshake_09_container_with_provider(self): - # No FaaS metadata should be present. await self._test_handshake( { ENV_VAR_K8S: "1", @@ -2028,7 +2027,12 @@ async def test_handshake_09_container_with_provider(self): "AWS_REGION": "us-east-1", "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "256", }, - {"container": {"orchestrator": "kubernetes"}}, + { + "container": {"orchestrator": "kubernetes"}, + "name": "aws.lambda", + "region": "us-east-1", + "memory_mb": 256, + }, ) def test_dict_hints(self): diff --git a/test/test_client.py b/test/test_client.py index c78310713a..8e3d9c8b8b 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -1978,7 +1978,6 @@ def test_handshake_08_invalid_aws_ec2(self): ) def test_handshake_09_container_with_provider(self): - # No FaaS metadata should be present. self._test_handshake( { ENV_VAR_K8S: "1", @@ -1986,7 +1985,12 @@ def test_handshake_09_container_with_provider(self): "AWS_REGION": "us-east-1", "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "256", }, - {"container": {"orchestrator": "kubernetes"}}, + { + "container": {"orchestrator": "kubernetes"}, + "name": "aws.lambda", + "region": "us-east-1", + "memory_mb": 256, + }, ) def test_dict_hints(self):