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.
- {qontract_reconcile-0.10.2.dev279.dist-info → qontract_reconcile-0.10.2.dev281.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev279.dist-info → qontract_reconcile-0.10.2.dev281.dist-info}/RECORD +76 -76
- reconcile/acs_policies.py +7 -7
- reconcile/aus/base.py +1 -1
- reconcile/aus/models.py +4 -5
- reconcile/aus/version_gate_approver.py +4 -1
- reconcile/aws_account_manager/merge_request_manager.py +5 -3
- reconcile/aws_ami_cleanup/integration.py +5 -8
- reconcile/aws_cloudwatch_log_retention/integration.py +6 -6
- reconcile/database_access_manager.py +1 -1
- reconcile/deadmanssnitch.py +1 -1
- reconcile/dynatrace_token_provider/ocm.py +10 -11
- reconcile/external_resources/aws.py +1 -1
- reconcile/external_resources/model.py +11 -11
- reconcile/external_resources/state.py +4 -4
- reconcile/fleet_labeler/dependencies.py +7 -3
- reconcile/fleet_labeler/ocm.py +6 -4
- reconcile/gitlab_housekeeping.py +2 -2
- reconcile/gitlab_permissions.py +1 -1
- reconcile/jenkins_webhooks.py +8 -4
- reconcile/jenkins_worker_fleets.py +2 -2
- reconcile/ocm_internal_notifications/integration.py +6 -4
- reconcile/ocm_labels/integration.py +7 -7
- reconcile/ocm_upgrade_scheduler_org_updater.py +2 -4
- reconcile/openshift_cluster_bots.py +1 -1
- reconcile/resource_scraper.py +1 -1
- reconcile/run_integration.py +1 -1
- reconcile/saas_auto_promotions_manager/integration.py +7 -3
- reconcile/saas_auto_promotions_manager/s3_exporter.py +6 -3
- reconcile/saas_file_validator.py +1 -2
- reconcile/skupper_network/models.py +4 -2
- reconcile/statuspage/page.py +1 -1
- reconcile/terraform_cloudflare_resources.py +1 -1
- reconcile/terraform_resources.py +1 -1
- reconcile/terraform_tgw_attachments.py +3 -3
- reconcile/terraform_users.py +1 -1
- reconcile/utils/aws_api.py +12 -30
- reconcile/utils/aws_api_typed/account.py +4 -4
- reconcile/utils/aws_api_typed/api.py +4 -2
- reconcile/utils/aws_api_typed/dynamodb.py +2 -2
- reconcile/utils/aws_api_typed/iam.py +2 -2
- reconcile/utils/aws_api_typed/organization.py +10 -7
- reconcile/utils/aws_api_typed/s3.py +2 -3
- reconcile/utils/aws_api_typed/service_quotas.py +4 -1
- reconcile/utils/aws_api_typed/sts.py +2 -2
- reconcile/utils/aws_api_typed/support.py +2 -2
- reconcile/utils/dynatrace/client.py +4 -1
- reconcile/utils/expiration.py +1 -1
- reconcile/utils/external_resource_spec.py +4 -2
- reconcile/utils/gitlab_api.py +4 -4
- reconcile/utils/glitchtip/models.py +4 -2
- reconcile/utils/jira_client.py +4 -4
- reconcile/utils/jobcontroller/models.py +8 -8
- reconcile/utils/mr/base.py +1 -1
- reconcile/utils/oc_connection_parameters.py +4 -1
- reconcile/utils/ocm/base.py +4 -1
- reconcile/utils/ocm/ocm.py +6 -5
- reconcile/utils/ocm/products.py +7 -4
- reconcile/utils/saasherder/interfaces.py +5 -2
- reconcile/utils/slack_api.py +4 -5
- reconcile/utils/state.py +9 -9
- reconcile/utils/terraform_client.py +1 -1
- reconcile/utils/terrascript_aws_client.py +8 -6
- reconcile/utils/vaultsecretref.py +1 -1
- reconcile/utils/vcs.py +14 -10
- reconcile/vault_replication.py +1 -1
- reconcile/vpc_peerings_validator.py +2 -4
- tools/app_interface_reporter.py +1 -2
- tools/cli_commands/erv2.py +7 -4
- tools/cli_commands/gpg_encrypt.py +4 -1
- tools/qontract_cli.py +13 -8
- tools/saas_metrics_exporter/commit_distance/channel.py +6 -3
- tools/saas_metrics_exporter/main.py +4 -1
- tools/saas_promotion_state/saas_promotion_state.py +4 -1
- {qontract_reconcile-0.10.2.dev279.dist-info → qontract_reconcile-0.10.2.dev281.dist-info}/WHEEL +0 -0
- {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,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
|
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
|
-
|
12
|
-
CreateAccountFailureReasonType =
|
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[
|
22
|
+
children: list[AwsOrganizationOU] = []
|
20
23
|
|
21
24
|
def locate(
|
22
25
|
self, path: list[str], ignore_case: bool = True
|
23
|
-
) ->
|
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) ->
|
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
|
-
|
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
|
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
|
reconcile/utils/expiration.py
CHANGED
@@ -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(
|
179
|
+
return OutputFormat(
|
180
|
+
**cast("dict[str, Any]", self.resource["output_format"])
|
181
|
+
)
|
180
182
|
return OutputFormat(provider="generic-secret")
|
181
183
|
|
182
184
|
|
reconcile/utils/gitlab_api.py
CHANGED
@@ -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.
|
reconcile/utils/jira_client.py
CHANGED
@@ -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
|
24
|
-
ERROR
|
25
|
-
IN_PROGRESS
|
26
|
-
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
|
31
|
-
REPLACE_FAILED
|
32
|
-
REPLACE_IN_PROGRESS
|
33
|
-
REPLACE_FINISHED
|
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):
|
reconcile/utils/mr/base.py
CHANGED
@@ -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
|
reconcile/utils/ocm/base.py
CHANGED
@@ -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"
|
reconcile/utils/ocm/ocm.py
CHANGED
@@ -1,16 +1,12 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import functools
|
4
|
-
from
|
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"
|
reconcile/utils/ocm/products.py
CHANGED
@@ -4,8 +4,7 @@ import logging
|
|
4
4
|
import random
|
5
5
|
import string
|
6
6
|
from abc import abstractmethod
|
7
|
-
from
|
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
|
-
|
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
|
-
|
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
|
reconcile/utils/slack_api.py
CHANGED
@@ -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
|
-
) ->
|
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[
|
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
|
-
|
997
|
-
|
998
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
|
reconcile/vault_replication.py
CHANGED
@@ -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
|
tools/app_interface_reporter.py
CHANGED
@@ -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
|
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())
|