Skip to content

Commit 68bc548

Browse files
committed
Use mypy for static type checking
# Conflicts: # .pre-commit-config.yaml # docker/mongodb-kubernetes-tests/kubetester/certs.py # Conflicts: # .pre-commit-config.yaml # Conflicts: # docker/mongodb-kubernetes-tests/kubetester/certs.py
1 parent a4f565f commit 68bc548

File tree

114 files changed

+558
-370
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+558
-370
lines changed

.pre-commit-config.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@ repos:
129129
^scripts/funcs/[^/]+$
130130
)
131131
132+
- repo: local
133+
hooks:
134+
- id: ty
135+
name: ty
136+
entry: bash -c 'cd docker/mongodb-kubernetes-tests && uvx ty check tests/'
137+
language: system
138+
pass_filenames: false
139+
files: docker/mongodb-kubernetes-tests/tests/.*\.py$
140+
stages: [pre-commit]
141+
132142
- repo: https://github.com/golangci/golangci-lint
133143
rev: v2.0.2
134144
hooks:

docker/mongodb-kubernetes-tests/kubeobject/customobject.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import copy
44
from datetime import datetime, timedelta
5-
from typing import Dict, Optional
5+
from typing import Any, Dict, Optional, Self
66

77
import yaml
88
from kubernetes import client
@@ -43,6 +43,7 @@ def __init__(
4343
version=version,
4444
api_client=api_client,
4545
)
46+
assert crd is not None, "Could not find CRD matching the given parameters"
4647
self.kind = crd.spec.names.kind
4748
self.plural = crd.spec.names.plural
4849
self.group = crd.spec.group
@@ -71,7 +72,7 @@ def __init__(
7172
self.auto_reload_period = timedelta(seconds=2)
7273

7374
# Last time this object was updated
74-
self.last_update: datetime = None
75+
self.last_update: Optional[datetime] = None
7576

7677
# Sets the API used for this particular type of object
7778
self.api = client.CustomObjectsApi(api_client=api_client)
@@ -85,7 +86,7 @@ def __init__(
8586
"status": {},
8687
}
8788

88-
def load(self) -> CustomObject:
89+
def load(self) -> Self:
8990
"""Loads this object from the API."""
9091

9192
obj = self.api.get_namespaced_custom_object(self.group, self.version, self.namespace, self.plural, self.name)
@@ -202,7 +203,7 @@ def from_yaml(cls, yaml_file, name=None, namespace=None, cluster_scoped=False):
202203

203204
@classmethod
204205
def define(
205-
cls: CustomObject,
206+
cls,
206207
name: str,
207208
kind: Optional[str] = None,
208209
plural: Optional[str] = None,
@@ -284,7 +285,7 @@ def get_crd_names(
284285
group: Optional[str] = None,
285286
version: Optional[str] = None,
286287
api_client: Optional[client.ApiClient] = None,
287-
) -> Optional[Dict]:
288+
) -> Optional[Any]:
288289
"""Gets the CRD entry that matches all the parameters passed."""
289290
api = client.ApiextensionsV1Api(api_client=api_client)
290291

@@ -313,6 +314,8 @@ def get_crd_names(
313314
if found:
314315
return crd
315316

317+
return None
318+
316319

317320
def create_or_update(resource: CustomObject) -> CustomObject:
318321
"""

docker/mongodb-kubernetes-tests/kubetester/__init__.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def delete_service_account(namespace: str, name: str) -> str:
7575

7676
def get_service(
7777
namespace: str, name: str, api_client: Optional[kubernetes.client.ApiClient] = None
78-
) -> client.V1ServiceSpec:
78+
) -> Optional[client.V1Service]:
7979
"""Gets a service with `name` in `namespace.
8080
:return None if the service does not exist
8181
"""
@@ -148,6 +148,13 @@ def create_or_update_service(
148148
service: Optional[client.V1Service] = None,
149149
) -> str:
150150
print("Logging inside create_or_update_service")
151+
if service_name is None and service is not None:
152+
if isinstance(service, dict):
153+
service_name = service.get("metadata", {}).get("name")
154+
elif hasattr(service, "metadata") and service.metadata is not None:
155+
service_name = service.metadata.name
156+
if service_name is None:
157+
raise ValueError("service_name must not be None")
151158
try:
152159
create_service(namespace, service_name, cluster_ip=cluster_ip, ports=ports, selector=selector, service=service)
153160
except kubernetes.client.ApiException as e:
@@ -247,8 +254,8 @@ def delete_pod(namespace: str, name: str, api_client: Optional[kubernetes.client
247254

248255
def create_or_update_namespace(
249256
namespace: str,
250-
labels: dict = None,
251-
annotations: dict = None,
257+
labels: Optional[dict] = None,
258+
annotations: Optional[dict] = None,
252259
api_client: Optional[kubernetes.client.ApiClient] = None,
253260
):
254261
namespace_resource = client.V1Namespace(
@@ -368,7 +375,7 @@ def get_pod_when_ready(
368375
"""
369376
cnt = 0
370377

371-
while True and cnt < default_retry:
378+
while default_retry is not None and cnt < default_retry:
372379
print(f"get_pod_when_ready: namespace={namespace}, label_selector={label_selector}")
373380

374381
if cnt > 0:
@@ -429,7 +436,7 @@ def is_pod_ready(
429436
return None
430437

431438

432-
def get_default_storage_class() -> str:
439+
def get_default_storage_class() -> Optional[str]:
433440
default_class_annotations = (
434441
"storageclass.kubernetes.io/is-default-class", # storage.k8s.io/v1
435442
"storageclass.beta.kubernetes.io/is-default-class", # storage.k8s.io/v1beta1
@@ -440,6 +447,7 @@ def get_default_storage_class() -> str:
440447
sc.metadata.annotations.get(a) == "true" for a in default_class_annotations
441448
):
442449
return sc.metadata.name
450+
return None
443451

444452

445453
def decode_secret(data: Dict[str, str]) -> Dict[str, str]:

docker/mongodb-kubernetes-tests/kubetester/automation_config_tester.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def assert_oidc_providers_size(self, expected_size: int):
104104
assert len(self.automation_config["oidcProviderConfigs"]) == expected_size
105105

106106
def assert_oidc_configuration(self, oidc_config: Optional[Dict] = None):
107+
assert oidc_config is not None, "oidc_config must not be None"
107108
actual_configs = self.automation_config["oidcProviderConfigs"]
108109
assert len(actual_configs) == len(
109110
oidc_config

docker/mongodb-kubernetes-tests/kubetester/certs.py

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,14 @@ class Issuer(IssuerType, WaitForConditions):
8181
Reason = "KeyPairVerified"
8282

8383

84-
class ClusterIssuer(ClusterIssuerType, WaitForConditions):
84+
class ClusterIssuer(ClusterIssuerType, WaitForConditions): # type: ignore[valid-type, misc]
8585
Reason = "KeyPairVerified"
8686

8787

8888
def generate_cert(
8989
namespace: str,
90-
pod: str,
91-
dns: str,
90+
pod: str | list[str],
91+
dns: str | list[str],
9292
issuer: str,
9393
spec: Optional[Dict] = None,
9494
additional_domains: Optional[List[str]] = None,
@@ -113,15 +113,18 @@ def generate_cert(
113113
cert = Certificate(namespace=namespace, name=secret_name)
114114

115115
if multi_cluster_mode:
116-
dns_names = dns_list
116+
dns_names = dns_list if dns_list is not None else []
117117
else:
118-
dns_names = [dns]
118+
dns_names = dns if isinstance(dns, list) else [dns]
119119

120120
if not multi_cluster_mode:
121-
dns_names.append(pod)
121+
if isinstance(pod, list):
122+
dns_names.extend(pod)
123+
else:
124+
dns_names.append(pod)
122125

123126
if additional_domains is not None:
124-
dns_names += additional_domains
127+
dns_names = dns_names + additional_domains
125128

126129
issuerRef = {"name": issuer, "kind": "Issuer"}
127130
if clusterwide:
@@ -176,8 +179,8 @@ def create_tls_certs(
176179
namespace: str,
177180
resource_name: str,
178181
replicas: int = 3,
179-
replicas_cluster_distribution: Optional[List[int]] = None,
180-
service_name: str = None,
182+
replicas_cluster_distribution: Optional[List[Optional[int]]] = None,
183+
service_name: Optional[str] = None,
181184
spec: Optional[Dict] = None,
182185
secret_name: Optional[str] = None,
183186
additional_domains: Optional[List[str]] = None,
@@ -308,8 +311,8 @@ def create_mongodb_tls_certs(
308311
resource_name: str,
309312
bundle_secret_name: str,
310313
replicas: int = 3,
311-
replicas_cluster_distribution: Optional[List[int]] = None,
312-
service_name: str = None,
314+
replicas_cluster_distribution: Optional[List[Optional[int]]] = None,
315+
service_name: Optional[str] = None,
313316
spec: Optional[Dict] = None,
314317
additional_domains: Optional[List[str]] = None,
315318
secret_backend: Optional[str] = None,
@@ -342,7 +345,7 @@ def create_mongodb_tls_certs(
342345
def multi_cluster_service_fqdns(
343346
resource_name: str,
344347
namespace: str,
345-
external_domain: str,
348+
external_domain: Optional[str],
346349
cluster_index: int,
347350
replicas: int,
348351
) -> List[str]:
@@ -374,11 +377,14 @@ def create_x509_mongodb_tls_certs(
374377
resource_name: str,
375378
bundle_secret_name: str,
376379
replicas: int = 3,
377-
replicas_cluster_distribution: Optional[List[int]] = None,
378-
service_name: str = None,
380+
replicas_cluster_distribution: Optional[List[Optional[int]]] = None,
381+
service_name: Optional[str] = None,
382+
spec: Optional[Dict] = None,
379383
additional_domains: Optional[List[str]] = None,
380384
secret_backend: Optional[str] = None,
381385
vault_subpath: Optional[str] = None,
386+
process_hostnames: Optional[List[str]] = None,
387+
clusterwide: bool = False,
382388
) -> str:
383389
spec = get_mongodb_x509_subject(namespace)
384390

@@ -394,6 +400,8 @@ def create_x509_mongodb_tls_certs(
394400
additional_domains=additional_domains,
395401
secret_backend=secret_backend,
396402
vault_subpath=vault_subpath,
403+
process_hostnames=process_hostnames,
404+
clusterwide=clusterwide,
397405
)
398406

399407

@@ -484,9 +492,9 @@ def create_sharded_cluster_certs(
484492
additional_domains: Optional[List[str]] = None,
485493
secret_prefix: Optional[str] = None,
486494
secret_backend: Optional[str] = None,
487-
shard_distribution: Optional[List[int]] = None,
488-
mongos_distribution: Optional[List[int]] = None,
489-
config_srv_distribution: Optional[List[int]] = None,
495+
shard_distribution: Optional[List[Optional[int]]] = None,
496+
mongos_distribution: Optional[List[Optional[int]]] = None,
497+
config_srv_distribution: Optional[List[Optional[int]]] = None,
490498
):
491499
cert_generation_func = create_mongodb_tls_certs
492500
if x509_certs:

docker/mongodb-kubernetes-tests/kubetester/certs_mongodb_multi.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def create_multi_cluster_tls_certs(
128128
secret_name: str,
129129
central_cluster_client: kubernetes.client.ApiClient,
130130
member_clients: List[MultiClusterClient],
131-
mongodb_multi: Optional[CustomObject] = None,
131+
mongodb_multi: Optional[MongoDBMulti] = None,
132132
namespace: Optional[str] = None,
133133
secret_backend: Optional[str] = None,
134134
additional_domains: Optional[List[str]] = None,
@@ -137,6 +137,7 @@ def create_multi_cluster_tls_certs(
137137
spec: Optional[dict] = None,
138138
) -> str:
139139
if service_fqdns is None:
140+
assert mongodb_multi is not None, "mongodb_multi is required when service_fqdns is not provided"
140141
service_fqdns = [f"{mongodb_multi.name}-svc.{mongodb_multi.namespace}.svc.cluster.local"]
141142

142143
for client in member_clients:
@@ -145,6 +146,7 @@ def create_multi_cluster_tls_certs(
145146
external_domain = cluster_spec["externalAccess"]["externalDomain"]
146147
except KeyError:
147148
external_domain = None
149+
assert client.cluster_index is not None
148150
service_fqdns.extend(
149151
multi_cluster_service_fqdns(
150152
mongodb_multi.name,
@@ -156,6 +158,7 @@ def create_multi_cluster_tls_certs(
156158
)
157159

158160
if namespace is None:
161+
assert mongodb_multi is not None, "mongodb_multi is required when namespace is not provided"
159162
namespace = mongodb_multi.namespace
160163

161164
generate_cert(

docker/mongodb-kubernetes-tests/kubetester/crypto.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def generate_csr(namespace: str, host: str, servicename: str):
4949
)
5050

5151

52-
def get_pem_certificate(name: str) -> Optional[str]:
52+
def get_pem_certificate(name: str) -> Optional[bytes]:
5353
body = client.CertificatesV1Api().read_certificate_signing_request_status(name)
5454
if body.status.certificate is None:
5555
return None

docker/mongodb-kubernetes-tests/kubetester/helm.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def helm_template(
3434
command_args.append("--show-only")
3535
command_args.append(templates)
3636

37+
helm_chart_path = helm_chart_path or "helm_chart"
3738
args = ("helm", "template", *command_args, helm_chart_path)
3839
logger.info(" ".join(args))
3940

@@ -53,6 +54,7 @@ def helm_install(
5354
custom_operator_version: Optional[str] = None,
5455
):
5556
command_args = _create_helm_args(helm_args, helm_options)
57+
helm_chart_path = helm_chart_path or "helm_chart"
5658
args = [
5759
"helm",
5860
"upgrade",
@@ -176,7 +178,8 @@ def helm_registry_login_to_ecr(helm_registry: str, region: str):
176178

177179
# Close the stdout stream of aws_proc in the parent process
178180
# to prevent resource leakage (only needed if you plan to do more processing)
179-
aws_proc.stdout.close()
181+
if aws_proc.stdout:
182+
aws_proc.stdout.close()
180183

181184
# Wait for the Helm command (helm_proc) to finish and capture its output
182185
helm_stdout, helm_stderr = helm_proc.communicate()
@@ -297,17 +300,19 @@ def _create_helm_args(helm_args: Dict[str, str], helm_options: Optional[List[str
297300
def helm_chart_path_and_version(helm_chart_path: str, operator_version: str) -> tuple[str, str]:
298301
# if helm_chart_path is not passed, use the default value from DEFAULT_HELM_CHART_PATH
299302
if not helm_chart_path:
300-
helm_chart_path = os.getenv(DEFAULT_HELM_CHART_PATH_ENV_VAR_NAME)
303+
helm_chart_path = os.getenv(DEFAULT_HELM_CHART_PATH_ENV_VAR_NAME, "")
301304

302305
if helm_chart_path.startswith("oci://"):
303306
# If operator_version is not passed, we want to install the current version.
304307
if not operator_version:
305-
operator_version = os.environ.get(OCI_HELM_VERSION_ENV_VAR_NAME)
308+
operator_version = os.environ.get(OCI_HELM_VERSION_ENV_VAR_NAME, "")
306309

307-
registry = os.environ.get(OCI_HELM_REGISTRY_ENV_VAR_NAME)
310+
registry = os.environ.get(OCI_HELM_REGISTRY_ENV_VAR_NAME, "")
308311
# If ECR we need to login first to the OCI container registry
309312
if registry == OCI_HELM_REGISTRY_ECR:
310313
region = os.environ.get(OCI_HELM_REGION_ENV_VAR_NAME)
314+
if not region:
315+
raise ValueError(f"{OCI_HELM_REGION_ENV_VAR_NAME} must be set when using ECR registry")
311316
try:
312317
helm_registry_login_to_ecr(registry, region)
313318
except Exception as e:

docker/mongodb-kubernetes-tests/kubetester/http.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def get_retriable_https_session(*, tls_verify: bool) -> requests.Session:
3030
return get_retriable_session("https", tls_verify)
3131

3232

33-
def https_endpoint_is_reachable(url: str, auth: Tuple[str], *, tls_verify: bool) -> bool:
33+
def https_endpoint_is_reachable(url: str, auth: Tuple[str, str], *, tls_verify: bool) -> bool:
3434
"""
3535
Checks that `url` is reachable, using `auth` basic credentials.
3636
"""

docker/mongodb-kubernetes-tests/kubetester/kmip.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ def _create_tls_certs_kmip(
124124
resource_name: str,
125125
bundle_secret_name: str,
126126
replicas: int = 3,
127-
service_name: str = None,
127+
service_name: Optional[str] = None,
128128
spec: Optional[Dict] = None,
129129
) -> str:
130130
ca = read_configmap(namespace, self.ca_configmap)
@@ -135,7 +135,7 @@ def _create_tls_certs_kmip(
135135
replicas=replicas,
136136
service_name=service_name,
137137
spec=spec,
138-
additional_domains=[service_name],
138+
additional_domains=[service_name] if service_name else None,
139139
)
140140
secret = read_secret(namespace, cert_secret_name)
141141
create_or_update_secret(

0 commit comments

Comments
 (0)