qontract-reconcile 0.10.2.dev279__py3-none-any.whl → 0.10.2.dev281__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.
Files changed (76) hide show
  1. {qontract_reconcile-0.10.2.dev279.dist-info → qontract_reconcile-0.10.2.dev281.dist-info}/METADATA +1 -1
  2. {qontract_reconcile-0.10.2.dev279.dist-info → qontract_reconcile-0.10.2.dev281.dist-info}/RECORD +76 -76
  3. reconcile/acs_policies.py +7 -7
  4. reconcile/aus/base.py +1 -1
  5. reconcile/aus/models.py +4 -5
  6. reconcile/aus/version_gate_approver.py +4 -1
  7. reconcile/aws_account_manager/merge_request_manager.py +5 -3
  8. reconcile/aws_ami_cleanup/integration.py +5 -8
  9. reconcile/aws_cloudwatch_log_retention/integration.py +6 -6
  10. reconcile/database_access_manager.py +1 -1
  11. reconcile/deadmanssnitch.py +1 -1
  12. reconcile/dynatrace_token_provider/ocm.py +10 -11
  13. reconcile/external_resources/aws.py +1 -1
  14. reconcile/external_resources/model.py +11 -11
  15. reconcile/external_resources/state.py +4 -4
  16. reconcile/fleet_labeler/dependencies.py +7 -3
  17. reconcile/fleet_labeler/ocm.py +6 -4
  18. reconcile/gitlab_housekeeping.py +2 -2
  19. reconcile/gitlab_permissions.py +1 -1
  20. reconcile/jenkins_webhooks.py +8 -4
  21. reconcile/jenkins_worker_fleets.py +2 -2
  22. reconcile/ocm_internal_notifications/integration.py +6 -4
  23. reconcile/ocm_labels/integration.py +7 -7
  24. reconcile/ocm_upgrade_scheduler_org_updater.py +2 -4
  25. reconcile/openshift_cluster_bots.py +1 -1
  26. reconcile/resource_scraper.py +1 -1
  27. reconcile/run_integration.py +1 -1
  28. reconcile/saas_auto_promotions_manager/integration.py +7 -3
  29. reconcile/saas_auto_promotions_manager/s3_exporter.py +6 -3
  30. reconcile/saas_file_validator.py +1 -2
  31. reconcile/skupper_network/models.py +4 -2
  32. reconcile/statuspage/page.py +1 -1
  33. reconcile/terraform_cloudflare_resources.py +1 -1
  34. reconcile/terraform_resources.py +1 -1
  35. reconcile/terraform_tgw_attachments.py +3 -3
  36. reconcile/terraform_users.py +1 -1
  37. reconcile/utils/aws_api.py +12 -30
  38. reconcile/utils/aws_api_typed/account.py +4 -4
  39. reconcile/utils/aws_api_typed/api.py +4 -2
  40. reconcile/utils/aws_api_typed/dynamodb.py +2 -2
  41. reconcile/utils/aws_api_typed/iam.py +2 -2
  42. reconcile/utils/aws_api_typed/organization.py +10 -7
  43. reconcile/utils/aws_api_typed/s3.py +2 -3
  44. reconcile/utils/aws_api_typed/service_quotas.py +4 -1
  45. reconcile/utils/aws_api_typed/sts.py +2 -2
  46. reconcile/utils/aws_api_typed/support.py +2 -2
  47. reconcile/utils/dynatrace/client.py +4 -1
  48. reconcile/utils/expiration.py +1 -1
  49. reconcile/utils/external_resource_spec.py +4 -2
  50. reconcile/utils/gitlab_api.py +4 -4
  51. reconcile/utils/glitchtip/models.py +4 -2
  52. reconcile/utils/jira_client.py +4 -4
  53. reconcile/utils/jobcontroller/models.py +8 -8
  54. reconcile/utils/mr/base.py +1 -1
  55. reconcile/utils/oc_connection_parameters.py +4 -1
  56. reconcile/utils/ocm/base.py +4 -1
  57. reconcile/utils/ocm/ocm.py +6 -5
  58. reconcile/utils/ocm/products.py +7 -4
  59. reconcile/utils/saasherder/interfaces.py +5 -2
  60. reconcile/utils/slack_api.py +4 -5
  61. reconcile/utils/state.py +9 -9
  62. reconcile/utils/terraform_client.py +1 -1
  63. reconcile/utils/terrascript_aws_client.py +8 -6
  64. reconcile/utils/vaultsecretref.py +1 -1
  65. reconcile/utils/vcs.py +14 -10
  66. reconcile/vault_replication.py +1 -1
  67. reconcile/vpc_peerings_validator.py +2 -4
  68. tools/app_interface_reporter.py +1 -2
  69. tools/cli_commands/erv2.py +7 -4
  70. tools/cli_commands/gpg_encrypt.py +4 -1
  71. tools/qontract_cli.py +13 -8
  72. tools/saas_metrics_exporter/commit_distance/channel.py +6 -3
  73. tools/saas_metrics_exporter/main.py +4 -1
  74. tools/saas_promotion_state/saas_promotion_state.py +4 -1
  75. {qontract_reconcile-0.10.2.dev279.dist-info → qontract_reconcile-0.10.2.dev281.dist-info}/WHEEL +0 -0
  76. {qontract_reconcile-0.10.2.dev279.dist-info → qontract_reconcile-0.10.2.dev281.dist-info}/entry_points.txt +0 -0
