qontract-reconcile 0.10.1rc830__py3-none-any.whl → 0.10.1rc832__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qontract-reconcile
3
- Version: 0.10.1rc830
3
+ Version: 0.10.1rc832
4
4
  Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
5
5
  Home-page: https://github.com/app-sre/qontract-reconcile
6
6
  Author: Red Hat App-SRE Team
@@ -10,7 +10,7 @@ reconcile/aws_iam_password_reset.py,sha256=NwErtrqgBiXr7eGCAHdtGGOx0S7-4JnSc29Ie
10
10
  reconcile/aws_support_cases_sos.py,sha256=Jk6_XjDeJSYxgRGqcEAOcynt9qJF2r5HPIPcSKmoBv8,2974
11
11
  reconcile/blackbox_exporter_endpoint_monitoring.py,sha256=W_VJagnsJR1v5oqjlI3RJJE0_nhtJ0m81RS8zWA5u5c,3538
12
12
  reconcile/checkpoint.py,sha256=R2WFXUXLTB4sWMi4GeA4eegsuf_1-Q4vH8M0Toh3Ij4,5036
13
- reconcile/cli.py,sha256=UnVVYcG6lqGAhUcXXCUsxw-eVlU4AyHjI5fAE4E_4DQ,101994
13
+ reconcile/cli.py,sha256=bRYr5vnUstP3dkRmt3NOyCaA4n-1xIxQU6vooISgFTk,102404
14
14
  reconcile/closedbox_endpoint_monitoring_base.py,sha256=SMhkcQqprWvThrIJa3U_3uh5w1h-alleW1QnCJFY4Qw,4909
15
15
  reconcile/cluster_deployment_mapper.py,sha256=2Ah-nu-Mdig0pjuiZl_XLrmVAjYzFjORR3dMlCgkmw0,2352
16
16
  reconcile/dashdotdb_base.py,sha256=R2JuwiXAEYAFiCtnztM_IIr1rtVzPpaWAmgxuDa2FgY,4813
@@ -115,7 +115,7 @@ reconcile/terraform_repo.py,sha256=xkp5EiRQ7cz-IquXiBq5plvBQLf910tqywKK0B_QlPM,1
115
115
  reconcile/terraform_resources.py,sha256=BN8XuJwjOt1ztruEAHydkd0YiBlb3fHZ7n0snZtRhck,19356
116
116
  reconcile/terraform_tgw_attachments.py,sha256=S5IP7RmnVuVSOIPXFlUX2srGBrBBeH2uM4J6ewHCvOQ,18797
117
117
  reconcile/terraform_users.py,sha256=9rgbM572LfmOSnV3uCP20G_Cw6T7due94g8rhhiz904,10225
118
- reconcile/terraform_vpc_peerings.py,sha256=rnDH1u93OyzrBM8Hib0HwSnlxZtx4ScRQaZAcn3mx-k,25402
118
+ reconcile/terraform_vpc_peerings.py,sha256=WhGvDHwllM36yTJPE5EzQ1Z0Oc-tT9ksXbBn5cpFBBg,27676
119
119
  reconcile/vault_replication.py,sha256=79GZ_kCimPoQcxkdhkWTQxPOAa46E0mNhf05s_Mk5so,17385
120
120
  reconcile/vpc_peerings_validator.py,sha256=Kv22HJVlTW9l9GB2eXwjPWqdDbr_VuvQBNPttox6s5o,7177
121
121
  reconcile/aus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -537,8 +537,8 @@ reconcile/test/test_terraform_repo.py,sha256=j9mLfwiK707U2KRxYpvzAbOYywk__pL9SXA
537
537
  reconcile/test/test_terraform_resources.py,sha256=EFCqPI5_G8hPRh1zmnU91o8wMeT2qK1CabDUa_X1rSk,15283
538
538
  reconcile/test/test_terraform_tgw_attachments.py,sha256=rHZHUtDxewpKsRj3nfm2bZ2JoQ4CWiN2nQM-SWkMopg,41047
539
539
  reconcile/test/test_terraform_users.py,sha256=XOAfGvITCJPI1LTlISmHbA4ONMQMkxYUMTsny7pQCFw,4319
540
- reconcile/test/test_terraform_vpc_peerings.py,sha256=ubcsKh0TrUIwuI1-W3ETIgzsFvzAyeoFmEJFC-IK6JY,20538
541
- reconcile/test/test_terraform_vpc_peerings_build_desired_state.py,sha256=DAfpb12I0PlqnuVUHK2vh4LH4d1OylT3H2GE_3TGZZI,47852
540
+ reconcile/test/test_terraform_vpc_peerings.py,sha256=Btl0ym7NmO2QFST9Xviz4OO1RjJuhCp1Xhix5A3e_HQ,20822
541
+ reconcile/test/test_terraform_vpc_peerings_build_desired_state.py,sha256=7VAFVbjlnnUJoOkZ4ApDc1lHFj38Zj4yrbDKvWkqWXE,49545
542
542
  reconcile/test/test_three_way_diff_strategy.py,sha256=0QY2hzOrTVnQxDFbdOJBOIIHEKKOA5RmGftT0QXABeY,3697
543
543
  reconcile/test/test_utils_jinja2.py,sha256=TpzQlpFnLGzNEZp5WOh0o7AuBiGEktqO4MuwiiJW2YY,3895
544
544
  reconcile/test/test_vault_replication.py,sha256=wlc4jm9f8P641UvvxIFFFc5_unJysNkOVrKJscjhQr0,16867
@@ -812,8 +812,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
812
812
  tools/test/test_qontract_cli.py,sha256=_D61RFGAN5x44CY1tYbouhlGXXABwYfxKSWSQx3Jrss,4941
