PYTHON-3837 Driver Container and Kubernetes Awareness (#1418)

This commit is contained in:
Noah Stapp 2023-11-02 13:13:45 -07:00 committed by GitHub
parent 923c8a5abe
commit 6c88c73219
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 1 deletions

View File

@ -25,6 +25,7 @@ import sys
import threading
import time
import weakref
from pathlib import Path
from typing import (
TYPE_CHECKING,
Any,
@ -268,6 +269,25 @@ else:
(platform.python_implementation(), ".".join(map(str, sys.version_info)))
)
DOCKER_ENV_PATH = "/.dockerenv"
ENV_VAR_K8S = "KUBERNETES_SERVICE_HOST"
RUNTIME_NAME_DOCKER = "docker"
ORCHESTRATOR_NAME_K8S = "kubernetes"
def get_container_env_info() -> dict[str, str]:
"""Returns the runtime and orchestrator of a container.
If neither value is present, the metadata client.env.container field will be omitted."""
container = {}
if Path(DOCKER_ENV_PATH).exists():
container["runtime"] = RUNTIME_NAME_DOCKER
if os.getenv(ENV_VAR_K8S):
container["orchestrator"] = ORCHESTRATOR_NAME_K8S
return container
def _is_lambda() -> bool:
if os.getenv("AWS_LAMBDA_RUNTIME_API"):
@ -307,6 +327,9 @@ def _getenv_int(key: str) -> Optional[int]:
def _metadata_env() -> dict[str, Any]:
env: dict[str, Any] = {}
container = get_container_env_info()
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

View File

@ -29,6 +29,7 @@ import sys
import threading
import time
from typing import Iterable, Type, no_type_check
from unittest import mock
from unittest.mock import patch
sys.path[0:0] = [""]
@ -97,7 +98,7 @@ from pymongo.errors import (
)
from pymongo.mongo_client import MongoClient
from pymongo.monitoring import ServerHeartbeatListener, ServerHeartbeatStartedEvent
from pymongo.pool import _METADATA, Connection, PoolOptions
from pymongo.pool import _METADATA, DOCKER_ENV_PATH, ENV_VAR_K8S, Connection, PoolOptions
from pymongo.read_preferences import ReadPreference
from pymongo.server_description import ServerDescription
from pymongo.server_selectors import readable_server_selector, writable_server_selector
@ -347,6 +348,15 @@ class ClientUnitTest(unittest.TestCase):
options = client._MongoClient__options
self.assertEqual(options.pool_options.metadata, metadata)
@mock.patch.dict("os.environ", {ENV_VAR_K8S: "1"})
def test_container_metadata(self):
metadata = copy.deepcopy(_METADATA)
metadata["env"] = {}
metadata["env"]["container"] = {"orchestrator": "kubernetes"}
client = MongoClient("mongodb://foo:27017/?appname=foobar&connect=false")
options = client._MongoClient__options
self.assertEqual(options.pool_options.metadata["env"], metadata["env"])
def test_kwargs_codec_options(self):
class MyFloatType:
def __init__(self, x):