@@ -3,10 +3,9 @@ from __future__ import annotations
3
3
  import textwrap
4
4
  from abc import ABC, abstractmethod
5
5
  from functools import cached_property
6
- from typing import Any, TypeVar
6
+ from typing import TYPE_CHECKING, Any, TypeVar
7
7
 
8
8
  from boto3 import Session
9
- from botocore.client import BaseClient
10
9
  from pydantic import BaseModel
11
10
 
12
11
  import reconcile.utils.aws_api_typed.account
@@ -26,6 +25,9 @@ from reconcile.utils.aws_api_typed.service_quotas import AWSApiServiceQuotas
26
25
  from reconcile.utils.aws_api_typed.sts import AWSApiSts
27
26
  from reconcile.utils.aws_api_typed.support import AWSApiSupport
28
27
 
28
+ if TYPE_CHECKING:
29
+ from botocore.client import BaseClient
30
+
29
31
  SubApi = TypeVar(
30
32
  "SubApi",
31
33
  AWSApiAccount,
@@ -1,9 +1,9 @@
1
+ from __future__ import annotations
2
+
1
3
  from typing import TYPE_CHECKING
2
4
 
3
5
  if TYPE_CHECKING:
4
6
  from mypy_boto3_dynamodb import DynamoDBClient
5
- else:
6
- DynamoDBClient = object
7
7
 
8
8
 
9
9
  class AWSApiDynamoDB:
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from typing import TYPE_CHECKING
2
4
 
3
5
  import botocore
@@ -5,8 +7,6 @@ from pydantic import BaseModel, Field
5
7
 
6
8
  if TYPE_CHECKING:
7
9
  from mypy_boto3_iam import IAMClient
8
- else:
9
- IAMClient = object
10
10
 
11
11
 
12
12
  class AWSAccessKey(BaseModel):
@@ -1,26 +1,29 @@
1
+ from __future__ import annotations
2
+
1
3
  import functools
2
- from collections.abc import Iterable, Mapping
3
- from typing import TYPE_CHECKING, Optional
4
+ from typing import TYPE_CHECKING
4
5
 
5
6
  from pydantic import BaseModel, Field
6
7
 
7
8
  if TYPE_CHECKING:
9
+ from collections.abc import Iterable, Mapping
10
+
8
11
  from mypy_boto3_organizations import OrganizationsClient
9
12
  from mypy_boto3_organizations.literals import CreateAccountFailureReasonType
10
13
  else:
11
- OrganizationsClient = object
12
- CreateAccountFailureReasonType = object
14
+ # pydantic needs these types to be defined during runtime
15
+ CreateAccountFailureReasonType = str
13
16
 
14
17
 
15
18
  class AwsOrganizationOU(BaseModel):
16
19
  id: str = Field(..., alias="Id")
17
20
  arn: str = Field(..., alias="Arn")
18
21
  name: str = Field(..., alias="Name")
19
- children: list["AwsOrganizationOU"] = []
22
+ children: list[AwsOrganizationOU] = []
20
23
 
21
24
  def locate(
22
25
  self, path: list[str], ignore_case: bool = True
23
- ) -> Optional["AwsOrganizationOU"]:
26
+ ) -> AwsOrganizationOU | None:
24
27
  name, *sub = path