813
813
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
814
814
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
815
- qontract_reconcile-0.10.1rc830.dist-info/METADATA,sha256=dFJyqmQPBYPDrL163PxcGXf0YY_SvLi75h_E5O5d5nQ,2314
816
- qontract_reconcile-0.10.1rc830.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
817
- qontract_reconcile-0.10.1rc830.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
818
- qontract_reconcile-0.10.1rc830.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
819
- qontract_reconcile-0.10.1rc830.dist-info/RECORD,,
815
+ qontract_reconcile-0.10.1rc832.dist-info/METADATA,sha256=7yMOQ62RfKBicCBhKjtcwL8CN6tJUQvFOH6K5lBcDP0,2314
816
+ qontract_reconcile-0.10.1rc832.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
817
+ qontract_reconcile-0.10.1rc832.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
818
+ qontract_reconcile-0.10.1rc832.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
819
+ qontract_reconcile-0.10.1rc832.dist-info/RECORD,,
reconcile/cli.py CHANGED
@@ -2296,9 +2296,19 @@ def terraform_users(
2296
2296
  @binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
2297
2297
  @enable_deletion(default=False)
2298
2298
  @account_name
2299
+ @enable_extended_early_exit
2300
+ @extended_early_exit_cache_ttl_seconds
2301
+ @log_cached_log_output
2299
2302
  @click.pass_context
2300
2303
  def terraform_vpc_peerings(
2301
- ctx, print_to_file, enable_deletion, thread_pool_size, account_name
2304
+ ctx,
2305
+ print_to_file,
2306
+ enable_deletion,
2307
+ thread_pool_size,
2308
+ account_name,
2309
+ enable_extended_early_exit,
2310
+ extended_early_exit_cache_ttl_seconds,
2311
+ log_cached_log_output,
2302
2312
  ):
2303
2313
  import reconcile.terraform_vpc_peerings
2304
2314
 
@@ -2311,6 +2321,9 @@ def terraform_vpc_peerings(
2311
2321
  enable_deletion,
2312
2322
  thread_pool_size,
2313
2323
  account_name,
2324
+ enable_extended_early_exit=enable_extended_early_exit,
2325
+ extended_early_exit_cache_ttl_seconds=extended_early_exit_cache_ttl_seconds,
2326
+ log_cached_log_output=log_cached_log_output,
2314
2327
  )
2315
2328
 
2316
2329
 
@@ -1,10 +1,8 @@
1
1
  import json
2
2
  import logging
3
3
  import sys
4
- from typing import (
5
- Any,
6
- Optional,
7
- )
4
+ from collections.abc import Callable, Iterable, Mapping
5
+ from typing import Any, TypedDict
8
6
 
9
7
  import reconcile.utils.terraform_client as terraform
10
8
  import reconcile.utils.terrascript_aws_client as terrascript
@@ -15,11 +13,16 @@ from reconcile.utils import (
15
13
  )
16
14
  from reconcile.utils.aws_api import AWSApi
17
15
  from reconcile.utils.defer import defer
16
+ from reconcile.utils.extended_early_exit import (
17
+ ExtendedEarlyExitRunnerResult,
18
+ extended_early_exit_run,
19
+ )
18
20
  from reconcile.utils.ocm import (
19
21
  OCM,
20
22
  OCMMap,
21
23
  )
22
24
  from reconcile.utils.semver_helper import make_semver
25
+ from reconcile.utils.unleash.client import get_feature_toggle_state
23
26
 
24
27
  QONTRACT_INTEGRATION = "terraform_vpc_peerings"
25
28
  QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
@@ -29,7 +32,11 @@ class BadTerraformPeeringState(Exception):
29
32
  pass
30
33
 
31
34
 
32
- def find_matching_peering(from_cluster, to_cluster, desired_provider):
35
+ def find_matching_peering(
36
+ from_cluster: Mapping[str, Any],
37
+ to_cluster: Mapping[str, Any],
38
+ desired_provider: str,
39
+ ) -> Mapping[str, Any] | None:
33
40
  """
34
41
  Ensures there is a matching peering with the desired provider type
35
42
  going from the destination (to) cluster back to this one (from)
@@ -47,8 +54,8 @@ def find_matching_peering(from_cluster, to_cluster, desired_provider):
47
54
 
48
55
 
49
56
  def _get_default_management_account(
50
- cluster: dict[str, Any],
51
- ) -> Optional[dict[str, Any]]:
57
+ cluster: Mapping[str, Any],
58
+ ) -> Mapping[str, Any] | None:
52
59
  cluster_infra_accounts = cluster["awsInfrastructureManagementAccounts"]
53
60
  for infra_account_def in cluster_infra_accounts or []:
54
61
  if (
@@ -60,11 +67,11 @@ def _get_default_management_account(
60
67
 
61
68
 
62
69
  def _build_infrastructure_assume_role(
63
- account: dict[str, Any],
64
- cluster: dict[str, Any],
65
- ocm: Optional[OCM],
66
- provided_assume_role: Optional[str],
67
- ) -> Optional[dict[str, Any]]:
70
+ account: Mapping[str, Any],
71
+ cluster: Mapping[str, Any],
72
+ ocm: OCM | None,
73
+ provided_assume_role: str | None,
74
+ ) -> dict[str, Any] | None:
68
75
  if provided_assume_role:
69
76
  assume_role = provided_assume_role
70
77
  elif cluster["spec"].get("account"):
@@ -97,11 +104,11 @@ def _build_infrastructure_assume_role(
97
104
 
98
105
 
99
106
  def aws_assume_roles_for_cluster_vpc_peering(
100
- requester_connection: dict[str, Any],
101
- requester_cluster: dict[str, Any],
102
- accepter_connection: dict[str, Any],
103
- accepter_cluster: dict[str, Any],
104
- ocm: Optional[OCM],
107
+ requester_connection: Mapping[str, Any],
108
+ requester_cluster: Mapping[str, Any],
109
+ accepter_connection: Mapping[str, Any],
110
+ accepter_cluster: Mapping[str, Any],
111
+ ocm: OCM | None,
105
112
  ) -> tuple[str, dict[str, Any], dict[str, Any]]:
106
113
  # check if dedicated infra accounts have been declared on the
107
114
  # accepters peering connection or on the accepters cluster
@@ -159,8 +166,11 @@ def aws_assume_roles_for_cluster_vpc_peering(
159
166
 
160
167
 
161
168
  def build_desired_state_single_cluster(
162
- cluster_info, ocm: Optional[OCM], awsapi: AWSApi, account_filter: Optional[str]
163
- ):
169
+ cluster_info: Mapping[str, Any],
170
+ ocm: OCM | None,
171
+ awsapi: AWSApi,
172
+ account_filter: str | None,
173
+ ) -> list[dict[str, Any]]:
164
174
  cluster_name = cluster_info["name"]
165
175
 
166
176
  peerings = []
@@ -268,8 +278,11 @@ def build_desired_state_single_cluster(
268
278
 
269
279
 
270
280
  def build_desired_state_all_clusters(
271
- clusters, ocm_map: Optional[OCMMap], awsapi: AWSApi, account_filter: Optional[str]
272
- ):
281
+ clusters: Iterable[Mapping[str, Any]],
282
+ ocm_map: OCMMap | None,
283
+ awsapi: AWSApi,
284
+ account_filter: str | None,
285
+ ) -> tuple[list[dict[str, Any]], bool]:
273
286
  """
274
287
  Fetch state for VPC peerings between two OCM clusters
275
288
  """
@@ -292,8 +305,11 @@ def build_desired_state_all_clusters(
292
305
 
293
306
 
294
307
  def build_desired_state_vpc_mesh_single_cluster(
295
- cluster_info, ocm: Optional[OCM], awsapi: AWSApi, account_filter: Optional[str]
296
- ):
308
+ cluster_info: Mapping[str, Any],
309
+ ocm: OCM | None,
310
+ awsapi: AWSApi,
311
+ account_filter: str | None,
312
+ ) -> list[dict[str, Any]]:
297
313
  desired_state = []
298
314
 
299
315
  cluster = cluster_info["name"]
@@ -386,8 +402,11 @@ def build_desired_state_vpc_mesh_single_cluster(
386
402
 
387
403
 
388
404
  def build_desired_state_vpc_mesh(
389
- clusters, ocm_map: Optional[OCMMap], awsapi: AWSApi, account_filter: Optional[str]
390
- ):
405
+ clusters: Iterable[Mapping[str, Any]],
406
+ ocm_map: OCMMap | None,
407
+ awsapi: AWSApi,
408
+ account_filter: str | None,
409
+ ) -> tuple[list[dict[str, Any]], bool]:
391
410
  """
392
411
  Fetch state for VPC peerings between a cluster and all VPCs in an account
393
412
  """
@@ -410,8 +429,11 @@ def build_desired_state_vpc_mesh(
410
429
 
411
430
 
412
431
  def build_desired_state_vpc_single_cluster(
413
- cluster_info, ocm: Optional[OCM], awsapi: AWSApi, account_filter: Optional[str]
414
- ):
432
+ cluster_info: Mapping[str, Any],
433
+ ocm: OCM | None,
434
+ awsapi: AWSApi,
435
+ account_filter: str | None,
436
+ ) -> list[dict[str, Any]]:
415
437
  desired_state = []
416
438
 
417
439
  peering_info = cluster_info["peering"]
@@ -506,15 +528,18 @@ def build_desired_state_vpc_single_cluster(
506
528
  return desired_state
507
529
 
508
530
 
509
- def _private_hosted_control_plane(cluster_info: dict[str, Any]) -> bool:
531
+ def _private_hosted_control_plane(cluster_info: Mapping[str, Any]) -> bool:
510
532
  return bool(
511
533
  cluster_info["spec"].get("hypershift") and cluster_info["spec"].get("private")
512
534
  )
513
535
 
514
536
 
515
537
  def build_desired_state_vpc(
516
- clusters, ocm_map: Optional[OCMMap], awsapi: AWSApi, account_filter: Optional[str]
517
- ):
538
+ clusters: Iterable[Mapping[str, Any]],
539
+ ocm_map: OCMMap | None,
540
+ awsapi: AWSApi,
541
+ account_filter: str | None,
542
+ ) -> tuple[list[dict[str, Any]], bool]:
518
543
  """
519
544
  Fetch state for VPC peerings between a cluster and a VPC (account)
520
545
  """
@@ -538,13 +563,16 @@ def build_desired_state_vpc(
538
563
 
539
564
  @defer
540
565
  def run(
541
- dry_run,
542
- print_to_file=None,
543
- enable_deletion=False,
544
- thread_pool_size=10,
545
- account_name: Optional[str] = None,
546
- defer=None,
547
- ):
566
+ dry_run: bool,
567
+ print_to_file: bool | None = None,
568
+ enable_deletion: bool = False,
569
+ thread_pool_size: int = 10,
570
+ account_name: str | None = None,
571
+ enable_extended_early_exit: bool = False,
572
+ extended_early_exit_cache_ttl_seconds: int = 3600,
573
+ log_cached_log_output: bool = False,
574
+ defer: Callable | None = None,
575
+ ) -> None:
548
576
  settings = queries.get_secret_reader_settings()
549
577
  clusters = queries.get_clusters_with_peering_settings()
550
578
  with_ocm = any(c.get("ocm") for c in clusters)
@@ -638,10 +666,14 @@ def run(
638
666
  ts.populate_additional_providers(infra_account_name, items)
639
667
  ts.populate_vpc_peerings(desired_state)
640
668
  working_dirs = ts.dump(print_to_file=print_to_file)
669
+ terraform_configurations = ts.terraform_configurations()
641
670
 
642
671
  if print_to_file:
643
672
  sys.exit(0 if dry_run else int(any(errors)))
644
673
 
674
+ if any(errors):
675
+ sys.exit(1)
676
+
645
677
  tf = terraform.TerraformClient(
646
678
  QONTRACT_INTEGRATION,
647
679
  QONTRACT_INTEGRATION_VERSION,
@@ -651,34 +683,68 @@ def run(
651
683
  thread_pool_size,
652
684
  awsapi,
653
685
  )
686
+ if defer:
687
+ defer(tf.cleanup)
654
688
 
655
- if any(errors):
656
- sys.exit(1)
689
+ runner_params: RunnerParams = dict(
690
+ tf=tf,
691
+ dry_run=dry_run,
692
+ enable_deletion=enable_deletion,
693
+ )
694
+
695
+ if enable_extended_early_exit and get_feature_toggle_state(
696
+ "terraform-vpc-peerings-extended-early-exit",
697
+ default=True,
698
+ ):
699
+ cache_source = CacheSource(terraform_configurations=terraform_configurations)
700
+ extended_early_exit_run(
701
+ integration=QONTRACT_INTEGRATION,
702
+ integration_version=QONTRACT_INTEGRATION_VERSION,
703
+ dry_run=dry_run,
704
+ cache_source=cache_source,
705
+ shard=account_name if account_name else "",
706
+ ttl_seconds=extended_early_exit_cache_ttl_seconds,
707
+ logger=logging.getLogger(),
708
+ runner=runner,
709
+ runner_params=runner_params,
710
+ log_cached_log_output=log_cached_log_output,
711
+ )
712
+ else:
713
+ runner(**runner_params)
714
+
715
+
716
+ class CacheSource(TypedDict):
717
+ terraform_configurations: dict[str, str]
718
+
719
+
720
+ class RunnerParams(TypedDict):
721
+ tf: terraform.TerraformClient
722
+ dry_run: bool
723
+ enable_deletion: bool
657
724
 
658
- defer(tf.cleanup)
659
725
 
726
+ def runner(
727
+ dry_run: bool,
728
+ tf: terraform.TerraformClient,
729
+ enable_deletion: bool = False,
730
+ ) -> ExtendedEarlyExitRunnerResult:
660
731
  disabled_deletions_detected, err = tf.plan(enable_deletion)
661
- errors.append(err)
662
732
  if disabled_deletions_detected:
663
- logging.error("Deletions detected when they are disabled")
664
- sys.exit(1)
733
+ raise RuntimeError("Terraform plan has disabled deletions detected")
734
+ if err:
735
+ raise RuntimeError("Terraform plan has errors")
665
736
 
666
737
  if dry_run:
667
- sys.exit(int(any(errors)))
668
- if any(errors):
669
- sys.exit(1)
738
+ return ExtendedEarlyExitRunnerResult(payload={}, applied_count=0)
739
+
740
+ if err := tf.apply():
741
+ raise RuntimeError("Terraform apply has errors")
670
742
 
671
- errors.append(tf.apply())
672
- sys.exit(int(any(errors)))
743
+ return ExtendedEarlyExitRunnerResult(payload={}, applied_count=tf.apply_count)
673
744
 
674
745
 
675
- def early_exit_desired_state(
676
- print_to_file=None,
677
- enable_deletion=False,
678
- thread_pool_size=10,
679
- account_name: Optional[str] = None,
680
- ) -> dict[str, Any]:
681
- if account_name:
746
+ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
747
+ if kwargs.get("account_name"):
682
748
  raise ValueError(
683
749
  "terraform-vpc-peerings early-exit check does not support sharding yet"
684
750
  )
@@ -1,11 +1,9 @@
1
1
  import sys
2
- from typing import (
3
- Any,
4
- Optional,
5
- )
2
+ from typing import Any, Self
6
3
 
7
4
  import pytest
8
5
  import testslide
6
+ from pytest_mock import MockerFixture
9
7
 
10
8
  import reconcile.terraform_vpc_peerings as integ
11
9
  import reconcile.utils.terraform_client as terraform
@@ -23,8 +21,8 @@ class MockOCM:
23
21
  self.assumes: dict[str, str] = {}
24
22
 
25
23
  def register(
26
- self, cluster: str, tf_account_id: str, tf_user: str, assume_role: Optional[str]
27
- ) -> "MockOCM":
24
+ self, cluster: str, tf_account_id: str, tf_user: str, assume_role: str | None
25
+ ) -> Self:
28
26
  if not assume_role:
29
27
  assume_role = f"arn::::{cluster}"
30
28
  if not assume_role.startswith("arn:"):
@@ -33,11 +31,11 @@ class MockOCM:
33
31
  return self
34
32
 
35
33
  def get_aws_infrastructure_access_terraform_assume_role(
36
- self, cluster, tf_account_id, tf_user
37
- ):
34
+ self, cluster: str, tf_account_id: str, tf_user: str
35
+ ) -> str | None:
38
36
  return self.assumes.get(f"{cluster}/{tf_account_id}/{tf_user}")
39
37
 
40
- def auto_speced_mock(self, mocker) -> ocm.OCM:
38
+ def auto_speced_mock(self, mocker: MockerFixture) -> ocm.OCM:
41
39
  ocm_mock = mocker.patch("reconcile.utils.ocm.OCM", autospec=True).return_value
42
40
  ocm_mock.get_aws_infrastructure_access_terraform_assume_role.mock_add_spec(
43
41
  ocm.OCM.get_aws_infrastructure_access_terraform_assume_role
@@ -50,15 +48,15 @@ class MockOCM:
50
48
 
51
49
  class MockAWSAPI:
52
50
  def __init__(self) -> None:
53
- self.vpc_details: dict[str, tuple[str, list[str], Optional[str]]] = {}
51
+ self.vpc_details: dict[str, tuple[str, list[str], str | None]] = {}
54
52
 
55
53
  def register(
56
54
  self,
57
55
  vpc: str,
58
56
  vpc_id: str,
59
57
  route_tables: list[str],
60
- vpce_sg: Optional[str] = None,
61
- ) -> "MockAWSAPI":
58
+ vpce_sg: str | None = None,
59
+ ) -> Self:
62
60
  self.vpc_details[vpc] = (
63
61
  vpc_id,
64
62
  route_tables,
@@ -69,9 +67,9 @@ class MockAWSAPI:
69
67
  def get_cluster_vpc_details(
70
68
  self,
71
69
  account: dict[str, Any],
72
- route_tables=False,
73
- subnets=False,
74
- hcp_vpc_endpoint_sg=False,
70
+ route_tables: bool = False,
71
+ subnets: bool = False,
72
+ hcp_vpc_endpoint_sg: bool = False,
75
73
  ) -> tuple:
76
74
  if account["assume_cidr"] in self.vpc_details:
77
75
  vpc_id, rt, sg_id = self.vpc_details[account["assume_cidr"]]
@@ -80,7 +78,7 @@ class MockAWSAPI:
80
78
  return vpc_id, rt, None, sg_id if hcp_vpc_endpoint_sg else None
81
79
  return None, None, None, None
82
80
 
83
- def auto_speced_mock(self, mocker) -> aws_api.AWSApi:
81
+ def auto_speced_mock(self, mocker: MockerFixture) -> aws_api.AWSApi:
84
82
  aws_api_mock = mocker.patch(
85
83
  "reconcile.utils.aws_api.AWSApi", autospec=True
86
84
  ).return_value
@@ -93,14 +91,14 @@ class MockAWSAPI:
93
91
 
94
92
  def build_cluster(
95
93
  name: str,
96
- vpc: Optional[str] = None,
97
- read_only_accounts: Optional[list[str]] = None,
98
- network_mgmt_accounts: Optional[list[str]] = None,
99
- peering_connections: Optional[list[dict[str, Any]]] = None,
94
+ vpc: str | None = None,
95
+ read_only_accounts: list[str] | None = None,
96
+ network_mgmt_accounts: list[str] | None = None,
97
+ peering_connections: list[dict[str, Any]] | None = None,
100
98
  hcp: bool = False,
101
99
  private: bool = False,
102
- sg: Optional[str] = None,
103
- ):
100
+ sg: str | None = None,
101
+ ) -> dict[str, Any]:
104
102
  if not vpc:
105
103
  vpc = name
106
104
  cluster = {
@@ -150,7 +148,7 @@ def build_cluster(
150
148
 
151
149
  def build_requester_connection(
152
150
  name: str, peer_cluster: dict[str, Any], manage_routes: bool = True
153
- ):
151
+ ) -> dict[str, Any]:
154
152
  return {
155
153
  "name": name,
156
154
  "provider": "cluster-vpc-requester",
@@ -162,9 +160,9 @@ def build_requester_connection(
162
160
  def build_accepter_connection(
163
161
  name: str,
164
162
  cluster: str,
165
- aws_infra_acc: Optional[str] = None,
163
+ aws_infra_acc: str | None = None,
166
164
  manage_routes: bool = True,
167
- ):
165
+ ) -> dict[str, Any]:
168
166
  connection = {
169
167
  "name": name,
170
168
  "provider": "cluster-vpc-accepter",
@@ -182,7 +180,7 @@ def build_accepter_connection(
182
180
  return connection
183
181
 
184
182
 
185
- def test_c2c_vpc_peering_assume_role_accepter_connection_acc_overwrite(mocker):
183
+ def test_c2c_vpc_peering_assume_role_accepter_connection_acc_overwrite() -> None:
186
184
  """
187
185
  makes sure the peer connection account overwrite on the accepter is used
188
186
  when available. in this test, the overwrite is also allowed
@@ -210,7 +208,7 @@ def test_c2c_vpc_peering_assume_role_accepter_connection_acc_overwrite(mocker):
210
208
  requester_cluster,
211
209
  accepter_connection,
212
210
  accepter_cluster,
213
- ocm,
211
+ ocm, # type: ignore
214
212
  )