25
28
  match = self.name.lower() == name.lower() if ignore_case else self.name == name
26
29
  if not match:
@@ -36,7 +39,7 @@ class AwsOrganizationOU(BaseModel):
36
39
  None,
37
40
  )
38
41
 
39
- def find(self, path: str, ignore_case: bool = True) -> "AwsOrganizationOU":
42
+ def find(self, path: str, ignore_case: bool = True) -> AwsOrganizationOU:
40
43
  node = self.locate(path.strip("/").split("/"), ignore_case=ignore_case)
41
44
  if not node:
42
45
  raise KeyError(f"OU not found: {path}")
@@ -1,10 +1,9 @@
1
+ from __future__ import annotations
2
+
1
3
  from typing import TYPE_CHECKING
2
4
 
3
5
  if TYPE_CHECKING:
4
6
  from mypy_boto3_s3 import S3Client
5
- from mypy_boto3_s3.literals import BucketLocationConstraintType
6
- else:
7
- S3Client = BucketLocationConstraintType = object
8
7
 
9
8
 
10
9
  class AWSApiS3:
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from typing import TYPE_CHECKING
2
4
 
3
5
  from pydantic import BaseModel, Field
@@ -6,7 +8,8 @@ if TYPE_CHECKING:
6
8
  from mypy_boto3_service_quotas import ServiceQuotasClient
7
9
  from mypy_boto3_service_quotas.literals import RequestStatusType
8
10
  else:
9
- ServiceQuotasClient = RequestStatusType = object
11
+ # pydantic needs these types to be defined during runtime
12
+ RequestStatusType = str
10
13
 
11
14
 
12
15
  class AWSRequestedServiceQuotaChange(BaseModel):
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from datetime import datetime
2
4
  from typing import TYPE_CHECKING
3
5
 
@@ -5,8 +7,6 @@ from pydantic import BaseModel, Field
5
7
 
6
8
  if TYPE_CHECKING:
7
9
  from mypy_boto3_sts import STSClient
8
- else:
9
- STSClient = object
10
10
 
11
11
 
12
12
  class AWSCredentials(BaseModel):
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from enum import Enum
2
4
  from typing import TYPE_CHECKING, Literal
3
5
 
@@ -5,8 +7,6 @@ from pydantic import BaseModel, Field
5
7
 
6
8
  if TYPE_CHECKING:
7
9
  from mypy_boto3_support import SupportClient
8
- else:
9
- SupportClient = object
10
10
 
11
11
 
12
12
  class AWSCase(BaseModel):
@@ -1,11 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Iterable
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  from dynatrace import Dynatrace
6
6
  from dynatrace.environment_v2.tokens_api import ApiTokenUpdate
7
7
  from pydantic import BaseModel
8
8
 
9
+ if TYPE_CHECKING:
10
+ from collections.abc import Iterable
11
+
9
12
 
10
13
  class DynatraceTokenCreationError(Exception):
11
14
  pass
@@ -41,4 +41,4 @@ def filter(roles: DictsOrRoles | None) -> DictsOrRoles:
41
41
  f"{key} field is not formatted as YYYY-MM-DD, currently set as {expiration_date}"
42
42
  ) from None
43
43
 