215
213
 
216
214
  assert infra_acc_name == "acc_overwrite"
@@ -238,7 +236,7 @@ def test_c2c_vpc_peering_assume_role_accepter_connection_acc_overwrite(mocker):
238
236
  assert acc_aws == expected_acc_aws
239
237
 
240
238
 
241
- def test_c2c_vpc_peering_assume_role_acc_overwrite_fail(mocker):
239
+ def test_c2c_vpc_peering_assume_role_acc_overwrite_fail() -> None:
242
240
  """
243
241
  try overwrite the account to be used on the accepter connection with an
244
242
  account not listed on the accepter cluster
@@ -263,12 +261,12 @@ def test_c2c_vpc_peering_assume_role_acc_overwrite_fail(mocker):
263
261
  requester_cluster,
264
262
  accepter_connection,
265
263
  accepter_cluster,
266
- ocm,
264
+ ocm, # type: ignore
267
265
  )
268
266
  assert str(ex.value).startswith("[account_not_allowed]")
269
267
 
270
268
 
271
- def test_c2c_vpc_peering_assume_role_accepter_cluster_account(mocker):
269
+ def test_c2c_vpc_peering_assume_role_accepter_cluster_account() -> None:
272
270
  """
273
271
  makes sure the clusters default infra account is used when no peer
274
272
  connection overwrite exists
@@ -292,7 +290,7 @@ def test_c2c_vpc_peering_assume_role_accepter_cluster_account(mocker):
292
290
  requester_cluster,
293
291
  accepter_connection,
294
292
  accepter_cluster,
295
- ocm,
293
+ ocm, # type: ignore
296
294
  )
297
295
 
298
296
  assert infra_acc_name == "default_acc"
@@ -320,7 +318,7 @@ def test_c2c_vpc_peering_assume_role_accepter_cluster_account(mocker):
320
318
  assert acc_aws == expected_acc_aws
321
319
 
322
320
 
323
- def test_c2c_vpc_peering_missing_ocm_assume_role(mocker):
321
+ def test_c2c_vpc_peering_missing_ocm_assume_role() -> None:
324
322
  """
325
323
  makes sure the clusters infra account is used when no peer connection
326
324
  overwrite exists
@@ -338,12 +336,12 @@ def test_c2c_vpc_peering_missing_ocm_assume_role(mocker):
338
336
  requester_cluster,
339
337
  accepter_connection,
340
338
  accepter_cluster,
341
- ocm,
339
+ ocm, # type: ignore
342
340
  )
343
341
  assert str(ex.value).startswith("[assume_role_not_found]")
344
342
 
345
343
 
346
- def test_c2c_vpc_peering_missing_account(mocker):
344
+ def test_c2c_vpc_peering_missing_account() -> None:
347
345
  """
348
346
  test the fallback logic, looking for network-mgmt groups accounts