44
- return cast(DictsOrRoles, filtered)
44
+ return cast("DictsOrRoles", filtered)
@@ -60,7 +60,7 @@ class GenericSecretOutputFormatConfig(OutputFormatProcessor):
60
60
  rendered_data = process_jinja2_template(self.data, dict(vars))
61
61
  parsed_data = yaml.safe_load(rendered_data)
62
62
  self.validate_k8s_secret_data(parsed_data)
63
- return cast(dict[str, str], parsed_data)
63
+ return cast("dict[str, str]", parsed_data)
64
64
  return dict(vars)
65
65
 
66
66
 
@@ -176,7 +176,9 @@ class ExternalResourceSpec:
176
176
 
177
177
  def _output_format(self) -> OutputFormat:
178
178
  if self.resource.get("output_format") is not None:
179
- return OutputFormat(**cast(dict[str, Any], self.resource["output_format"]))
179
+ return OutputFormat(
180
+ **cast("dict[str, Any]", self.resource["output_format"])
181
+ )
180
182
  return OutputFormat(provider="generic-secret")
181
183
 
182
184
 
@@ -425,7 +425,7 @@ class GitLabApi:
425
425
  merge_request: ProjectMergeRequest,
426
426
  ) -> list[str]:
427
427
  result = merge_request.changes()
428
- changes = cast(dict, result)["changes"]
428
+ changes = cast("dict", result)["changes"]
429
429
  changed_paths = set()
430
430
  for change in changes:
431
431
  old_path = change["old_path"]
@@ -562,9 +562,9 @@ class GitLabApi:
562
562
  manager: ProjectMergeRequestManager | ProjectIssueManager
563
563
  match item:
564
564
  case ProjectMergeRequest():
565
- manager = cast(ProjectMergeRequestManager, item.manager)
565
+ manager = cast("ProjectMergeRequestManager", item.manager)
566
566
  case ProjectIssue():
567
- manager = cast(ProjectIssueManager, item.manager)
567
+ manager = cast("ProjectIssueManager", item.manager)
568
568
  case _:
569
569
  raise ValueError("item must be a ProjectMergeRequest or ProjectIssue")
570
570
  item_id = item.get_id()
@@ -668,7 +668,7 @@ class GitLabApi:
668
668
  :return: list of tree objects
669
669
  """
670
670
  return cast(
671
- list[dict],
671
+ "list[dict]",
672
672
  self.project.repository_tree(
673
673
  ref=ref,
674
674
  recursive=recursive,
@@ -1,10 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import re
4
- from collections.abc import MutableMapping
5
4
  from datetime import datetime
6
5
  from enum import Enum
7
- from typing import Any
6
+ from typing import TYPE_CHECKING, Any
8
7
 
9
8
  from pydantic import (
10
9
  BaseModel,
@@ -13,6 +12,9 @@ from pydantic import (
13
12
  validator,
14
13
  )
15
14
 
15
+ if TYPE_CHECKING:
16
+ from collections.abc import MutableMapping
17
+
16
18
 
17
19
  def slugify(value: str) -> str:
18
20
  """Convert value into a slug.
@@ -2,11 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  import functools
4
4
  import logging
5
- from collections.abc import (
6
- Iterable,
7
- Mapping,
8
- )
9
5
  from typing import (
6
+ TYPE_CHECKING,
10
7
  Any,
11
8
  Protocol,
12
9
  )
@@ -22,6 +19,9 @@ from pydantic import BaseModel
22
19
 
23
20
  from reconcile.utils.secret_reader import SecretReader
24
21
 
22
+ if TYPE_CHECKING:
23
+ from collections.abc import Iterable, Mapping
24
+
25
25
 
26
26
  class JiraWatcherSettings(Protocol):
27
27
  read_timeout: int