349
347
  """
@@ -360,12 +358,12 @@ def test_c2c_vpc_peering_missing_account(mocker):
360
358
  requester_cluster,
361
359
  accepter_connection,
362
360
  accepter_cluster,
363
- ocm,
361
+ ocm, # type: ignore
364
362
  )
365
363
  assert str(ex.value).startswith("[no_account_available]")
366
364
 
367
365
 
368
- def test_empty_run(mocker):
366
+ def test_empty_run(mocker: MockerFixture) -> None:
369
367
  mocked_queries = mocker.patch("reconcile.terraform_vpc_peerings.queries")
370
368
  mocked_queries.get_secret_reader_settings.return_value = {}
371
369
  mocked_queries.get_clusters_with_peering_settings.return_value = []
@@ -390,7 +388,7 @@ def test_empty_run(mocker):
390
388
 
391
389
 
392
390
  class TestRun(testslide.TestCase):
393
- def setUp(self):
391
+ def setUp(self) -> None:
394
392
  super().setUp()
395
393
 
396
394
  self.awsapi = testslide.StrictMock(aws_api.AWSApi)
@@ -412,6 +410,7 @@ class TestRun(testslide.TestCase):
412
410
  self.mock_constructor(terraform, "TerraformClient").to_return_value(
413
411
  self.terraform
414
412
  )
413
+ self.terraform.apply_count = 1
415
414
  self.mock_constructor(terrascript, "TerrascriptClient").to_return_value(
416
415
  self.terrascript
417
416
  )
@@ -442,11 +441,14 @@ class TestRun(testslide.TestCase):
442
441
  self.mock_callable(self.terrascript, "dump").to_return_value({
443
442
  "some_account": "/some/dir"
444
443
  }).and_assert_called_once()
444
+ self.mock_callable(
445
+ self.terrascript, "terraform_configurations"
446
+ ).to_return_value({"foo": "bar"}).and_assert_called_once()
445
447
  # Sigh...
446
448
  self.exit = self.mock_callable(sys, "exit").to_raise(OSError("Exit called!"))
447
449
  self.addCleanup(testslide.mock_callable.unpatch_all_callable_mocks)
448
450
 
449
- def initialize_desired_states(self, error_code):
451
+ def initialize_desired_states(self, error_code: bool) -> None:
450
452
  self.build_desired_state_vpc.to_return_value((
451
453
  [
452
454
  {
@@ -499,7 +501,7 @@ class TestRun(testslide.TestCase):
499
501
  ],
500
502
  ).to_return_value(None).and_assert_called_once()
501
503
 
502
- def test_all_fine(self):
504
+ def test_all_fine(self) -> None:
503
505
  self.initialize_desired_states(False)
504
506
  self.mock_callable(self.terraform, "plan").to_return_value((
505
507
  False,
@@ -511,11 +513,9 @@ class TestRun(testslide.TestCase):
511
513
  self.mock_callable(self.terraform, "apply").to_return_value(
512
514
  None
513
515
  ).and_assert_called_once()
514
- self.exit.for_call(0).and_assert_called_once()
515
- with self.assertRaises(OSError):
516
- integ.run(False, print_to_file=None, enable_deletion=False)
516
+ integ.run(False, print_to_file=None, enable_deletion=False)
517
517
 
518
- def test_fail_state(self):
518
+ def test_fail_state(self) -> None:
519
519
  """Ensure we don't change the world if there are failures"""
520
520
  self.initialize_desired_states(True)
521
521
  self.mock_callable(self.terraform, "plan").to_return_value((
@@ -532,7 +532,7 @@ class TestRun(testslide.TestCase):
532
532
  with self.assertRaises(OSError):
533
533
  integ.run(False, print_to_file=None, enable_deletion=True)
534
534
 
535
- def test_dry_run(self):
535
+ def test_dry_run(self) -> None:
536
536
  self.initialize_desired_states(False)
537
537
 
538
538
  self.mock_callable(self.terraform, "plan").to_return_value((
@@ -545,11 +545,9 @@ class TestRun(testslide.TestCase):
545
545
  self.mock_callable(self.terraform, "apply").to_return_value(
546
546
  None
547
547
  ).and_assert_not_called()
548
- self.exit.for_call(0).and_assert_called_once()
549
- with self.assertRaises(OSError):
550
- integ.run(True, print_to_file=None, enable_deletion=False)
548
+ integ.run(True, print_to_file=None, enable_deletion=False)
551
549
 
552
- def test_dry_run_with_failures(self):
550
+ def test_dry_run_with_failures(self) -> None:
553
551
  """This is what we do during PR checks and new clusters!"""
554
552
  self.initialize_desired_states(True)
555
553
  self.mock_callable(self.terraform, "plan").to_return_value((
@@ -563,7 +561,7 @@ class TestRun(testslide.TestCase):
563
561
  with self.assertRaises(OSError):
564
562
  integ.run(True, print_to_file=None, enable_deletion=False)
565
563
 
566
- def test_dry_run_print_only_with_failures(self):
564
+ def test_dry_run_print_only_with_failures(self) -> None:
567
565
  """This is what we do during PR checks and new clusters!"""
568
566
  self.initialize_desired_states(True)
569
567
  self.mock_callable(self.terraform, "plan").to_return_value((
@@ -1,5 +1,6 @@
1
1
  import pytest
2
2
  import testslide
3
+ from pytest_mock import MockerFixture
3
4
 
4
5
  import reconcile.terraform_vpc_peerings as sut
5
6
  from reconcile.test.test_terraform_vpc_peerings import (
@@ -15,7 +16,7 @@ from reconcile.utils import (
15
16
  )
16
17
 
17
18
 
18
- def test_c2c_all_clusters(mocker):
19
+ def test_c2c_all_clusters() -> None:
19
20
  """
20
21
  happy path
21
22
  """
@@ -101,27 +102,36 @@ def test_c2c_all_clusters(mocker):
101
102
 
102
103
  # no account filter
103
104
  result, error = sut.build_desired_state_all_clusters(
104
- [requester_cluster], ocm_map, awsapi, account_filter=None
105
+ [requester_cluster],
106
+ ocm_map, # type: ignore
107
+ awsapi, # type: ignore
108
+ account_filter=None,
105
109
  )
106
110
  assert result == expected
107
111
  assert not error
108
112
 
109
113
  # correct account filter
110
114
  result, error = sut.build_desired_state_all_clusters(
111
- [requester_cluster], ocm_map, awsapi, account_filter="acc"
115
+ [requester_cluster],
116
+ ocm_map, # type: ignore
117
+ awsapi, # type: ignore
118
+ account_filter="acc",
112
119
  )
113
120
  assert result == expected
114
121
  assert not error
115
122
 
116
123
  # wrong account filter
117
124
  result, error = sut.build_desired_state_all_clusters(
118
- [requester_cluster], ocm_map, awsapi, account_filter="another_account"
125
+ [requester_cluster],
126
+ ocm_map, # type: ignore
127
+ awsapi, # type: ignore
128
+ account_filter="another_account",
119
129
  )
120
130
  assert not result
121
131
  assert not error
122
132
 
123
133
 
124
- def test_c2c_one_cluster_failing_recoverable(mocker):
134
+ def test_c2c_one_cluster_failing_recoverable(mocker: MockerFixture) -> None:
125
135
  """
126
136
  in this scenario, the handling of a single cluster fails with known
127
137
  exceptions
@@ -134,14 +144,17 @@ def test_c2c_one_cluster_failing_recoverable(mocker):
134
144
  )
135
145
 
136
146
  result, error = sut.build_desired_state_all_clusters(
137
- [{"name": "cluster"}], {}, {}, account_filter=None
147
+ [{"name": "cluster"}],
148
+ None,
149
+ None, # type: ignore
150
+ account_filter=None,
138
151
  )
139
152
 
140
153
  assert not result
141
154
  assert error
142
155
 
143
156
 
144
- def test_c2c_one_cluster_failing_weird(mocker):
157
+ def test_c2c_one_cluster_failing_weird(mocker: MockerFixture) -> None:
145
158
  """
146
159
  in this scenario, the handling of a single cluster fails with unexpected
147
160
  exceptions
@@ -154,7 +167,10 @@ def test_c2c_one_cluster_failing_weird(mocker):
154
167
 
155
168
  with pytest.raises(ValueError) as ex:
156
169
  sut.build_desired_state_all_clusters(
157
- [{"name": "cluster"}], {}, {}, account_filter=None
170
+ [{"name": "cluster"}],
171
+ None,
172
+ None, # type: ignore
173
+ account_filter=None,
158
174
  )
159
175
 
160
176
  assert str(ex.value) == SOMETHING_UNEXPECTED
@@ -173,14 +189,13 @@ def test_c2c_one_cluster_failing_weird(mocker):
173
189
  ],
174
190
  )
175
191
  def test_c2c_hcp(
176
- accepter_hcp,
177
- accepter_private,
178
- requester_hcp,
179
- requester_private,
180
- expected_accepter_security_group,
181
- expected_requester_security_group,
182
- mocker,
183
- ):
192
+ accepter_hcp: bool,
193
+ accepter_private: bool,
194
+ requester_hcp: bool,
195
+ requester_private: bool,
196
+ expected_accepter_security_group: str | None,
197
+ expected_requester_security_group: str | None,
198
+ ) -> None:
184
199
  accepter_cluster = build_cluster(
185
200
  name="accepter_cluster",
186
201
  vpc="accepter_vpc",
@@ -267,24 +282,33 @@ def test_c2c_hcp(
267
282
 
268
283
  # no account filtering
269
284
  result = sut.build_desired_state_single_cluster(
270
- requester_cluster, ocm, awsapi, account_filter=None
285
+ requester_cluster,
286
+ ocm, # type: ignore
287
+ awsapi, # type: ignore
288
+ account_filter=None,
271
289
  )
272
290
  assert result == expected
273
291
 
274
292
  # correct account filtering
275
293
  result = sut.build_desired_state_single_cluster(
276
- requester_cluster, ocm, awsapi, account_filter="acc"
294
+ requester_cluster,
295
+ ocm, # type: ignore
296
+ awsapi, # type: ignore
297
+ account_filter="acc",
277
298
  )
278
299
  assert result == expected
279
300
 
280
301
  # correct account filtering
281
302
  result = sut.build_desired_state_single_cluster(
282
- requester_cluster, ocm, awsapi, account_filter="another_account"
303
+ requester_cluster,
304
+ ocm, # type: ignore
305
+ awsapi, # type: ignore
306
+ account_filter="another_account",
283
307
  )
284
308
  assert not result
285
309
 
286
310
 
287
- def test_c2c_base(mocker):
311
+ def test_c2c_base() -> None:
288
312
  """
289
313
  happy path
290
314
  """
@@ -368,24 +392,33 @@ def test_c2c_base(mocker):
368
392
 
369
393
  # no account filtering
370
394
  result = sut.build_desired_state_single_cluster(
371
- requester_cluster, ocm, awsapi, account_filter=None
395
+ requester_cluster,
396
+ ocm, # type: ignore
397
+ awsapi, # type: ignore
398
+ account_filter=None,
372
399
  )
373
400
  assert result == expected
374
401
 
375
402
  # correct account filtering
376
403
  result = sut.build_desired_state_single_cluster(
377
- requester_cluster, ocm, awsapi, account_filter="acc"
404
+ requester_cluster,
405
+ ocm, # type: ignore
406
+ awsapi, # type: ignore
407
+ account_filter="acc",
378
408
  )
379
409
  assert result == expected
380
410
 
381
411
  # correct account filtering
382
412
  result = sut.build_desired_state_single_cluster(
383
- requester_cluster, ocm, awsapi, account_filter="another_account"
413
+ requester_cluster,
414
+ ocm, # type: ignore
415
+ awsapi, # type: ignore
416
+ account_filter="another_account",
384
417
  )
385
418
  assert not result
386
419
 
387
420
 
388
- def test_c2c_no_peerings(mocker):
421
+ def test_c2c_no_peerings() -> None:
389
422
  """
390
423
  in this scenario, the requester cluster has no peerings defines,
391
424
  which results in an empty desired state
@@ -398,14 +431,14 @@ def test_c2c_no_peerings(mocker):
398
431
  )
399
432
  result = sut.build_desired_state_single_cluster(
400
433
  requester_cluster,
401
- MockOCM(),
402
- MockAWSAPI(),
434
+ MockOCM(), # type: ignore
435
+ MockAWSAPI(), # type: ignore
403
436
  account_filter=None,
404
437
  )
405
438
  assert not result
406
439
 
407
440
 
408
- def test_c2c_no_matches(mocker):
441
+ def test_c2c_no_matches() -> None:
409
442
  """
410
443
  in this scenario, the accepter cluster has no cluster-vpc-accepter
411
444
  connection that references back to the requester cluster
@@ -430,14 +463,14 @@ def test_c2c_no_matches(mocker):
430
463
  with pytest.raises(sut.BadTerraformPeeringState) as ex:
431
464
  sut.build_desired_state_single_cluster(
432
465
  requester_cluster,
433
- MockOCM(),
434
- MockAWSAPI(),
466
+ MockOCM(), # type: ignore
467
+ MockAWSAPI(), # type: ignore
435
468
  account_filter=None,
436
469
  )
437
470
  assert str(ex.value).startswith("[no_matching_peering]")
438
471
 
439
472
 
440
- def test_c2c_no_vpc_in_aws(mocker):
473
+ def test_c2c_no_vpc_in_aws() -> None:
441
474
  """
442
475
  in this scenario, there are no VPCs found in AWS
443
476
  """
@@ -467,12 +500,15 @@ def test_c2c_no_vpc_in_aws(mocker):
467
500
  awsapi = MockAWSAPI()
468
501
 
469
502
  desired_state = sut.build_desired_state_single_cluster(
470
- requester_cluster, ocm, awsapi, account_filter=None
503
+ requester_cluster,
504
+ ocm, # type: ignore
505
+ awsapi, # type: ignore
506
+ account_filter=None,
471
507
  )
472
508
  assert desired_state == []
473
509
 
474
510
 
475
- def test_c2c_no_peer_account(mocker):
511
+ def test_c2c_no_peer_account() -> None:
476
512
  """
477
513
  in this scenario, the accepters connection and the accepters cluster
478
514
  have no aws infrastructura account available to set up the peering″
@@ -503,13 +539,16 @@ def test_c2c_no_peer_account(mocker):
503
539
 
504
540
  with pytest.raises(sut.BadTerraformPeeringState) as ex:
505
541
  sut.build_desired_state_single_cluster(
506
- requester_cluster, ocm, awsapi, account_filter=None
542
+ requester_cluster,
543
+ ocm, # type: ignore
544
+ awsapi, # type: ignore
545
+ account_filter=None,
507
546
  )
508
547
  assert str(ex.value).startswith("[no_account_available]")
509
548
 
510
549
 
511
550
  class TestBuildDesiredStateVpcMesh(testslide.TestCase):
512
- def setUp(self):
551
+ def setUp(self) -> None:
513
552
  super().setUp()
514
553
  self.clusters = [
515
554
  {
@@ -577,8 +616,8 @@ class TestBuildDesiredStateVpcMesh(testslide.TestCase):
577
616
  "assume_region": "mars-hellas-1",
578
617
  "assume_cidr": "172.25.0.0/12",
579
618
  }
580
- self.clusters[0]["peering"]["connections"][0]["cluster"] = self.peer_cluster
581
- self.clusters[0]["peering"]["connections"][0]["account"] = self.peer_account
619
+ self.clusters[0]["peering"]["connections"][0]["cluster"] = self.peer_cluster # type: ignore
620
+ self.clusters[0]["peering"]["connections"][0]["account"] = self.peer_account # type: ignore
582
621
  self.peer_vpc = {
583
622
  "cidr_block": "172.30.0.0/12",
584
623
  "vpc_id": "peervpcid",
@@ -589,11 +628,11 @@ class TestBuildDesiredStateVpcMesh(testslide.TestCase):
589
628
  )
590
629
  self.maxDiff = None
591
630
  self.ocm = testslide.StrictMock(ocm.OCM)
592
- self.ocm_map = {"clustername": self.ocm}
631
+ self.ocm_map: ocm.OCMMap = {"clustername": self.ocm} # type: ignore
593
632
  self.ocm.get_aws_infrastructure_access_terraform_assume_role = (
594
633
  lambda cluster, uid, tfuser: self.peer_account["assume_role"]
595
634
  )
596
- self.awsapi = testslide.StrictMock(aws_api.AWSApi)
635
+ self.awsapi: aws_api.AWSApi = testslide.StrictMock(aws_api.AWSApi)
597
636
  self.account_vpcs = [
598
637
  {
599
638
  "vpc_id": "vpc1",
@@ -610,7 +649,7 @@ class TestBuildDesiredStateVpcMesh(testslide.TestCase):
610
649
  ]
611
650
  self.addCleanup(testslide.mock_callable.unpatch_all_callable_mocks)
612
651
 
613
- def test_all_fine(self):
652
+ def test_all_fine(self) -> None:
614
653
  expected = [
615
654
  {
616
655
  "connection_provider": "account-vpc-mesh",
@@ -652,7 +691,10 @@ class TestBuildDesiredStateVpcMesh(testslide.TestCase):
652
691
  },
653
692
  ]
654
693
  self.vpc_mesh_single_cluster.for_call(
655
- self.clusters[0], self.ocm, self.awsapi, None
694
+ self.clusters[0],
695
+ self.ocm,
696
+ self.awsapi,
697
+ None,
656
698
  ).to_return_value(expected)
657
699
 
658
700
  rs = sut.build_desired_state_vpc_mesh(
@@ -663,25 +705,31 @@ class TestBuildDesiredStateVpcMesh(testslide.TestCase):
663
705
  )
664
706
  self.assertEqual(rs, (expected, False))
665
707
 
666
- def test_cluster_raises(self):
708
+ def test_cluster_raises(self) -> None:
667
709
  self.vpc_mesh_single_cluster.to_raise(
668
710
  sut.BadTerraformPeeringState("This is wrong")
669
711
  )
670
712
  rs = sut.build_desired_state_vpc_mesh(
671
- self.clusters, self.ocm_map, self.awsapi, None
713
+ self.clusters,
714
+ self.ocm_map,
715
+ self.awsapi,
716
+ None,
672
717
  )
673
718
  self.assertEqual(rs, ([], True))
674
719
 
675
- def test_cluster_raises_unexpected(self):
720
+ def test_cluster_raises_unexpected(self) -> None:
676
721
  self.vpc_mesh_single_cluster.to_raise(ValueError("Nope"))
677
722
  with self.assertRaises(ValueError):
678
723
  sut.build_desired_state_vpc_mesh(
679
- self.clusters, self.ocm_map, self.awsapi, None
724
+ self.clusters,
725
+ self.ocm_map,
726
+ self.awsapi,
727
+ None,
680
728
  )
681
729
 
682
730
 
683
731
  class TestBuildDesiredStateVpcMeshSingleCluster(testslide.TestCase):
684
- def setUp(self):
732
+ def setUp(self) -> None:
685
733
  super().setUp()
686
734
  self.cluster = {
687
735
  "name": "clustername",
@@ -728,7 +776,7 @@ class TestBuildDesiredStateVpcMeshSingleCluster(testslide.TestCase):
728
776
  ]
729
777
  },
730
778
  }
731
- self.awsapi = testslide.StrictMock(aws_api.AWSApi)
779
+ self.awsapi: aws_api.AWSApi = testslide.StrictMock(aws_api.AWSApi)
732
780
  self.mock_constructor(aws_api, "AWSApi").to_return_value(self.awsapi)
733
781
  self.find_matching_peering = self.mock_callable(sut, "find_matching_peering")
734
782
  self.aws_account = {
@@ -749,8 +797,8 @@ class TestBuildDesiredStateVpcMeshSingleCluster(testslide.TestCase):
749
797
  "assume_region": "mars-hellas-1",
750
798
  "assume_cidr": "172.25.0.0/12",
751
799
  }
752
- self.cluster["peering"]["connections"][0]["cluster"] = self.peer_cluster
753
- self.cluster["peering"]["connections"][0]["account"] = self.peer_account
800
+ self.cluster["peering"]["connections"][0]["cluster"] = self.peer_cluster # type: ignore
801
+ self.cluster["peering"]["connections"][0]["account"] = self.peer_account # type: ignore
754
802
  self.peer_vpc = {
755
803
  "cidr_block": "172.30.0.0/12",
756
804
  "vpc_id": "peervpcid",
@@ -758,8 +806,8 @@ class TestBuildDesiredStateVpcMeshSingleCluster(testslide.TestCase):
758
806
  }
759
807
  self.maxDiff = None
760
808
  self.addCleanup(testslide.mock_callable.unpatch_all_callable_mocks)
761
- self.ocm = testslide.StrictMock(template=ocm.OCM)
762
- self.ocm.get_aws_infrastructure_access_terraform_assume_role = (
809
+ self.ocm: ocm.OCM = testslide.StrictMock(template=ocm.OCM)
810
+ self.ocm.get_aws_infrastructure_access_terraform_assume_role = ( # type: ignore
763
811
  lambda cluster, uid, tfuser: self.peer_account["assume_role"]
764
812
  )
765
813
  self.account_vpcs = [
@@ -777,7 +825,7 @@ class TestBuildDesiredStateVpcMeshSingleCluster(testslide.TestCase):
777
825
  },
778
826
  ]
779
827
 
780
- def test_one_cluster(self):
828
+ def test_one_cluster(self) -> None:
781
829
  req_account = {
782
830
  **self.peer_account,
783
831
  "assume_region": "mars-plain-1",
@@ -842,11 +890,14 @@ class TestBuildDesiredStateVpcMeshSingleCluster(testslide.TestCase):
842
890
  ]
843
891
 
844
892
  rs = sut.build_desired_state_vpc_mesh_single_cluster(
845
- self.cluster, self.ocm, self.awsapi, None
893
+ self.cluster,
894
+ self.ocm,
895
+ self.awsapi,
896
+ None,
846
897
  )
847
898
  self.assertEqual(rs, expected)
848
899
 
849
- def test_one_cluster_private_hcp(self):
900
+ def test_one_cluster_private_hcp(self) -> None:
850
901
  self.cluster["spec"] = {
851
902
  "region": "mars-plain-1",
852
903
  "hypershift": True,
@@ -920,14 +971,14 @@ class TestBuildDesiredStateVpcMeshSingleCluster(testslide.TestCase):
920
971
  )
921
972
  self.assertEqual(rs, expected)
922
973
 
923
- def test_no_peering_connections(self):
924
- self.cluster["peering"]["connections"] = []
974
+ def test_no_peering_connections(self) -> None:
975
+ self.cluster["peering"]["connections"] = [] # type: ignore
925
976
  rs = sut.build_desired_state_vpc_mesh_single_cluster(
926
977
  self.cluster, self.ocm, self.awsapi, None
927
978
  )
928
979
  self.assertEqual(rs, [])
929
980
 
930
- def test_no_peer_vpc_id(self):
981
+ def test_no_peer_vpc_id(self) -> None:
931
982
  self.mock_callable(self.awsapi, "get_cluster_vpc_details").to_return_value((
932
983
  None,
933
984
  [None],
@@ -942,7 +993,7 @@ class TestBuildDesiredStateVpcMeshSingleCluster(testslide.TestCase):
942
993
 
943
994
 
944
995
  class TestBuildDesiredStateVpc(testslide.TestCase):
945
- def setUp(self):
996
+ def setUp(self) -> None:
946
997
  super().setUp()
947
998
  self.peer = {
948
999
  "vpc": "172.17.0.0/12",
@@ -1007,13 +1058,13 @@ class TestBuildDesiredStateVpc(testslide.TestCase):
1007
1058
  ]
1008
1059
  },
1009
1060
  }
1010
- self.clusters[0]["peering"]["connections"][0]["cluster"] = self.peer_cluster
1061
+ self.clusters[0]["peering"]["connections"][0]["cluster"] = self.peer_cluster # type: ignore
1011
1062
  self.build_single_cluster = self.mock_callable(
1012
1063
  sut, "build_desired_state_single_cluster"
1013
1064
  )
1014
1065
  self.ocm = testslide.StrictMock(template=ocm.OCM)
1015
- self.ocm_map = {"clustername": self.ocm}
1016
- self.awsapi = testslide.StrictMock(aws_api.AWSApi)
1066
+ self.ocm_map: ocm.OCMMap = {"clustername": self.ocm} # type: ignore
1067
+ self.awsapi: aws_api.AWSApi = testslide.StrictMock(aws_api.AWSApi)
1017
1068
 
1018
1069
  self.build_single_cluster = self.mock_callable(
1019
1070
  sut, "build_desired_state_vpc_single_cluster"
@@ -1021,7 +1072,7 @@ class TestBuildDesiredStateVpc(testslide.TestCase):
1021
1072
  self.addCleanup(testslide.mock_callable.unpatch_all_callable_mocks)
1022
1073
  self.maxDiff = None
1023
1074
 
1024
- def test_all_fine(self):
1075
+ def test_all_fine(self) -> None:
1025
1076
  expected = [
1026
1077
  {
1027
1078
  "accepter": {
@@ -1067,7 +1118,7 @@ class TestBuildDesiredStateVpc(testslide.TestCase):
1067
1118
  )
1068
1119
  self.assertEqual(rs, (expected, False))
1069
1120
 
1070
- def test_cluster_fails(self):
1121
+ def test_cluster_fails(self) -> None:
1071
1122
  self.build_single_cluster.to_raise(
1072
1123
  sut.BadTerraformPeeringState("I have failed")
1073
1124
  )
@@ -1079,10 +1130,10 @@ class TestBuildDesiredStateVpc(testslide.TestCase):
1079
1130
  ([], True),
1080
1131
  )
1081
1132
 
1082
- def test_error_persists(self):
1133
+ def test_error_persists(self) -> None:
1083
1134
  self.clusters.append(self.clusters[0].copy())
1084
1135
  self.clusters[1]["name"] = "afailingcluster"
1085
- self.ocm_map["afailingcluster"] = self.ocm
1136
+ self.ocm_map["afailingcluster"] = self.ocm # type: ignore
1086
1137
  self.build_single_cluster.for_call(
1087
1138
  self.clusters[0], self.ocm, self.awsapi, None
1088
1139
  ).to_return_value([{"a dict": "a value"}]).and_assert_called_once()
@@ -1100,10 +1151,10 @@ class TestBuildDesiredStateVpc(testslide.TestCase):
1100
1151
  ([{"a dict": "a value"}], True),
1101
1152
  )
1102
1153
 
1103
- def test_other_exceptions_raise(self):
1154
+ def test_other_exceptions_raise(self) -> None:
1104
1155
  self.clusters.append(self.clusters[0].copy())
1105
1156
  self.clusters[1]["name"] = "afailingcluster"
1106
- self.ocm_map["afailingcluster"] = self.ocm
1157
+ self.ocm_map["afailingcluster"] = self.ocm # type: ignore
1107
1158
  self.build_single_cluster.for_call(
1108
1159
  self.clusters[0], self.ocm, self.awsapi, None
1109
1160
  ).to_raise(ValueError("I am not planned!")).and_assert_called_once()
@@ -1114,7 +1165,7 @@ class TestBuildDesiredStateVpc(testslide.TestCase):
1114
1165
 
1115
1166
 
1116
1167
  class TestBuildDesiredStateVpcSingleCluster(testslide.TestCase):
1117
- def setUp(self):
1168
+ def setUp(self) -> None:
1118
1169
  super().setUp()
1119
1170
  self.peer = {
1120
1171
  "vpc": "172.17.0.0/12",
@@ -1177,20 +1228,20 @@ class TestBuildDesiredStateVpcSingleCluster(testslide.TestCase):
1177
1228
  ]
1178
1229
  },
1179
1230
  }
1180
- self.cluster["peering"]["connections"][0]["cluster"] = self.peer_cluster
1231
+ self.cluster["peering"]["connections"][0]["cluster"] = self.peer_cluster # type: ignore
1181
1232
  self.build_single_cluster = self.mock_callable(
1182
1233
  sut, "build_desired_state_single_cluster"
1183
1234
  )
1184
- self.ocm = testslide.StrictMock(template=ocm.OCM)
1185
- self.awsapi = testslide.StrictMock(aws_api.AWSApi)
1235
+ self.ocm: ocm.OCM = testslide.StrictMock(template=ocm.OCM)
1236
+ self.awsapi: aws_api.AWSApi = testslide.StrictMock(aws_api.AWSApi)
1186
1237
  self.mock_constructor(aws_api, "AWSApi").to_return_value(self.awsapi)
1187
- self.ocm.get_aws_infrastructure_access_terraform_assume_role = (
1238
+ self.ocm.get_aws_infrastructure_access_terraform_assume_role = ( # type: ignore
1188
1239
  lambda cluster, uid, tfuser: self.aws_account["assume_role"]
1189
1240
  )
1190
1241
  self.addCleanup(testslide.mock_callable.unpatch_all_callable_mocks)
1191
1242
  self.maxDiff = None
1192
1243
 
1193
- def test_all_fine(self):
1244
+ def test_all_fine(self) -> None:
1194
1245
  expected = [
1195
1246
  {
1196
1247
  "accepter": {
@@ -1252,7 +1303,7 @@ class TestBuildDesiredStateVpcSingleCluster(testslide.TestCase):
1252
1303
  )
1253
1304
  self.assertEqual(rs, expected)
1254
1305
 
1255
- def test_private_hcp(self):
1306
+ def test_private_hcp(self) -> None:
1256
1307
  self.cluster["spec"] = {
1257
1308
  "region": "mars-plain-1",
1258
1309
  "hypershift": True,
@@ -1319,16 +1370,19 @@ class TestBuildDesiredStateVpcSingleCluster(testslide.TestCase):
1319
1370
  )
1320
1371
  self.assertEqual(rs, expected)
1321
1372
 
1322
- def test_different_provider(self):
1323
- self.cluster["peering"]["connections"][0]["provider"] = "something-else"
1373
+ def test_different_provider(self) -> None:
1374
+ self.cluster["peering"]["connections"][0]["provider"] = "something-else" # type: ignore
1324
1375
  self.assertEqual(
1325
1376
  sut.build_desired_state_vpc_single_cluster(
1326
- self.cluster, self.ocm, self.awsapi, None
1377
+ self.cluster,
1378
+ self.ocm,
1379
+ self.awsapi,
1380
+ None,
1327
1381
  ),
1328
1382
  [],
1329
1383
  )
1330
1384
 
1331
- def test_no_vpc_id(self):
1385
+ def test_no_vpc_id(self) -> None:
1332
1386
  self.mock_callable(self.awsapi, "get_cluster_vpc_details").to_return_value((
1333
1387
  None,
1334
1388
  None,
@@ -1345,7 +1399,7 @@ class TestBuildDesiredStateVpcSingleCluster(testslide.TestCase):
1345
1399
  )
1346
1400
  assert desired_state == []
1347
1401
 
1348
- def test_aws_exception(self):
1402
+ def test_aws_exception(self) -> None:
1349
1403
  exc_txt = "AWS Problem!"
1350
1404
  self.mock_callable(self.awsapi, "get_cluster_vpc_details").to_raise(
1351
1405
  Exception(exc_txt)
@@ -1357,5 +1411,8 @@ class TestBuildDesiredStateVpcSingleCluster(testslide.TestCase):
1357
1411
 
1358
1412
  with pytest.raises(Exception, match=exc_txt):
1359
1413
  sut.build_desired_state_vpc_single_cluster(
1360
- self.cluster, self.ocm, self.awsapi, None
1414
+ self.cluster,
1415
+ self.ocm,
1416
+ self.awsapi,
1417
+ None,
1361
1418
  )