@@ -20,17 +20,17 @@ from kubernetes.client import (
20
20
 
21
21
 
22
22
  class JobStatus(StrEnum):
23
- SUCCESS: str = "SUCCESS"
24
- ERROR: str = "ERROR"
25
- IN_PROGRESS: str = "IN_PROGRESS"
26
- NOT_EXISTS: str = "NOT_EXISTS"
23
+ SUCCESS = "SUCCESS"
24
+ ERROR = "ERROR"
25
+ IN_PROGRESS = "IN_PROGRESS"
26
+ NOT_EXISTS = "NOT_EXISTS"
27
27
 
28
28
 
29
29
  class JobConcurrencyPolicy(IntFlag):
30
- NO_REPLACE: int = 1
31
- REPLACE_FAILED: int = 2
32
- REPLACE_IN_PROGRESS: int = 4
33
- REPLACE_FINISHED: int = 8
30
+ NO_REPLACE = 1
31
+ REPLACE_FAILED = 2
32
+ REPLACE_IN_PROGRESS = 4
33
+ REPLACE_FINISHED = 8
34
34
 
35
35
 
36
36
  class JobValidationError(Exception):
@@ -225,7 +225,7 @@ class MergeRequestBase(ABC):
225
225
 
226
226
  def diffs(self, gitlab_cli: GitLabApi) -> Any:
227
227
  return cast(
228
- dict,
228
+ "dict",
229
229
  gitlab_cli.project.repository_compare(
230
230
  from_=gitlab_cli.main_branch, to=self.branch
231
231
  ),
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from collections.abc import Iterable
5
4
  from dataclasses import dataclass
6
5
  from typing import (
6
+ TYPE_CHECKING,
7
7
  Protocol,
8
8
  runtime_checkable,
9
9
  )
@@ -16,6 +16,9 @@ from reconcile.utils.secret_reader import (
16
16
  SecretReaderBase,
17
17
  )
18
18
 
19
+ if TYPE_CHECKING:
20
+ from collections.abc import Iterable
21
+
19
22
 
20
23
  class OCConnectionError(Exception):
21
24
  pass
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Iterable
4
3
  from datetime import datetime
5
4
  from enum import Enum, StrEnum
6
5
  from typing import (
6
+ TYPE_CHECKING,
7
7
  TypeVar,
8
8
  )
9
9
 
@@ -15,6 +15,9 @@ from pydantic import (
15
15
  from reconcile.utils.aws_helper import get_account_uid_from_arn, get_role_name_from_arn
16
16
  from reconcile.utils.semver_helper import parse_semver
17
17
 
18
+ if TYPE_CHECKING:
19
+ from collections.abc import Iterable
20
+
18
21
  LabelSetTypeVar = TypeVar("LabelSetTypeVar", bound=BaseModel)
19
22
  ACTIVE_SUBSCRIPTION_STATES = {"Active", "Reserved"}
20
23
  CAPABILITY_MANAGE_CLUSTER_ADMIN = "capability.cluster.manage_cluster_admin"
@@ -1,16 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import functools
4
- from collections.abc import Mapping
5
- from typing import Any
4
+ from typing import TYPE_CHECKING, Any
6
5
 
7
6
  from sretoolbox.utils import retry
8
7
 
9
8
  import reconcile.utils.aws_helper as awsh
10
9
  from reconcile.gql_definitions.fragments.vault_secret import VaultSecret
11
- from reconcile.ocm.types import (
12
- OCMSpec,
13
- )
14
10
  from reconcile.utils.ocm.clusters import get_node_pools
15
11
  from reconcile.utils.ocm.products import (
16
12
  OCMProduct,
@@ -24,6 +20,11 @@ from reconcile.utils.ocm_base_client import (
24
20
  )
25
21
  from reconcile.utils.secret_reader import SecretReader
26
22
 
23
+ if TYPE_CHECKING:
24
+ from collections.abc import Mapping
25
+
26
+ from reconcile.ocm.types import OCMSpec
27
+
27
28
  STATUS_READY = "ready"
28
29
  STATUS_FAILED = "failed"
29
30
  STATUS_DELETING = "deleting"
@@ -4,8 +4,7 @@ import logging
4
4
  import random
5
5
  import string
6
6
  from abc import abstractmethod
7
- from collections.abc import Mapping
8
- from typing import Any
7
+ from typing import TYPE_CHECKING, Any
9
8
 
10
9
  from pydantic import BaseModel
11
10
 
@@ -22,9 +21,13 @@ from reconcile.ocm.types import (
22
21
  )
23
22
  from reconcile.utils.exceptions import ParameterError
24
23
  from reconcile.utils.ocm.clusters import get_provisioning_shard_id
25
- from reconcile.utils.ocm_base_client import OCMBaseClient
26
24
  from reconcile.utils.rosa.rosa_cli import RosaCliError
27
- from reconcile.utils.rosa.session import RosaSessionBuilder
25
+
26
+ if TYPE_CHECKING:
27
+ from collections.abc import Mapping
28
+
29
+ from reconcile.utils.ocm_base_client import OCMBaseClient
30
+ from reconcile.utils.rosa.session import RosaSessionBuilder
28
31
 
29
32
  CS_API_BASE = "/api/clusters_mgmt"
30
33
 
@@ -3,14 +3,17 @@ from __future__ import annotations
3
3
 
4
4
  from collections.abc import Mapping, Sequence, Set
5
5
  from typing import (
6
+ TYPE_CHECKING,
6
7
  Any,
7
8
  Protocol,
8
9
  runtime_checkable,
9
10
  )
10
11
 
11
- from reconcile.gql_definitions.fragments.saas_slo_document import SLODocument
12
12
  from reconcile.utils import oc_connection_parameters
13
- from reconcile.utils.secret_reader import HasSecret
13
+
14
+ if TYPE_CHECKING:
15
+ from reconcile.gql_definitions.fragments.saas_slo_document import SLODocument
16
+ from reconcile.utils.secret_reader import HasSecret
14
17
 
15
18
 
16
19
  @runtime_checkable
@@ -2,12 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  import logging
5
- from collections.abc import (
6
- Iterable,
7
- Mapping,
8
- Sequence,
9
- )
10
5
  from typing import (
6
+ TYPE_CHECKING,
11
7
  Any,
12
8
  Protocol,
13
9
  )
@@ -24,6 +20,9 @@ from slack_sdk.http_retry import (
24
20
 
25
21
  from reconcile.utils.metrics import slack_request
26
22
 
23
+ if TYPE_CHECKING:
24
+ from collections.abc import Iterable, Mapping, Sequence
25
+
27
26
  MAX_RETRIES = 5
28
27
  TIMEOUT = 30
29
28
 
reconcile/utils/state.py CHANGED
@@ -1,9 +1,10 @@
1
+ from __future__ import annotations
2
+
1
3
  import contextlib
2
4
  import json
3
5
  import logging
4
6
  import os
5
7
  from abc import abstractmethod
6
- from collections.abc import Callable, Generator, Mapping
7
8
  from dataclasses import dataclass, field
8
9
  from typing import (
9
10
  TYPE_CHECKING,
@@ -13,12 +14,6 @@ from typing import (
13
14
 
14
15
  import boto3
15
16
  from botocore.errorfactory import ClientError
16
-
17
- if TYPE_CHECKING:
18
- from mypy_boto3_s3 import S3Client
19
- else:
20
- S3Client = object
21
-
22
17
  from pydantic import BaseModel
23
18
 
24
19
  from reconcile.gql_definitions.common.app_interface_state_settings import (
@@ -38,6 +33,11 @@ from reconcile.utils.secret_reader import (
38
33
  create_secret_reader,
39
34
  )
40
35
 
36
+ if TYPE_CHECKING:
37
+ from collections.abc import Callable, Generator, Mapping
38
+
39
+ from mypy_boto3_s3 import S3Client
40
+
41
41
 
42
42
  class StateInaccessibleError(Exception):
43
43
  pass
@@ -46,7 +46,7 @@ class StateInaccessibleError(Exception):
46
46
  def init_state(
47
47
  integration: str,
48
48
  secret_reader: SecretReaderBase | None = None,
49
- ) -> "State":
49
+ ) -> State:
50
50
  if not secret_reader:
51
51
  vault_settings = get_app_interface_vault_settings()
52
52
  secret_reader = create_secret_reader(use_vault=vault_settings.vault)
@@ -418,7 +418,7 @@ class State:
418
418
  @contextlib.contextmanager
419
419
  def transaction(
420
420
  self, key: str, value: Any = None
421
- ) -> Generator["TransactionStateObj", None, None]:
421
+ ) -> Generator[TransactionStateObj, None, None]:
422
422
  """Get a context manager to set the key in the state if no exception occurs.
423
423
 
424
424
  You can set the value either via the value parameter or by setting the value attribute of the returned object.
@@ -744,7 +744,7 @@ class TerraformClient:
744
744
  value = allowed_modifications.get(argument)
745
745
  if (
746
746
  value in pending_modified_values
747
- and cast(dict[str, str], pending_modified_values)[value]
747
+ and cast("dict[str, str]", pending_modified_values)[value]
748
748
  == after[argument]
749
749
  ):
750
750
  changed_values.append(argument)
@@ -993,9 +993,11 @@ class TerrascriptClient:
993
993
  lifecycle.prevent_destroy = False
994
994
  if lifecycle.ignore_changes is None:
995
995
  lifecycle.ignore_changes = []
996
- if "all" in lifecycle.ignore_changes:
997
- lifecycle.ignore_changes = "all"
998
- return lifecycle.dict(by_alias=True)
996
+ # 'all' must be passed as a string for ignore_changes! stupid terraform aws provider!
997
+ ignore_changes = (
998
+ "all" if "all" in lifecycle.ignore_changes else lifecycle.ignore_changes
999
+ )
1000
+ return lifecycle.dict(by_alias=True) | {"ignore_changes": ignore_changes}
999
1001
  return None
1000
1002
 
1001
1003
  def populate_additional_providers(self, infra_account_name: str, accounts):
@@ -1090,7 +1092,7 @@ class TerrascriptClient:
1090
1092
  )
1091
1093
  if records_from_vault:
1092
1094
  allowed_vault_secret_paths = (
1093
- cast(set[str], zone.get("allowed_vault_secret_paths")) or set()
1095
+ cast("set[str]", zone.get("allowed_vault_secret_paths")) or set()
1094
1096
  )
1095
1097
  vault_values: list[str] = []
1096
1098
  for rec in records_from_vault:
@@ -5752,7 +5754,7 @@ class TerrascriptClient:
5752
5754
  tags.update(json.loads(extra_tags))
5753
5755
  # common_values is untyped, so casting is necessary
5754
5756
  region = cast(
5755
- str, common_values.get("region") or self.default_regions.get(account)
5757
+ "str", common_values.get("region") or self.default_regions.get(account)
5756
5758
  )
5757
5759
 
5758
5760
  template_values = {
@@ -5768,7 +5770,7 @@ class TerrascriptClient:
5768
5770
  }
5769
5771
 
5770
5772
  # common_values is untyped, so casting is necessary
5771
- image = cast(list[dict[str, Any]], common_values.get("image"))
5773
+ image = cast("list[dict[str, Any]]", common_values.get("image"))
5772
5774
  image_id = self.get_asg_image_id(filters=image, account=account, region=region)
5773
5775
  if not image_id:
5774
5776
  if self._use_previous_image_id(image):
@@ -27,7 +27,7 @@ class VaultSecretRef:
27
27
  return secret_content.get(self.field, default)
28
28
 
29
29
  def _resolve_secret(self) -> dict[str, str]:
30
- vault_client = cast(_VaultClient, VaultClient())
30
+ vault_client = cast("_VaultClient", VaultClient())
31
31
  if self.field == VaultSecretRef._ALL_FIELDS:
32
32
  return vault_client.read_all(self.__dict__)
33
33
  field_value = vault_client.read(self.__dict__)
reconcile/utils/vcs.py CHANGED
@@ -2,28 +2,32 @@ from __future__ import annotations
2
2
 
3
3
  import logging
4
4
  import re
5
- from collections.abc import Iterable
6
5
  from dataclasses import dataclass
7
6
  from datetime import datetime
8
7
  from enum import Enum
9
- from typing import Literal
8
+ from typing import TYPE_CHECKING, Literal
10
9
  from urllib.parse import urlparse
11
10
 
12
11
  from gitlab.const import PipelineStatus
13
- from gitlab.v4.objects import ProjectMergeRequest
14
12
 
15
- from reconcile.typed_queries.github_orgs import GithubOrgV1
16
- from reconcile.typed_queries.gitlab_instances import GitlabInstanceV1
17
13
  from reconcile.utils.github_api import GithubRepositoryApi
18
14
  from reconcile.utils.gitlab_api import (
19
15
  GitLabApi,
20
16
  MRState,
21
17
  )
22
- from reconcile.utils.mr.base import MergeRequestBase
23
- from reconcile.utils.secret_reader import (
24
- HasSecret,
25
- SecretReaderBase,
26
- )
18
+
19
+ if TYPE_CHECKING:
20
+ from collections.abc import Iterable
21
+
22
+ from gitlab.v4.objects import ProjectMergeRequest
23
+
24
+ from reconcile.typed_queries.github_orgs import GithubOrgV1
25
+ from reconcile.typed_queries.gitlab_instances import GitlabInstanceV1
26
+ from reconcile.utils.mr.base import MergeRequestBase
27
+ from reconcile.utils.secret_reader import (
28
+ HasSecret,
29
+ SecretReaderBase,
30
+ )
27
31
 
28
32
  GITHUB_BASE_URL = "https://github.com/"
29
33
 
@@ -294,7 +294,7 @@ def get_vault_credentials(
294
294
  """Returns a dictionary with the credentials used to authenticate with Vault,
295
295
  retrieved from the values present on AppInterface and comming from Vault itself."""
296
296
  vault_creds = {}
297
- vault = cast(_VaultClient, VaultClient())
297
+ vault = cast("_VaultClient", VaultClient())
298
298
 
299
299
  if not isinstance(
300
300
  vault_auth,
@@ -112,8 +112,7 @@ def validate_no_internal_to_public_peerings(
112
112
  }:
113
113
  continue
114
114
  connection = cast(
115
- ClusterPeeringConnectionClusterAccepterV1
116
- | ClusterPeeringConnectionClusterRequesterV1,
115
+ "ClusterPeeringConnectionClusterAccepterV1 | ClusterPeeringConnectionClusterRequesterV1",
117
116
  connection,
118
117
  )
119
118
  peer = connection.cluster
@@ -153,8 +152,7 @@ def validate_no_public_to_public_peerings(
153
152
  }:
154
153
  continue
155
154
  connection = cast(
156
- ClusterPeeringConnectionClusterAccepterV1
157
- | ClusterPeeringConnectionClusterRequesterV1,
155
+ "ClusterPeeringConnectionClusterAccepterV1 | ClusterPeeringConnectionClusterRequesterV1",
158
156
  connection,
159
157
  )
160
158
  peer = connection.cluster
@@ -29,7 +29,6 @@ from reconcile.cli import (
29
29
  )
30
30
  from reconcile.jenkins_job_builder import init_jjb
31
31
  from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
32
- from reconcile.utils.jjb_client import JJB
33
32
  from reconcile.utils.mr import CreateAppInterfaceReporter
34
33
  from reconcile.utils.runtime.environment import init_env
35
34
  from reconcile.utils.secret_reader import SecretReader
@@ -188,7 +187,7 @@ def get_apps_data(
188
187
  secret_reader = SecretReader(settings)
189
188
 
190
189
  apps = queries.get_apps()
191
- jjb: JJB = init_jjb(secret_reader)
190
+ jjb = init_jjb(secret_reader)
192
191
  jenkins_map = jenkins_base.get_jenkins_map()
193
192
  time_limit = date - relativedelta(months=month_delta)
194
193
  timestamp_limit = int(time_limit.replace(tzinfo=UTC).timestamp())